← all branches

feat/ph-consent

safeviewing older commit
22fc175 · incrementalpre-PRreviewed 2026-08-01 00:30 UTC0H · 0M · 4L · 6I
The branch
Purpose
Add GDPR-compliant analytics consent gating for PostHog session replay across both apps
Goal
Gate session replay behind visitor consent on apps/web and scope recording to authenticated routes on apps/platform; add revocation and persistence
Sub-goals
  • SG-1: Consent banner on public site (apps/web) gating session replay
  • SG-2: Per-app replay policy — 60% sampling on web (consent-required), explicit policy on platform
  • SG-3: Identity gating on consent — PostHog identify() only fires after grant
  • SG-4: Route-scoped replay via SessionReplayScope — Atlas only on web, authenticated dashboard only on platform
  • SG-5: Consent revocation support and persistence tests
The changes (whole branch)
What
This incremental diff clarifies comments and JSDoc across 4 files — updated layout.tsx comment to distinguish policy from activation, expanded README with 4-gate architecture and route-scoped replay table, refined PostHogProvider JSDoc to emphasize policy-vs-activation distinction, and updated isSessionReplayEnabled @param description to name both apps.
Why
Documentation cleanup following earlier implementation commits to make the architecture clearer for future contributors navigating the consent/replay system.
Areas
apps/platform+134apps/web+1955packages/analytics+87948
Blast
14 files, +1091/−62 across 3 areas; touches analytics consent, replay scoping, consent UI, and privacy page
No PR open yet — pre-PR branch apps/web and apps/platform both affected GDPR consent implementation — consent revocation path is critical correctness
ci· No PR open — CI status not availablecoderabbit· No .coderabbit.yaml found

Findings · 10

correctness1

info

Comment-only diff — no executable paths changed

packages/analytics/src/providers/PostHogProvider.tsx

All 4 changed files contain only comment/JSDoc/documentation updates. No logic, types, control flow, or data handling was modified.

security2

info

localStorage consent key — origin isolation assumption

packages/analytics/src/providers/session-replay.ts

Consent is stored under 'batu.analytics.consent' in localStorage, accessible to any script on the same origin. The README additions make the 4-gate architecture clearer, but if apps/web and apps/platform ever share an origin, a revocation on one may not propagate to the other. Verify the two apps are on distinct origins, or that readStoredConsent() is called fresh on each PostHog init (it is, by the effect in PostHogProvider).

info

Comment-only diff — no new security surface

apps/web/src/app/layout.tsx

The sessionReplay policy object ({sampleRate:0.6, requireConsent:true}) was already present; the diff only updates the surrounding comment. No new security surface introduced.

conventions3

low

Comment explains WHAT, not WHY

apps/web/src/app/layout.tsx

The updated comment block describes what the code does ('This does not turn recording on', 'it is mounted on Atlas only') rather than why. Per project rules, only add a comment when the WHY is non-obvious. The non-obvious WHY (client-side sampling because PostHog sample rate is per-project and shared) is already in the last two sentences — the first half of the comment is WHAT and could be trimmed.

low

JSDoc @param description lists callers instead of semantics

packages/analytics/src/providers/session-replay.ts:211

The @param description 'the app declared a replay policy on the provider (apps/platform and apps/web)' enumerates current callers — WHAT — rather than the param's intent or constraints. Should describe the gate semantics abstractly.

info

README.md additions — no convention findings

packages/analytics/README.md

Documentation-only file; no convention rules applicable.

improvement4

low

Atlas-only mounting is a prose contract, not structural

apps/web/src/app/layout.tsx:71

The comment says '<SessionReplayScope /> is mounted on Atlas only' but there is no compile-time or lint guard to enforce this. A future developer adding SessionReplayScope to another route would not see a warning. Consider a named constant or TSDoc marking SessionReplayScope as atlas-only to surface the constraint at the use site.

low

README route-scoped replay table may drift silently

packages/analytics/README.md

The hand-written table listing where replay runs per app is valuable but will drift if a new route or app mounts SessionReplayScope. There is no test or type check tying this documentation to the code. Consider a colocated comment or type export that is grep-able rather than a prose table.

info

sampleRate lacks documented valid range

packages/analytics/src/providers/PostHogProvider.tsx

The JSDoc clarification that sessionReplay is 'POLICY, not activation' is helpful. The prop's sampleRate has no documented range constraint (must be 0–1). Adding a note or a branded type would prevent misconfiguration (e.g. sampleRate: 60) that would silently disable all sampling.

info

isSessionReplayEnabled @param names specific apps — will grow stale

packages/analytics/src/providers/session-replay.ts

Naming 'apps/platform and apps/web' in a generic utility's JSDoc creates coupling. If a third app adopts the package, the comment misleads. Describe the gate semantics abstractly instead of listing callers.

History · 6 commits

  1. 8c748c7safeincremental0H · 0M · 2L2026-08-01 00:40
  2. 22fc175safeincremental0H · 0M · 4L2026-08-01 00:30current
  3. f26dee1needs attentionincremental2H · 2M · 9L2026-08-01 00:24
  4. bf92308needs attentionincremental2H · 8M · 8L2026-07-31 23:56
  5. cf3e330needs attentionincremental0H · 6M · 5L2026-07-31 23:17
  6. 5fb4d78blockedfull4H · 8M · 9L2026-07-31 22:11