Found while QA-ing #1268 on a deploy preview with a fixture user that held no consent artifacts at all.
What happens
GET /dashboard/consultee/[consulteeId]/appointments (and the appointment detail route) throws from the render path:
Error [ConsentRequiredError]: Video and chat are unavailable because data-processing
consent for messaging has not been granted (or was withdrawn).
purposeCode: 'STREAM_DATA_PROCESSING'
at async (.next/server/app/dashboard/consultee/[consulteeId]/(features)/appointments/page.js)
Sentry: FAMILIARISE_WEB-12 — 12 events, preview only, zero production events.
Why it matters
Nobody has withdrawn consent in production, which is the only reason this isn't firing. But withdrawal is a right DPDP explicitly grants, and lib/auth.ts documents the in-app withdrawal flow as supported — "When a user hits the in-app withdrawal flow, this artifact is superseded and checkConsent fails closed." Failing closed is correct for Stream; taking the whole appointments page down with it is not.
The first person to exercise that right loses access to their own bookings.
Expected
The route should degrade, not fail: render the appointment, and show video/chat as unavailable with a route back to the consent settings. The consent gate should scope to the Stream-dependent parts rather than the page.
Pre-existing. Surfaced there only because the QA fixture user happened to have no consent — a normal signup stamps PRIMARY_PROCESSING, STREAM_DATA_PROCESSING and SESSION_BOOKING (lib/auth.ts:265-285).
Repro
Create a user with no ConsentArtifact rows (or withdraw STREAM_DATA_PROCESSING), sign in, open the appointments page.
Part of #705
Found while QA-ing #1268 on a deploy preview with a fixture user that held no consent artifacts at all.
What happens
GET /dashboard/consultee/[consulteeId]/appointments(and the appointment detail route) throws from the render path:Sentry: FAMILIARISE_WEB-12 — 12 events, preview only, zero production events.
Why it matters
Nobody has withdrawn consent in production, which is the only reason this isn't firing. But withdrawal is a right DPDP explicitly grants, and
lib/auth.tsdocuments the in-app withdrawal flow as supported — "When a user hits the in-app withdrawal flow, this artifact is superseded andcheckConsentfails closed." Failing closed is correct for Stream; taking the whole appointments page down with it is not.The first person to exercise that right loses access to their own bookings.
Expected
The route should degrade, not fail: render the appointment, and show video/chat as unavailable with a route back to the consent settings. The consent gate should scope to the Stream-dependent parts rather than the page.
Not from #1268
Pre-existing. Surfaced there only because the QA fixture user happened to have no consent — a normal signup stamps
PRIMARY_PROCESSING,STREAM_DATA_PROCESSINGandSESSION_BOOKING(lib/auth.ts:265-285).Repro
Create a user with no
ConsentArtifactrows (or withdrawSTREAM_DATA_PROCESSING), sign in, open the appointments page.Part of #705