critical priority low complexity backend pending backend specialist Tier 6

Acceptance Criteria

ProxyRegistrationRequest is an immutable Dart class with required fields: coordinator_user_id, peer_mentor_id, activity_type, activity_date, duration_minutes, organisation_id; and optional fields: notes, location
ProxyRegistrationResult is a sealed class (or equivalent discriminated union pattern) with exactly three concrete subtypes: ProxyRegistrationSuccess, ProxyRegistrationDuplicateConflict, ProxyRegistrationError
ProxyRegistrationSuccess contains: the created ProxyActivityRecord and a confirmation timestamp
ProxyRegistrationDuplicateConflict contains: the conflicting existing record reference and a human-readable conflict reason string
ProxyRegistrationError contains: an error code enum (ProxyRegistrationErrorCode) and a message string; it does NOT contain raw exception objects or stack traces
ProxyRegistrationErrorCode enum covers at minimum: unauthorized, network_failure, validation_failure, unknown
All result types implement == and hashCode (or use package:equatable)
All classes have a copyWith method
ProxyRegistrationRequest validates that duration_minutes > 0 and activity_date is not in the future beyond a configurable threshold (e.g., 7 days) at construction time, throwing ArgumentError for invalid values
All types are exported from a single barrel file (e.g., proxy_registration_types.dart) to simplify imports

Technical Requirements

frameworks
Flutter
Dart
data models
ProxyActivityRecord
ProxyRegistrationRequest
ProxyRegistrationResult
ProxyRegistrationSuccess
ProxyRegistrationDuplicateConflict
ProxyRegistrationError
ProxyRegistrationErrorCode enum
performance requirements
All type instantiation must be O(1) — no async operations or I/O in constructors
security requirements
ProxyRegistrationError must not expose raw exception messages or stack traces to the BLoC — use structured error codes only
coordinator_user_id must be validated as a non-empty UUID string at construction to prevent empty-string injection

Execution Context

Execution Tier
Tier 6

Tier 6 - 158 tasks

Can start after Tier 5 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

Use Dart's sealed classes (Dart 3.0+) for ProxyRegistrationResult to enable exhaustive pattern matching in the BLoC — this eliminates the need for an 'else' branch and ensures new variants are caught at compile time. If the codebase targets Dart < 3.0, use a manual union pattern with a private constructor and static factory methods. Define ProxyRegistrationErrorCode as an enum (not string constants) so the BLoC switch statement is exhaustive. Keep validation logic in ProxyRegistrationRequest's constructor (or a validate() factory) rather than in the service, so the BLoC receives a validated request and the service can assume inputs are structurally correct.

Place all types in lib/features/proxy_registration/domain/types/ to keep the domain layer clean and free of framework dependencies.

Testing Requirements

Unit tests using flutter_test. Test ProxyRegistrationRequest construction with valid data (succeeds), with duration_minutes = 0 (throws ArgumentError), with a future activity_date beyond threshold (throws ArgumentError). Test the discriminated union: use pattern matching (switch on result type) to verify each variant is distinguishable and carries its expected payload. Test equality: two ProxyRegistrationSuccess instances with the same record are equal.

Test copyWith on all classes. Full test file under test/services/proxy_registration_types_test.dart.

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.