high priority low complexity infrastructure pending backend specialist Tier 4

Acceptance Criteria

duplicateCheckRepositoryProvider is a Provider<IDuplicateCheckRepository> that returns a SupabaseDuplicateCheckRepository instance with SupabaseClient injected from supabaseClientProvider
duplicateQueueRepositoryProvider is a Provider<IDuplicateQueueRepository> that returns a SupabaseDuplicateQueueRepository instance with SupabaseClient injected
duplicateReviewedFlagMiddlewareProvider is a Provider<DuplicateReviewedFlagMiddleware> registered as a singleton (not autoDispose) so all submission paths share the same instance
The wizard cubit provider reads duplicateReviewedFlagMiddlewareProvider from its ref parameter
The bulk registration service provider reads duplicateReviewedFlagMiddlewareProvider from its ref parameter
The proxy registration service provider reads duplicateReviewedFlagMiddlewareProvider from its ref parameter
All three providers have a doc comment explaining their purpose, the dependency they provide, and which consumers use them
Provider overrides for testing are possible: all providers accept interface types, not concrete types, enabling ProviderScope overrides in tests
No provider creates a SupabaseClient directly — all use the existing supabaseClientProvider

Technical Requirements

frameworks
Flutter
Riverpod
data models
IDuplicateCheckRepository
IDuplicateQueueRepository
DuplicateReviewedFlagMiddleware
performance requirements
duplicateReviewedFlagMiddlewareProvider must not be autoDispose — it is a stateless singleton with no cleanup needed
duplicateQueueRepositoryProvider should be autoDispose if the Realtime channel is tied to the repository lifecycle, to ensure channels are closed when the provider is disposed
security requirements
Providers must not store or expose the SupabaseClient directly in their public API — only inject it into repository constructors

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Place all three providers in lib/features/duplicate_detection/providers/duplicate_detection_providers.dart. Follow the existing project pattern for repository providers (look at how ActivityRepository or ContactRepository are registered as reference). Use final + Provider (not the concrete class) as the type annotation so that ProviderScope.overrides() works cleanly in tests. For the Realtime-backed DuplicateQueueRepository, consider whether the provider should be a StreamProvider or a plain Provider — if the repository manages the stream lifecycle internally, a plain Provider is sufficient and simpler.

Add a comment on duplicateQueueRepositoryProvider explaining when to use autoDispose vs keep-alive based on the Realtime channel strategy chosen in task-007.

Testing Requirements

Write flutter_test widget tests that use ProviderScope with overrides to inject mock implementations of IDuplicateCheckRepository and IDuplicateQueueRepository. Verify: (1) wizard cubit receives the middleware singleton via its provider, (2) bulk registration service receives the same middleware instance as the wizard cubit (same object reference), (3) proxy registration service receives the same middleware instance. These tests confirm the singleton contract without requiring a live Supabase connection.

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.