critical priority low complexity backend pending backend specialist Tier 0

Acceptance Criteria

PauseStatusRecord Dart class is defined with fields: id (String), mentorId (String), status (PauseStatus enum: paused/active), pausedAt (DateTime?), resumedAt (DateTime?), reason (String?), createdAt (DateTime), updatedAt (DateTime)
PauseStatus enum covers all valid states used in the peer_mentor_profiles table
CoordinatorRelationship Dart class is defined with fields: coordinatorId (String), mentorId (String), chapterId (String), isPrimary (bool)
Abstract PauseStatusRecordRepository interface declares: fetchActivePauseRecord(String mentorId), resolveCoordinator(String mentorId), and watchPauseStatus(String mentorId) returning a Stream
All models implement copyWith, equality (==), hashCode, and toJson/fromJson
No concrete Supabase dependencies appear in model or interface files (pure Dart only)
All files are placed under lib/features/pause_status/domain/ following the existing project layer structure
Code compiles without warnings via flutter analyze

Technical Requirements

frameworks
Flutter
Dart
data models
PauseStatusRecord
CoordinatorRelationship
PauseStatus
performance requirements
Data models must be immutable value objects to support BLoC state equality checks
security requirements
No PII stored in model fields beyond the minimum required (mentorId, coordinatorId references only — no names or contact details in the domain layer)

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Follow the existing domain layer pattern used in other features (e.g., activity registration). Use freezed or manual immutability — check which pattern the codebase already uses and match it exactly. The PauseStatusRecordRepository interface should return Either or throw typed exceptions consistent with existing repository contracts in the project. The Stream-based watchPauseStatus method will be used by the BLoC to react to real-time Supabase changes.

Define a dedicated PauseStatusFailure sealed class (or extend an existing Failure hierarchy) covering: RecordNotFound, NetworkError, PermissionDenied. Keep value objects free of any Flutter imports — they must be usable in Dart-only contexts.

Testing Requirements

Unit tests for all models: (1) fromJson round-trip (serialize then deserialize, assert equality). (2) copyWith produces a new instance with only the specified field changed. (3) Equality: two instances with identical fields are equal. (4) PauseStatus enum covers all expected string values from the database.

(5) CoordinatorRelationship.isPrimary defaults correctly. No Supabase or Flutter widget dependencies in test files — pure Dart unit tests only.

Component
Pause Status Record Repository
data low
Epic Risks (3)
high impact medium prob integration

The org membership table structure used to resolve coordinator relationships may differ from what the repository assumes, causing incorrect coordinator lookup or missing rows for mentors in multi-chapter scenarios.

Mitigation & Contingency

Mitigation: Review the existing org membership table schema and RLS policies before writing repository queries. Align query logic with the patterns already used by peer-mentor-status-repository and multi-chapter-membership-service.

Contingency: If schema differs, add an adapter layer in the repository that normalises the membership resolution and document the discrepancy for the data team. Fall back to coordinator lookup via the feature's own stored coordinator_id field if org membership join fails.

high impact medium prob technical

Device tokens stored in the database may be stale or unregistered, causing FCM dispatch failures that silently drop coordinator notifications — the primary coordination safeguard of this feature.

Mitigation & Contingency

Mitigation: Implement token validation on every dispatch call and handle FCM's NOT_REGISTERED error by flagging the token as invalid in the database. Reuse the token refresh pattern already established by fcm-token-manager.

Contingency: If push delivery fails after retry, ensure the in-app notification record is always written regardless of push outcome so coordinators can still see the event in the notification centre.

medium impact low prob technical

The optional reason field may contain special characters, emoji, or non-Latin scripts that exceed the 200-character byte limit when FCM encodes the payload, causing delivery failures.

Mitigation & Contingency

Mitigation: Enforce the 200-character limit on Unicode code point count, not byte count, in the payload builder. Add a unit test with multi-byte input strings.

Contingency: If an oversized payload is detected at dispatch time, strip the reason field from the push notification body and note 'See in-app notification for full reason' to preserve delivery.