- Updated `sanitizeCsvFieldMappings` to utilize constants for protected target IDs.
- Refactored connector actions to streamline field mapping processing.
- Added a new test case for sanitization to ensure correct handling of all-protected mappings.
- Improved localization for CSV row count and field types in the UI components.
- FormError ignored its children when an error was set, rendering the raw
zod message instead of the translated text passed in. Prefer explicit
children, fall back to the field error message.
- Use .at(-1) in getTranslatedFeedbackDirectoryError per SonarQube S7755.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per Johannes on ENG-893: zero-workspace creation is acceptable — admins
move workspaces between directories and forcing at least one is an
arbitrary limitation. The unformatted-error fix
(getTranslatedFeedbackDirectoryError prefix stripping) is retained.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ENG-893
Why: A feedback directory with zero workspaces is useless — it groups
nothing. The create path allowed it, and any validation error that did
fire surfaced as a raw "field: CODE" string in the toast.
How:
- createFeedbackDirectory now rejects empty/missing workspaceIds with
DIRECTORY_WORKSPACES_REQUIRED before touching the database.
- getTranslatedFeedbackDirectoryError strips the "<field>: " prefix that
next-safe-action prepends to validation errors, so machine codes always
map to a translated message.
- Add the new translation key across all 15 locales.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tests now expect validation failures when CUBEJS_API_URL, CUBEJS_API_SECRET,
or HUB_API_KEY are missing, and all test env helpers provide HUB_API_KEY.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hub 0.3.0 renames the `user_identifier` API field to `user_id` (breaking
change). This commit bumps the Hub Docker image, upgrades the
@formbricks/hub TypeScript SDK from 0.4.3 to 0.5.0, and renames every
`user_identifier` reference in Zod schemas, server actions, transform
pipeline, form components, CubeJS schema, connector types, and seed data
to match the new API contract.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move duplicated function to @/lib/ai/service and export TAIUnavailableReason
type. Remove local copies from charts-list-page and dashboard-detail-page.
- Server-side: Replace hardcoded OpenAI with provider-agnostic `getAiModel(env)` and enforce
`assertOrganizationAIConfigured(organizationId, "dataAnalysis")` which validates license
entitlement, org-level toggle, and instance configuration
- Client-side: Instead of hiding AI section when unavailable, show it disabled with a tooltip
explaining the reason (not in plan / not enabled / instance not configured), following the
same pattern as AI translate
- Thread `isAIAvailable` and `aiUnavailableReason` through the component chain from server
pages down to `AIQuerySection`
- Update test mocks to match new provider-agnostic AI imports
The feedback-sources page was still using the old WorkspaceConfigNavigation
(secondary tabs) instead of the new unified settings sidebar introduced in
#7904. This caused an inconsistent navigation experience.
Changes:
- Create new route at /settings/workspace/feedback-sources
- Add feedback-sources entry to SettingsSidebarContent
- Remove old WorkspaceConfigNavigation from ConnectorsSection
- Redirect old /feedback-sources route to new settings path
- Update all stale /feedback-sources links across the codebase
All internal links (billing, enterprise, general, api-keys, feedback-record-directories,
integrations) now point to their correct nested paths under /settings/organization/ or
/settings/workspace/. Also adds feedback-record-directories to the new sidebar nav with
the member visibility rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>