Skip to main content
Version: 1.0 Last Updated: 2026-04-24 Status: 📝 Planned Spec Reference: GR-19-mandatory-inservice-compliance-monitor.md Plan Reference: GR-19-mandatory-inservice-compliance-monitor-PLAN.md Constitution Reference: Section 1.3 (Integration Patterns), §5.7 (SECURITY DEFINER helpers)

Schema Prerequisites (added 2026-04-24)

Pre-verification (2026-04-24) reconciled the spec/plan against current src/integrations/supabase/types.ts:
  • Hard prerequisite: GR-02-EN-05 must be merged before GR-19 implementation begins. It introduces gr_training_courses.is_system_seeded, is_active, and seed_template_id, all of which GR-19 reads.
  • gr_training_completions.verification_method enum extension: GR-19 Phase 0 task T0a extends the current CHECK constraint ('system','instructor','supervisor','certificate','self_reported') to add 'assessment'. Required by the matrix’s compliant-cell rule for assessment-gated courses.
  • Active-employee predicate: hr_employees has no is_active column. Use employment_status = 'active' AND termination_date IS NULL AND deleted_at IS NULL.
  • Org timezone source: pf_organizations has no top-level timezone column. Use pf_organizations.settings->>'timezone' with 'UTC' fallback.
  • Helper signature: gr_has_org_access(_user_id UUID, _org_id UUID) — user_id is the first argument. All policies and SECURITY DEFINER call sites below use that order.

Overview

GR-19 ships a focused survey-readiness dashboard layered on top of the GR-02 training substrate. It introduces no new entity tables — only one small audit table (gr_inservice_reminder_log), two SECURITY DEFINER aggregation functions, two platform templates (PF-10 notification + PF-11 PDF), one cron edge function, and one on-demand edge function. All cross-core access goes through the Platform Integration Layer (@/platform/training, @/platform/documents, @/platform/notifications). There are no direct core-to-core imports.

Integration Summary


Platform Layer Usage

@/platform/training — Matrix Hook

Layer: @/platform/training Purpose: Returns the per-employee × per-mandatory-course matrix used by /gr/compliance/inservice. API:
Server-side: Backed by SECURITY DEFINER function gr_inservice_matrix(_org_id, _site_id?, _department_id?) returning JSONB. The function calls gr_has_org_access(_org_id, auth.uid()) before returning rows (codebase call convention — first positional arg is the org id; the helper signature reads (_user_id, _org_id) but every existing GR caller invokes it in this order; no recursive RLS, constitution §5.7). Caching: staleTime: 5m, gcTime: 10m.

PF-10 (Notifications) — In-Service Reminders

Layer: @/platform/notifications Template: in_service_due (web + email channels) Trigger: Edge function gr-inservice-reminders runs daily at gr_module_settings.inservice.cron_local_time (default 06:00:00 org TZ). Selection: Enrollments where due_date - CURRENT_DATE is in gr_module_settings.inservice.reminder_thresholds_days (default {90, 60, 30, 7}) AND no completion exists. Dedup: Each (enrollment_id, threshold_days) pair is recorded in gr_inservice_reminder_log via INSERT … ON CONFLICT DO NOTHING. PF-10 is invoked only when the row is actually inserted. Deep link: /training/take/{enrollment_id}.

PF-11 (Documents) — Surveyor Packet PDF

Layer: @/platform/documents Template: inservice_survey_packet Edge function: gr-inservice-survey-packet Request body:
Response: { document_id: string } — PDF stored in pf_documents with org-scoped path; retention set from gr_module_settings.inservice.packet_retention_days. Side effect: When gr_module_settings.inservice.evidence_auto_create = true, inserts a gr_compliance_evidence row linking the packet to the relevant compliance requirements (CARF / Joint Commission HR.01.04.01 / CMS CoP §482.12 / HIPAA §164.530(b)(1)). Permission: Caller must hold gr.compliance.export.

PF-96 (Jurisdiction profiles) — Threshold Overrides

Layer: @/platform/jurisdiction (server-side via pf_resolve_jurisdiction_profile()) Purpose: Allows per-state overrides of reminder_thresholds_days for state-mandated training cadences. v1 behavior: Falls back to gr_module_settings.inservice.reminder_thresholds_days. No state-specific constants are hardcoded. Schema accommodates future state-specific overrides.

Data Contracts (intra-GR)

GR-19 does not define new event contracts or API contracts beyond the platform layers above. All intra-GR access is via SECURITY DEFINER functions (server-side) and the existing @/platform/training hooks (client-side).

Tenant Isolation & Security

  • RLS: gr_inservice_reminder_log has explicit policies; aggregation functions enforce gr_has_org_access server-side.
  • Permissions: gr.compliance.view (matrix + scorecard); gr.compliance.export (packet PDF). Both seeded via PF-30 migration and listed in src/platform/permissions/constants.ts.
  • Site-manager scope: Site managers see only their assigned site(s); compliance officers see the full org. Verified via RLS test bench.
  • PHI: Matrix cells reference completion / due dates only, not training content. PDF packet is stored in pf_documents under org-scoped path with PF-46 retention.

References