critical priority low complexity database pending database specialist Tier 0

Acceptance Criteria

pause_records table exists in Supabase with columns: id (uuid PK), mentor_id (uuid FK → user_profiles), status (text CHECK IN ('active','paused','expired_cert')), pause_reason (text nullable), expected_return_date (date nullable), paused_at (timestamptz nullable), reactivated_at (timestamptz nullable), coordinator_id (uuid FK → user_profiles nullable), created_at (timestamptz DEFAULT now()), updated_at (timestamptz DEFAULT now())
Migration script is idempotent (CREATE TABLE IF NOT EXISTS) and can be re-run without error
RLS policy: peer mentors can SELECT their own row only (auth.uid() = mentor_id)
RLS policy: coordinators can SELECT rows of mentors they manage (via chapter membership join)
RLS policy: INSERT and UPDATE permitted only by service role or coordinator role — mentors cannot directly mutate status column
Index exists on mentor_id for fast per-mentor lookups
Index exists on (coordinator_id, status) for coordinator roster queries
updated_at column auto-updates via trigger on any row change
Exactly one active pause_records row per mentor enforced via partial unique index: UNIQUE (mentor_id) WHERE status IN ('paused', 'expired_cert')
Migration includes rollback script that safely drops table and indexes

Technical Requirements

frameworks
Supabase migrations (SQL)
apis
Supabase Management API (for applying migrations in CI)
data models
pause_records
user_profiles
chapter_memberships
performance requirements
Single mentor lookup by mentor_id must resolve in < 10ms on p95
Coordinator roster query for up to 200 mentors must resolve in < 100ms
security requirements
Row Level Security enabled on pause_records table at creation time
No direct status mutation by mentor role — enforced at RLS level
coordinator_id column must reference a user with coordinator or admin role (enforced via trigger or FK to a coordinators view)
pause_reason field must not exceed 500 characters — enforce via CHECK constraint

Execution Context

Execution Tier
Tier 0

Tier 0 - 440 tasks

Implementation Notes

Apply the migration via Supabase CLI (`supabase migration new pause_records`). Use `supabase db reset` locally to verify idempotency. The partial unique index (`WHERE status IN ('paused', 'expired_cert')`) is the correct pattern to allow a mentor to have multiple historical rows (active periods) while enforcing only one live paused/expired row. Do NOT use a single row per mentor design — retaining history is required for audit trails and Bufdir reporting.

The coordinator_id column records who last managed the status, not a permanent assignment; chapter membership is the source of truth for coordinator–mentor relationships. Ensure the migration runs before any application code referencing the table is deployed.

Testing Requirements

Write SQL-level integration tests using Supabase's pgTAP or a local Supabase instance. Test cases: (1) Insert valid row with all required fields succeeds. (2) Insert with invalid status value fails CHECK constraint. (3) Insert second paused row for same mentor fails partial unique index.

(4) Mentor JWT can SELECT own row, cannot SELECT another mentor's row. (5) Coordinator JWT can SELECT rows of their mentors. (6) Mentor JWT cannot UPDATE status column. (7) updated_at trigger fires on UPDATE.

(8) Rollback script successfully removes all objects. Run all tests in CI against a clean Supabase local instance.

Component
Peer Mentor Status Repository
data medium
Epic Risks (3)
medium impact medium prob technical

Concurrent status transitions (e.g., coordinator and automated scheduler both attempting to update the same mentor's status simultaneously) may produce race conditions or inconsistent state in the database, leading to audit log gaps or incorrect notifications.

Mitigation & Contingency

Mitigation: Implement all status transitions as atomic Postgres RPC functions with optimistic locking (version column or updated_at check). Use database-level constraints rather than application-level guards as the final enforcement point.

Contingency: Add a compensation job that reconciles status and log table consistency on each nightly scheduler run, surfacing any discrepancies to coordinator dashboards.

medium impact medium prob integration

The coordinator-to-mentor assignment relationship may not always be 1:1 or may be stale (coordinator reassigned after a pause was set), causing notifications to be sent to the wrong coordinator or not sent at all.

Mitigation & Contingency

Mitigation: Query the assignment relationship at notification dispatch time rather than caching it at pause creation time. Add a fallback to notify the chapter administrator if no active coordinator assignment exists.

Contingency: Log all undeliverable notification attempts with the originating mentor ID so administrators can manually follow up, and surface undelivered notification counts on the coordinator dashboard.

medium impact low prob technical

The CoordinatorPauseRosterScreen may load slowly for coordinators managing large rosters with many concurrent certification expiry queries, degrading usability on low-bandwidth mobile connections.

Mitigation & Contingency

Mitigation: Use a single Supabase RPC that joins mentor status, certification expiry, and assignment data in one query rather than N+1 individual calls. Implement pagination with a configurable page size and skeleton loading states.

Contingency: Add an offline cache of the last-fetched roster state using Riverpod with SharedPreferences, ensuring coordinators can at minimum view stale data when connectivity is poor.