Pipeline errors (snapshot loading or dispatch) should not prevent the
201 response from being returned. Dispatch pipeline events without
awaiting so the response is returned immediately.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add optional chaining for organization.billing in response pipeline
- Add missing feedbackRecordDirectoryId to Chart seed data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dropdown actions say "Enable"/"Disable" but the status badges showed
"In Progress"/"Paused". Now both use "Enabled"/"Disabled" for consistency.
Resolves ENG-769
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `?` operator only checks key existence — if the form layer saved
`{"elementHeadlineColor": null}` (JSON null = "use default"), the
migration skipped the copy and then removed the legacy key, losing
the color value. Switch to COALESCE(styling->'field', 'null'::jsonb)
= 'null'::jsonb which catches both missing keys (SQL NULL) and JSON
null values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures the UPDATE only processes JSONB objects, preventing errors
on unexpected scalar or array values in the styling column.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Aligns storybook story helpers and element stories with the legacy
field removal — inputColor → inputTextColor, mapping to
--fb-input-text-color CSS variable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the async job queue + Redis polling pattern with a direct
server action call. The translation now runs synchronously inside
translateSurveyFieldsAction, removing the need for BullMQ job
definitions, processors, cache keys, and client-side polling logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace remaining environment wording with workspace terminology across setup flows, API key permissions, and email preview text, and switch the email Tailwind config to ESM so formatting hooks run under the current Node runtime.
Made-with: Cursor
- Reuse ZAITranslationField from @formbricks/jobs instead of duplicating
the schema locally in actions.ts; tighten sourceLanguage/targetLanguage
validators with .min(1) to match the downstream job schema
- Guard against undefined translations in getAITranslationResultAction
instead of using the unsafe `translations!` assertion — return
"pending" status for malformed cache entries
- Use createCacheKey.custom("ai-translation", jobId) instead of raw
template strings to follow cache key conventions
- Improve JSON parsing robustness: strip markdown code fences before
attempting JSON.parse, log raw response on parse failures
- Add stale-request guard and error handling to the AI availability
useEffect in language-view.tsx
- Replace shared pollingCancelledRef boolean with per-invocation Symbol
token to prevent stale polling loops from clobbering state when the
modal is reopened
- Track timeout explicitly with a timedOut flag so the "timed out" toast
doesn't fire when polling was actually cancelled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add userId verification in getAITranslationResultAction (security)
- Use OperationNotAllowedError for auth failures
- Store failure marker in cache on last BullMQ attempt
- Make JSON parsing more robust (extract first {...} block)
- Add "keep modal open" hint to translating toast
- Add test coverage for process-ai-translation-job
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>