What's Changed
- feat(helm): add Hub volume extension points by @BhagyaAmarasinghe in #8504
- fix: let MCP clients request surveys:write and correct validate_survey scope by @xernobyl in #8509
- fix: prevent infinite re-render loop when authenticated actions refresh the route by @pandeymangg in #8507
- fix: resolve hydration errors in RatingSmiley table markup by @itsjavi in #8514
- fix(database): seed Better Auth credential accounts so seed users can log in by @itsjavi in #8512
- fix: prevent auth-action route-refresh loop in chart edit and feedback record modals by @pandeymangg in #8518
- fix(web): stop infinite server-action refresh loop on survey analysis pages by @itsjavi in #8513
- fix(api-keys): stop truncating the org-access note in the API key modal by @Dhruwang in #8519
- fix(ui): keep InputCombobox chevron right-aligned when the dropdown is empty by @Dhruwang in #8520
- feat(auth): reject breached passwords via Have-I-Been-Pwned on password set (ENG-1587) by @xernobyl in #8508
- fix: verify password against the credential account for email change and 2FA by @xernobyl in #8532
- docs: update license table workspaces pricing to pay per workspace by @jobenjada in #8549
- fix(charts): correct rating measure labels and stale "Run Query" empty-state copy by @itsjavi in #8543
- chore: document SIGNUP_DOMAIN_CHECK_ON_INVITES in .env.example by @Dhruwang in #8528
- fix(api): reject response updates on a closed survey (ENG-1654) by @Dhruwang in #8536
- fix(api): reject publishing an app survey with zero triggers by @pandeymangg in #8547
- fix(billing): refresh plan state after a successful upgrade (ENG-1790) by @Dhruwang in #8534
- fix(charts): remove leading gap on category bar charts by @itsjavi in #8542
- feat(dashboards): add duplicate action to dashboard widgets by @itsjavi in #8541
- fix(charts): scale rating chart Y-axis to the question's scale by @itsjavi in #8540
- fix(charts): close chart dialog on Escape and show chart name in edit title by @itsjavi in #8544
- fix(account): redirect SSO account deletion to the post-deletion survey (ENG-1780) by @Dhruwang in #8530
- feat(charts): prefill chart name from AI-generated chart by @itsjavi in #8545
- feat(charts): use semantic colors for sentiment buckets by @itsjavi in #8546
- fix: header-only CSV crash in Unify source creation (ENG-1799) by @xernobyl in #8533
- fix(helm): wait for PostgreSQL before migrations [QA 5.2] by @BhagyaAmarasinghe in #8550
- fix(navigation): center icons in the collapsed sidebar by @itsjavi in #8563
- fix(sso): stop requiring RFC 9207 issuer param for Azure (ENG-1800) by @xernobyl in #8561
- fix(api): allow displayLimit recontact + independent displayPercentage in v3 surveys by @pandeymangg in #8537
- fix: return 409 for duplicate creates under the Prisma 7 driver adapter (ENG-1801) by @xernobyl in #8565
- fix(docker): validate environment before migrations [QA 5.2] by @BhagyaAmarasinghe in #8551
- chore(pnpm): activate supply-chain release cooldown by @mattinannt in #8498
- chore(node): unify Node.js version across dev, CI and production by @mattinannt in #8500
- fix: sync Better Auth TwoFactor table so 2FA login works after enabling by @xernobyl in #8559
- fix(unify): disable active write controls for read-only members on Feedback Data by @pandeymangg in #8570
- feat(charts): language-stable option grouping via value_id + canonical value_text [ENG-1673] by @Dhruwang in #8464
- feat(mcp): add a list_workspaces tool (ENG-1776) by @xernobyl in #8577
- chore(pnpm): remove legacyPeerDeps no-op, document node-linker decision by @mattinannt in #8499
- fix(auth): read the correct field from the OAuth consent response (MCP) by @xernobyl in #8575
- fix(surveys): screen-reader semantics for survey elements by @itsjavi in #8567
- refactor(surveys): WCAG-compliant keyboard and focus model for survey elements by @itsjavi in #8566
- fix(surveys): visual a11y polish for the survey player by @itsjavi in #8568
- fix(turbo): exclude .next/cache and .next/dev from web build outputs by @Dhruwang in #8553
- fix(taxonomy): make failed runs actionable and recoverable by @pandeymangg in #8582
- docs(unify-feedback): rename "Feedback Directories" to "Feedback Datasets" by @jobenjada in #8584
- fix(sso): normalize IdP display name & accept common name punctuation (ENG-1743) by @pandeymangg in #8574
- fix: correct Helm release image validation by @BhagyaAmarasinghe in #8589
- chore(vitest): remove dead environmentMatchGlobs, adopt projects layout by @mattinannt in #8502
- fix: enforce organization/workspace scoping across API keys, surveys, quotas, and integrations (ENG-1749) by @xernobyl in #8596
- fix(auth): block billing-role members from workspace product data [ENG-1763] by @pandeymangg in #8592
- docs(self-hosting): add v5.2 migration guide by @Dhruwang in #8593
- fix: bump tar to 7.5.19 to patch decompression DoS (ENG-1947) by @Dhruwang in #8604
- fix(scheduling): drop NEXT_PUBLIC_ prefix from survey scheduling env vars (ENG-1665) by @Dhruwang in #8601
- fix: enforce workspace-level access in getWorkspaceAuth [ENG-1769] by @xernobyl in #8591
- fix(surveys): enforce link-survey PIN on the client response API [ENG-1579] by @Dhruwang in #8506
- fix(web): unoptimize external next/image srcs instead of a host wildcard by @mattinannt in #8501
- chore(pnpm): declare dependencies previously resolved only via hoisting by @mattinannt in #8511
- chore(deps): patch 13 Dependabot security alerts (ENG-1988..ENG-1999) by @Dhruwang in #8612
- docs(pr): require an agent-maintained QA / Test Plan section on every PR by @Dhruwang in #8595
- refactor: extract shared Prisma unique-constraint error helper by @xernobyl in #8394
- fix(i18n): heal empty default-language keys that reject valid choice responses [ENG-2001] by @Dhruwang in #8614
- chore(deps): patch Dependabot security alerts across 7 packages by @mattinannt in #8623
- perf(e2e): small CI cleanup + measured findings on the real bottlenecks by @mattinannt in #8619
- fix(billing): stop reverse trial laundering into active paid plan [ENG-1968] by @Dhruwang in #8602
- docs(pr): retarget PR template for agent-authored, Linear-driven PRs by @mattinannt in #8620
- fix: bump next to 16.2.11 to patch 9 Next.js CVEs by @mattinannt in #8633
- fix(web): match protocol in isExternalImageSrc against remotePatterns (#ENG-2003) by @mattinannt in #8616
- docs(surveys): refine in-prod targeting docs by @jobenjada in #8611
- fix: apply API-key creator-role clamp to team creation (ENG-1765) by @mattinannt in #8634
- chore(ci): remove inert Turbo remote cache and unify pnpm store caching by @mattinannt in #8635
- fix: stop echoing raw error.message in v1 API 500 responses by @xernobyl in #8622
- fix: resolve pnpm audit dependency vulnerabilities by @mattinannt in #8638
- perf(database): speed up Prisma migrations on empty databases by @mattinannt in #8627
- fix: proxy feedback records in local development by @BhagyaAmarasinghe in #8646
- fix(deps): bump brace-expansion@5 to 5.0.8 and align postcss pins by @mattinannt in #8641
- chore(eslint): migrate to ESLint 9 flat config by @mattinannt in #8505
- chore: remove dead nextBundleAnalysis config from root package.json by @mattinannt in #8657
- fix: disable external pre-aggregations for bundled Cube by @BhagyaAmarasinghe in #8652
- fix(docker): remove npm from runtime image by @BhagyaAmarasinghe in #8660
- docs: remove embedded YouTube videos from docs by @jobenjada in #8664
- fix: declare js-core's real dependency, drop dead database coupling (#ENG-1681) by @mattinannt in #8645
- fix: load typegen env from a file instead of inline placeholders by @mattinannt in #8640
- fix(a11y): allow overriding Alert role and use role="status" for static banners by @itsjavi in #8626
- ci: fall back to db:migrate:dev when db:migrate:ci is absent by @Dhruwang in #8661
- chore(deps): drop 17 obsolete pnpm overrides by @mattinannt in #8663
- fix: give each package its own lint:report output file (#ENG-1694) by @mattinannt in #8632
- fix: hard-gate contacts page PII reads on the contacts entitlement (#ENG-1768) by @mattinannt in #8618
- feat(segments): interaction-based segment filter (ENG-1275) by @Dhruwang in #8588
- feat: soft-delete (archive) surveys (ENG-1042) by @Dhruwang in #8609
- feat(surveys): add Vietnamese, Traditional Chinese, Urdu and Indonesian translations by @mattinannt in #8678
- fix(api): bind management response file uploads to authorized workspace [ENG-1981] by @Dhruwang in #8647
- fix(security): scope historical response import to the authorized workspace [1/4 critical] by @mattinannt in #8679
- fix(auth): resolve login-path deadlock and stop over-capturing auth failures by @xernobyl in #8637
- fix: prevent feedback-source ingestion crash on malformed choice elements (ENG-1939) by @xernobyl in #8600
- fix(surveys): return structured 422 when AI generation hits the output token limit (ENG-1891) by @itsjavi in #8585
- feat(surveys): default link surveys to the cardless card arrangement by @jobenjada in #8688
- feat(support): migrate in-product chat from Chatwoot to Plain [ENG-1984] by @Dhruwang in #8654
- fix(security): close the high-severity auth, authz and exposure gaps [2/4 high] by @mattinannt in #8680
- chore: add email domain to PostHog organization group identify by @harshsbhat in #8605
- feat: add feedbackRecord MCP tools to the XM Suite MCP server by @xernobyl in #8650
- feat(license): add Workflows to the enterprise licensed features list by @jobenjada in #8689
- fix(hub): bind feedback records gateway API key access to target organization [ENG-1980] by @Dhruwang in #8648
- fix(security): close the medium-severity bypass and disclosure gaps [3/4 medium] by @mattinannt in #8681
- docs: document built-in survey interface languages by @jobenjada in #8672
- chore: add breaking changes section to PR template by @Dhruwang in #8684
- docs(surveys): add product screenshots to link survey quickstart by @jobenjada in #8696
- chore: remove runtime react deps from root package.json (#1693) by @mattinannt in #8695
- fix: count only finished responses for survey response limit by @jobenjada in #8673
- fix(security): harden the low-severity storage, authz and abuse paths [4/4 low] by @mattinannt in #8682
- fix(editor): support nested lists via Tab in the rich text editor [ENG-1747] by @itsjavi in #8631
- fix: consistent edit-caution modal CTAs across survey list & summary by @jobenjada in #8674
- fix(surveys): stop the focus trap recursing into a stack overflow (ENG-2090) by @pandeymangg in #8700
- feat(auth): block mailbox.org and yeah.net email domains by @jobenjada in #8606
- docs(unify-feedback): add Enrichment page and promote MCP to a top-level nav tab by @harshsbhat in #8642
- feat: formbricks workflows - epic PR by @itsjavi in #8281
- fix(taxonomy): map Hub 404 to 404 instead of a blanket 502 (ENG-1886) by @pandeymangg in #8707
- fix(auth): send the verification email on invite sign-up and bind invites to the invited address [ENG-2091] by @xernobyl in #8691
- feat(billing): charge trial upgrades immediately at full price [ENG-1968] by @Dhruwang in #8659
Full Changelog: 5.2.0-rc.1...5.3.0-rc.1