high priority medium complexity backend pending backend specialist Tier 5

Acceptance Criteria

location-privacy-config stores a consent_version field (semantic version string, e.g., '1.2.0') and a change_summary field per organisation record
When an org admin updates the consent_version in location-privacy-config, a background job or trigger sets requires_reconsent = true on all consent_grants rows for that org where the stored consent_version differs from the new current version
The consent status API endpoint (task-008) returns requires_reconsent: true for affected mentors, which the Flutter client uses to trigger the re-prompt flow
The re-prompt dialog displays the change_summary text from location-privacy-config prominently above the standard consent explanation, with a heading 'What changed'
Mentors who choose Opt In during re-consent have their consent_grants row updated with the new consent_version and requires_reconsent reset to false
Mentors who choose Opt Out during re-consent have their location data deleted (reuses revokeConsent from task-004) and requires_reconsent set to false
A mentor cannot access map features while requires_reconsent is true — the re-prompt is mandatory and non-skippable
The consent_version update and the batch requires_reconsent flag update are executed in a single transaction to prevent a window where the version is updated but mentors are not yet flagged
An audit log entry is created for each re-consent event recording previous_version, new_version, mentor_id, and decision
Unit tests cover: version bump triggers requires_reconsent for all affected mentors, re-consent Opt In updates version and clears flag, re-consent Opt Out triggers deletion
The system handles graceful degradation: if location-privacy-config is unavailable, the dialog shows a generic privacy explanation without a change summary rather than blocking the user entirely

Technical Requirements

frameworks
Supabase Edge Functions (Deno)
Flutter
Riverpod
apis
Supabase PostgreSQL 15 (batch UPDATE, transaction)
Supabase Realtime (optional: push requires_reconsent change to connected clients)
consent status API endpoint (task-008)
data models
consent_grants
location-privacy-config (consent_version, change_summary, requires_reconsent)
consent_audit_log
performance requirements
Batch UPDATE to set requires_reconsent on all org mentors must use a single UPDATE WHERE org_id = $orgId AND consent_version != $newVersion — no row-by-row updates
Batch update for large orgs (e.g., 200+ mentors) must complete within 2 seconds
The re-prompt check on app launch adds at most one additional API call (reuse task-008 endpoint which already returns requires_reconsent)
security requirements
Only org admin role may update consent_version in location-privacy-config — enforce via RLS and Edge Function role check
The batch requires_reconsent update must run server-side (Edge Function) — no client-initiated batch updates
Re-consent audit log entries follow the same append-only immutability policy as the main audit log (task-005)
GDPR: change_summary must not contain PII; it is a policy description only
Version downgrade (setting a lower version) must be rejected to prevent bypassing consent for mentors who consented to a higher version
ui components
LocationConsentDialog extended with optional changeSummary: String? parameter
ChangeSummaryBanner widget (shown inside dialog when changeSummary is non-null)
ConsentStatusNotifier updated to handle requires_reconsent: true state

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

Add consent_version (text) and requires_reconsent (boolean, default false) columns to consent_grants via a migration. Add consent_version (text) and change_summary (text) columns to location-privacy-config. Implement the version bump flow as an Edge Function updateConsentVersion(orgId, newVersion, changeSummary) that: (1) validates caller is org admin, (2) rejects if newVersion <= currentVersion (semver compare), (3) in a transaction: updates location-privacy-config.consent_version, then runs UPDATE consent_grants SET requires_reconsent = true WHERE org_id = $orgId AND consent_version != $newVersion. Extend ConsentStatusNotifier to expose a requiresReconsent state variant.

In the map feature guard widget, check both status == pending and requiresReconsent == true as triggers to show the dialog. Pass changeSummary from the ConsentStatusResponse into the dialog as an optional parameter. To avoid a separate API call for the change summary, include change_summary in the ConsentStatusResponse from task-008 when requires_reconsent is true.

Testing Requirements

Unit tests: mock location-privacy-config provider returning a new version, assert ConsentStatusNotifier transitions to requiresReconsent state, assert re-prompt dialog is shown. Test that Opt In during re-consent calls grantConsent with new version and clears requires_reconsent. Test that Opt Out during re-consent calls revokeConsent. Integration tests: create an org with 3 mentors who have consented under version 1.0.0, simulate admin updating to version 1.1.0, assert all 3 rows have requires_reconsent = true in the database.

Test version downgrade rejection. Test graceful degradation: make location-privacy-config unavailable and assert dialog still renders with generic text. Widget test: render LocationConsentDialog with changeSummary set and assert ChangeSummaryBanner is visible; render without changeSummary and assert banner is absent.

Component
Location Privacy Configuration
infrastructure low
Epic Risks (2)
medium impact medium prob scope

If the privacy policy text or consent terms change after mentors have already opted in, existing consent records may become legally insufficient, requiring re-consent from all opted-in mentors which could temporarily reduce map coverage.

Mitigation & Contingency

Mitigation: Store a consent_version field on every consent record. Implement a consent version check in location-consent-service that compares the stored version against the current policy version from location-privacy-config and flags stale consents for re-consent prompting.

Contingency: If a policy update invalidates existing consents, suppress affected mentors from the map, queue them for re-consent notification via the existing in-app notification system, and restore map visibility only after new consent is recorded.

medium impact medium prob scope

A poorly designed consent dialog may lead to low opt-in rates, reducing map utility for coordinators to the point where the feature delivers insufficient value to justify maintenance cost.

Mitigation & Contingency

Mitigation: Follow plain-language writing guidelines from the cognitive accessibility feature. User-test the dialog with 2-3 peer mentors from Blindeforbundet before implementation is finalised. Ensure the dialog explains the benefit to the mentor, not just the data collection facts.

Contingency: If opt-in rate after launch is below 40%, conduct a targeted usability study and iterate on dialog copy and layout. The coordinator can also send a bulk opt-in invitation notification (per the user story) to non-consenting mentors.