critical priority low complexity backend pending backend specialist Tier 0

Acceptance Criteria

PeerMentorProfile model exists with all fields matching the peer_mentors Supabase table schema, including nullable fields for org-specific branching (e.g., expected_return_date, certification_expiry)
CertificationRecord model exists with fields matching the certification_records table; all date fields are nullable to support orgs where certifications are not applicable
MentorActivitySummary model contains total_sessions (int), total_hours (double), unique_contacts_reached (int), and period (ActivityPeriod enum) fields
AssignedContact model contains all fields required to display a contact card on the peer mentor detail screen
Every model implements fromJson(Map<String, dynamic> json) factory constructor that correctly maps Supabase snake_case keys to Dart camelCase fields
Every model implements toJson() method returning Map<String, dynamic> with Supabase-compatible snake_case keys
Every model implements copyWith(...) method covering all fields
All fields are null-safe: required fields are non-nullable, optional org-specific fields are nullable with documented rationale in a comment
MentorStatus is defined as a Dart enum with values: active, paused, inactive; includes fromString factory for JSON deserialization
ActivityPeriod is defined as a Dart enum with values: last30Days, last90Days, yearToDate, allTime; includes toQueryParam() method returning the Supabase-compatible string
All model files are placed under lib/features/peer_mentor/data/models/ following the existing project layer structure
Unit tests pass for fromJson/toJson round-trip for all four models using representative fixture JSON

Technical Requirements

frameworks
Flutter
Dart
apis
Supabase REST API (read schema from peer_mentors, certification_records, mentor_activity_logs tables)
data models
PeerMentorProfile
CertificationRecord
MentorActivitySummary
AssignedContact
MentorStatus (enum)
ActivityPeriod (enum)
performance requirements
fromJson must not perform any I/O or async operations — pure synchronous transformation
Models must be immutable (all fields final) to enable safe use in BLoC state objects without unintended mutation
security requirements
No PII fields (name, phone, email) should have default non-null fallback values — always nullable to avoid leaking placeholder data
toJson must not include server-managed fields (created_at, updated_at) when used for INSERT/UPDATE payloads — provide a separate toInsertJson() if needed

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Follow the existing model conventions already present in the codebase (check lib/features/ for pattern). Use freezed or hand-write copyWith — match the existing pattern, do not introduce a new code-generation dependency unless freezed is already used. Supabase returns timestamps as ISO-8601 strings; parse with DateTime.parse() and store as DateTime?. For multi-tenant nullable fields, add a // org-specific: HLF only comment on the field declaration so future developers understand the branching intent.

Do NOT add json_serializable annotations unless the project already uses it — manual fromJson/toJson is preferred for explicit control over field mapping. Define MentorStatus and ActivityPeriod enums in separate files (lib/features/peer_mentor/domain/enums/) so they can be imported by both repository and BLoC layers without circular dependencies.

Testing Requirements

Unit tests using flutter_test. Create test/features/peer_mentor/data/models/ directory. Write one test file per model class. Each test file must cover: (1) fromJson with a fully-populated fixture map, (2) fromJson with all nullable fields set to null, (3) toJson round-trip equality, (4) copyWith preserves unchanged fields and overrides specified fields, (5) MentorStatus.fromString for all valid values and throws/returns fallback for unknown strings, (6) ActivityPeriod.toQueryParam returns expected strings.

Target 100% line coverage for model files.

Component
Peer Mentor Repository
data low
Epic Risks (3)
high impact medium prob security

Supabase RLS policies for peer mentor data may block coordinator queries if the RLS rules are written for peer-mentor-self access only, requiring policy updates that affect other features sharing the same tables.

Mitigation & Contingency

Mitigation: Review existing RLS policies on peer_mentors, certification_records, and activity_log tables before writing repository queries. Coordinate with the database team to add coordinator-role predicates without weakening existing mentor-self policies.

Contingency: If policy changes are blocked, implement a Supabase Edge Function as a secure query proxy that enforces authorization server-side, avoiding direct RLS policy modification.

medium impact medium prob technical

The activity log table schema may not have a mentor_id foreign key column or may require a JOIN through an intermediate table, making the aggregation query significantly more complex than anticipated.

Mitigation & Contingency

Mitigation: Inspect the actual Supabase activity_log table schema before starting the MentorActivityLogRepository implementation. Document the exact JOIN path needed and validate it returns correct results for a known mentor.

Contingency: If schema requires complex multi-table aggregation, implement a Supabase database function (RPC) and expose it via the repository's fetchSummary method to keep Dart code clean.

high impact low prob dependency

The Blindeforbundet assignment table may not yet exist in the shared Supabase schema or may have a different structure than assumed, blocking the AssignmentHistoryRepository implementation.

Mitigation & Contingency

Mitigation: Verify the assignments table exists and confirm its column structure with the Contact Detail & Edit Screen team which also depends on assignment data (assignment-repository in that feature).

Contingency: If the assignments table is not yet available, implement the AssignmentHistoryRepository with a stub returning empty list and a TODO marker, unblocking the aggregation service while the schema is finalized.