critical priority medium complexity backend pending backend specialist Tier 8

Acceptance Criteria

ProxyRegistrationService calls ProxyDuplicateDetectionService before any Supabase write operation is initiated
The duplicate check receives both the attributed peer_mentor_id and the complete activity details (type, date, time, duration)
When a duplicate is detected, a ProxyRegistrationDuplicateConflict result is returned containing the conflicting record's ID, date, and activity type
The repository persist step is never called when a duplicate is detected — no partial writes occur
When no duplicate is detected, execution continues normally to the next step in the service flow
ProxyRegistrationDuplicateConflict carries enough data for the BLoC to display conflict details without additional queries
Duplicate detection errors (e.g. Supabase timeout) are caught and mapped to ProxyRegistrationError, not silently swallowed
Unit tests confirm that the persistence method is never invoked when the detection service returns a conflict

Technical Requirements

frameworks
Flutter
BLoC
Riverpod
apis
Supabase REST API
Supabase RPC (duplicate detection query)
data models
ProxyActivityRecord
ProxyRegistrationDuplicateConflict
ProxyRegistrationResult
performance requirements
Duplicate detection query must complete within 2 seconds under normal network conditions
No redundant Supabase queries — a single RPC call should cover the full duplicate check scope
security requirements
peer_mentor_id must be validated against the coordinator's permitted scope before passing to the detection service
No raw user-supplied strings passed directly into Supabase queries — use parameterized RPC calls
Sensitive activity details must not be logged in plain text

Execution Context

Execution Tier
Tier 8

Tier 8 - 48 tasks

Can start after Tier 7 completes

Dependencies (10)
epic-proxy-activity-registration-core-services-task-001 component Cross-Epic Component proxy-registration-service depends on proxy-duplicate-detection-service
epic-proxy-activity-registration-core-services-task-002 component Cross-Epic Component proxy-registration-service depends on proxy-duplicate-detection-service
epic-proxy-activity-registration-core-services-task-003 component Cross-Epic Component proxy-registration-service depends on proxy-duplicate-detection-service
epic-proxy-activity-registration-core-services-task-008 component Cross-Epic Component proxy-registration-service depends on proxy-duplicate-detection-service
epic-proxy-activity-registration-core-services-task-004 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
epic-proxy-activity-registration-core-services-task-005 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
epic-proxy-activity-registration-core-services-task-006 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
epic-proxy-activity-registration-core-services-task-007 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
epic-proxy-activity-registration-core-services-task-009 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
epic-proxy-activity-registration-core-services-task-010 component Cross-Epic Component proxy-registration-service depends on activity-attribution-service
Dependents (18)
epic-proxy-activity-registration-ui-task-001 component Cross-Epic Component bulk-participant-list depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-002 component Cross-Epic Component bulk-participant-list depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-003 component Cross-Epic Component bulk-participant-list depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-004 component Cross-Epic Component duplicate-warning-dialog depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-005 component Cross-Epic Component duplicate-warning-dialog depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-006 component Cross-Epic Component duplicate-warning-dialog depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-007 component Cross-Epic Component proxy-peer-mentor-selector depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-008 component Cross-Epic Component proxy-peer-mentor-selector depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-009 component Cross-Epic Component proxy-peer-mentor-selector depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-010 component Cross-Epic Component proxy-activity-form depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-011 component Cross-Epic Component proxy-activity-form depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-012 component Cross-Epic Component proxy-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-013 component Cross-Epic Component proxy-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-014 component Cross-Epic Component proxy-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-015 component Cross-Epic Component bulk-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-016 component Cross-Epic Component bulk-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-017 component Cross-Epic Component bulk-registration-screen depends on proxy-registration-service
epic-proxy-activity-registration-ui-task-018 component Cross-Epic Component proxy-registration-bloc depends on proxy-registration-service

Implementation Notes

Model ProxyRegistrationResult as a sealed class (or freezed union) with variants: ProxyRegistrationSuccess, ProxyRegistrationDuplicateConflict, ProxyRegistrationError. The duplicate detection call should be the first async operation inside the registration method — place it before any attribution or persistence logic. Use Dart's sealed classes (Dart 3+) or the freezed package for exhaustive pattern matching in the BLoC. The conflict result should include at minimum: conflicting_activity_id, conflicting_date, peer_mentor_id, and activity_type so the UI can show a meaningful message.

Ensure the detection service dependency is injected (not constructed inline) to keep the service testable. Avoid catching broad Exception types — only catch expected Supabase/network errors and rethrow unknown errors.

Testing Requirements

Write unit tests using flutter_test with mocked ProxyDuplicateDetectionService and ProxyActivityRepository. Test cases must cover: (1) duplicate detected → conflict result returned, repository never called; (2) no duplicate → execution proceeds to next step; (3) detection service throws exception → mapped to ProxyRegistrationError; (4) detection service called with correct peer_mentor_id and full activity payload. Achieve 100% branch coverage on the duplicate check guard. Integration test against a Supabase test environment to verify the RPC query returns the correct conflicting record.

Component
Proxy Registration Service
service medium
Epic Risks (3)
high impact low prob integration

If the Supabase batch RPC partial-inserts some records before encountering an error and does not roll back cleanly, the bulk service may report failure while orphaned records exist in the database, corrupting reporting data.

Mitigation & Contingency

Mitigation: Wrap the bulk insert in an explicit Supabase transaction via the RPC function. Write an integration test that simulates a mid-batch constraint violation and asserts zero records were written.

Contingency: If a partial-write incident occurs, the registered_by audit field allows identification and deletion of the orphaned records. Implement a coordinator-facing bulk submission status screen to surface any such anomalies.

medium impact medium prob scope

When a bulk submission of 15 participants has 4 duplicates, the aggregated conflict summary may be too complex for coordinators to process quickly, leading to blanket override decisions that defeat the purpose of duplicate detection.

Mitigation & Contingency

Mitigation: Design the conflict result type to support per-participant override flags, so the UI can present a clear list of conflicting participants with individual cancel/override toggles rather than a single global decision.

Contingency: If coordinator usability testing reveals the conflict review screen is too complex, simplify to a 'skip all conflicts and submit the rest' mode as an immediate fallback while a more granular UI is designed.

high impact low prob security

If the coordinator role check inside proxy-registration-service is inconsistent with the route-level guard, a regression in the guard could allow peer mentors to call the service directly via deep links, submitting records with incorrect attribution.

Mitigation & Contingency

Mitigation: Enforce role authorization at both the route guard level (coordinator-role-guard) and inside each service method independently. Write a security test that calls the service directly with a peer mentor session token and asserts rejection.

Contingency: If a bypass is discovered, immediately enable the server-side RLS policy as the final enforcement layer and audit any records written during the exposure window using the registered_by field.