critical priority low complexity infrastructure pending backend specialist Tier 1

Acceptance Criteria

DuplicateReviewedFlagMiddleware exposes a single method: Map<String, dynamic> inject(Map<String, dynamic> payload) that returns the payload with duplicate_reviewed set to false, regardless of whether the key was already present
A shared insertActivity(Map<String, dynamic> payload) helper in the activity repository applies the middleware before every Supabase insert — no insert call exists outside this helper
The wizard submission path (ActivityWizardCubit or equivalent) uses insertActivity() exclusively
The bulk registration path uses insertActivity() exclusively for each record in the batch
The proxy submission path (coordinator registering on behalf of peer mentor) uses insertActivity() exclusively
If duplicate_reviewed is explicitly set to true in the incoming payload, the middleware overwrites it with false — callers cannot pre-set the flag to bypass detection
middleware.inject() is a pure function with no side effects — safe to call multiple times with the same payload
The middleware class is registered as a singleton in the Riverpod provider graph (wired in task-010)

Technical Requirements

frameworks
Flutter
Riverpod
apis
Supabase REST (INSERT activities)
data models
Activity
ActivityInsertPayload
performance requirements
inject() is O(1) — only a map key assignment; no database calls or async operations
security requirements
Middleware must always overwrite any caller-supplied duplicate_reviewed value with false — prevents any accidental or malicious bypass
insertActivity() helper must be the single chokepoint; audit the codebase to confirm no direct supabase.from('activities').insert() calls exist outside it after this task

Execution Context

Execution Tier
Tier 1

Tier 1 - 540 tasks

Can start after Tier 0 completes

Implementation Notes

Keep DuplicateReviewedFlagMiddleware as a simple Dart class with no dependencies — it is a pure transformation function. Place it in lib/features/duplicate_detection/middleware/duplicate_reviewed_flag_middleware.dart. The shared insertActivity() helper belongs in the ActivityRepository class; replace all existing direct .insert() calls in ActivityRepository with calls to this helper. Since bulk registration may call insertActivity() in a loop, ensure the middleware does not have any shared mutable state that could cause race conditions.

After implementing, do a project-wide search for '.from("activities").insert(' to verify there are no remaining bypass points and document the result in a code comment on the helper method.

Testing Requirements

Write flutter_test unit tests for DuplicateReviewedFlagMiddleware.inject(): (1) payload without duplicate_reviewed key gets it added as false, (2) payload with duplicate_reviewed=false is returned unchanged, (3) payload with duplicate_reviewed=true is overwritten to false, (4) payload with additional arbitrary fields is returned with all fields intact. Write unit tests for insertActivity() helper verifying it always calls middleware.inject() before the Supabase insert. Add integration tests tracing each submission path (wizard, bulk, proxy) to confirm duplicate_reviewed=false is present in the inserted row.

Component
Duplicate Reviewed Flag Middleware
infrastructure low
Epic Risks (3)
high impact medium prob technical

The `check_activity_duplicates` RPC may not meet the 500ms target on production-scale data if the composite index is not applied correctly or if Supabase RLS evaluation adds unexpected overhead, causing the duplicate check to noticeably delay activity submission.

Mitigation & Contingency

Mitigation: Write the RPC with an explicit EXPLAIN ANALYZE in development against a seeded dataset representative of a large chapter (10,000+ activities). Pin the index hint in the RPC body and verify the query plan in Supabase's SQL editor before merging.

Contingency: If the 500ms target cannot be met with the RPC approach, introduce an async post-submit check pattern where the activity is saved first and the duplicate warning is surfaced as a follow-up notification, preserving submission speed at the cost of real-time blocking UX.

high impact medium prob security

RLS policies for the coordinator_duplicate_queue view must correctly scope results to the coordinator's chapters. Incorrect policies could expose duplicate records from other chapters (privacy violation) or hide legitimate duplicates (functional regression).

Mitigation & Contingency

Mitigation: Write explicit integration tests that verify RLS behaviour using at least three distinct coordinator + chapter combinations, including a peer mentor belonging to two chapters. Use Supabase's built-in RLS testing utilities.

Contingency: If RLS proves too complex for the queue view, move the chapter-scoping filter into the DuplicateQueueRepository query layer at the application level, trading database-enforced isolation for application-enforced scoping with full test coverage.

medium impact low prob dependency

Adding the duplicate_reviewed column to the activities table and the composite index requires a migration against a live table. If the migration locks the table for an extended period, it could disrupt active coordinators submitting activities.

Mitigation & Contingency

Mitigation: Use PostgreSQL's `CREATE INDEX CONCURRENTLY` to avoid table lock. Add the duplicate_reviewed column with a DEFAULT false so no backfill update lock is required. Schedule the migration during a low-traffic window.

Contingency: If concurrent index creation fails or takes too long, fall back to a smaller partial index scoped to the last 90 days of activities, then expand it incrementally.