feat(surveys): replace Formbricks with self-rendered PostHog API surveys

Formbricks CE turned out to gate person-based targeting (setUserId/attributes
→ 403 enterprise) — the exact flexibility surveys need. PostHog already holds
the person properties, so surveys move back there in API mode: posthog-js
evaluates eligibility (event triggers, targeting flags like
subscription_status=active, wait periods, per-distinct_id dedup) via
getActiveMatchingSurveys, and we render the popover ourselves — zero PostHog
branding, sase.tr dark-theme styling.

- lib/surveys.ts: display manager + capture payload builders that mirror
  posthog-js's own "survey shown/dismissed/sent" shapes exactly
  ($survey_response_<qid>, $set $survey_dismissed/<id>[/iter], seenSurvey_*,
  lastSeenSurveyDate) so the PostHog Surveys results UI works unchanged
- components/survey-popover.tsx: single_choice (+Diğer), open text, rating/NPS
- posthog.ts: capture/pageview/identify now schedule survey checks; register
  deploy_env (dev.sase.tr ships the key now → staging traffic is filterable)
- remove @formbricks/js, its CSP entries and build args

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 00:40:18 +03:00
parent 4ffc3577a5
commit 72c3fe0dc2
12 changed files with 520 additions and 123 deletions

View File

@@ -30,9 +30,6 @@ async function bootstrap() {
"https://connect.facebook.net",
"https://challenges.cloudflare.com",
"https://destek.sase.tr",
// @formbricks/js is only a loader shim — the real SDK is injected as
// an external <script> from the Formbricks host (like Chatwoot's sdk.js).
"https://anket.sase.tr",
"'sha256-T5FzBQBMINFjZ4WLy58SeZ+J7xXzjnQEGlg618CQnhA='",
],
styleSrc: ["'self'", "https:", "'unsafe-inline'"],
@@ -42,7 +39,6 @@ async function bootstrap() {
"https://storage.sase.tr",
"https://www.facebook.com",
"https://destek.sase.tr",
"https://anket.sase.tr",
],
fontSrc: ["'self'", "https:", "data:"],
mediaSrc: ["'self'", "data:", "https://destek.sase.tr"],
@@ -55,7 +51,6 @@ async function bootstrap() {
"https://challenges.cloudflare.com",
"https://destek.sase.tr",
"wss://destek.sase.tr",
"https://anket.sase.tr",
// Sentry browser SDK envelope POSTs (otolog org, de region).
// Without this CSP silently blocks every error/replay upload.
"https://*.ingest.de.sentry.io",