open-design/apps
lefarcen c30f3fbfac
feat(analytics): default telemetry to on so onboarding events emit pre-disclosure (#2682)
The post-onboarding disclosure modal (App.tsx:349 — `showPrivacyConsent =
... && config.onboardingCompleted === true`) only renders after the user
completes the welcome flow. Before that, `config.telemetry` is undefined
and both the daemon-side gate
(`analytics.ts: if (cfg.telemetry?.metrics !== true) return`) and the
web-side `/api/analytics/config` drop every event the onboarding view
fires.

E2E on nightly.10 (QA, 2026-05-22 06:15+ UTC) confirmed the symptom: a
real user completed the full Connect → About you → Design system → Generate
flow but PostHog received zero `page_view pn=onboarding` / `ui_click` /
`onboarding_runtime_scan_result` / `onboarding_complete_result` rows from
their distinct_id. Other events (post-onboarding home, settings, project
creation) flowed normally because by then the disclosure had been
accepted and `telemetry.metrics` was true.

Product decision (2026-05-22): default telemetry ON. The disclosure
modal stays disclosure-style ("I get it") and Settings → Privacy
remains the one-click opt-out — same UX, only the pre-decision default
changes from off to on.

Changes:
- `apps/web/src/state/config.ts`: `DEFAULT_CONFIG.telemetry =
  { metrics: true, content: true, artifactManifest: false }` so fresh
  `loadConfig()` calls emit during the first onboarding render.
- `apps/web/src/types.ts`: comment now documents the default-on
  semantics + the opt-out path.
- `apps/daemon/src/app-config.ts`: new `applyTelemetryDefaults` helper
  fills in the same defaults when `readAppConfig` finds no telemetry
  field on disk. Helper runs on BOTH the
  installation-file-shadowing path and the fallback path. An
  explicit user opt-out (`metrics: false`) is preserved untouched —
  defaults only fill `undefined`, never overwrite a saved value.
- `apps/daemon/tests/app-config.test.ts`: 49 → 51 tests. Updated 9
  existing assertions that expected `cfg.telemetry === undefined` /
  `cfg === {}` to expect the new default; added 2 regression guards:
  - "preserves an explicit telemetry opt-out across reads" pins the
    `metrics: false` invariant so a future refactor can't silently
    re-enable opted-out users.
  - "preserves a partial explicit telemetry (metrics on, content off)"
    pins per-field user choices against the default fill.

Validation:
- `pnpm --filter @open-design/daemon exec vitest run tests/app-config.test.ts`  51/51
- `pnpm --filter @open-design/web typecheck` 
- `pnpm --filter @open-design/daemon typecheck` 
- `pnpm --filter @open-design/web test`  201 files / 1839 tests
2026-05-22 15:42:20 +08:00
..
daemon feat(analytics): default telemetry to on so onboarding events emit pre-disclosure (#2682) 2026-05-22 15:42:20 +08:00
desktop fix: harden Windows packaged updater flow (#2595) 2026-05-21 22:32:02 +08:00
landing-page Merge origin/main into release/v0.8.0 2026-05-21 13:17:52 +08:00
packaged fix: harden Windows packaged updater flow (#2595) 2026-05-21 22:32:02 +08:00
telemetry-worker chore: pin dependency versions and harden CI caches (#2189) 2026-05-19 13:58:27 +08:00
web feat(analytics): default telemetry to on so onboarding events emit pre-disclosure (#2682) 2026-05-22 15:42:20 +08:00
AGENTS.md refactor(daemon): split agent runtime definitions (#1063) 2026-05-11 15:01:55 +08:00