# Policies & Safety Protocols Integration

## Purpose

Three pages — **Handbook & Policies**, **Safety Protocols**, and
**Acknowledgments** — are backed by one
unified store, `policy_documents` (it replaced the former generic `documents`
API, which has been removed). `category` selects the page (`handbook_policy` vs
`safety_protocol`); `tag` carries the finer sub-category (the handbook's
Operations/Behavior/… and the safety card icon). Staff acknowledgment is
**persisted per document version** via `policy_acknowledgments`.

## Frontend Structure

Handbook & Policies:

- Framework wrapper: `frontend/src/components/frameworks/HandbookPolicy.tsx`
- View components: `frontend/src/components/policies/`
- Business: `frontend/src/business/policies/{hooks,pageHooks,mappers,selectors}.ts`

Safety Protocols:

- Module: `frontend/src/components/safety-protocols/SafetyProtocolsModule.tsx`
  (+ `SafetyProtocolForm.tsx`, `SafetyDynamicListEditor.tsx`)
- Business: `frontend/src/business/safety-protocols/{hooks,mappers,selectors,types}.ts`

Acknowledgments:

- Page: `frontend/src/pages/modules/AcknowledgmentsPage.tsx`
- Business/API: `usePolicyAcknowledgmentReport` in
  `frontend/src/business/policies/hooks.ts`, backed by
  `frontend/src/shared/api/policyAcknowledgments.ts`
- Dashboard: `DirectorDashboard` includes the report summary as an overview card.

Shared:

- API layer: `frontend/src/shared/api/policyDocuments.ts`,
  `frontend/src/shared/api/policyAcknowledgments.ts`
- DTO types: `frontend/src/shared/types/policyDocuments.ts`
- Types/constants: `frontend/src/shared/types/policies.ts`,
  `frontend/src/shared/constants/policies.ts`,
  `frontend/src/shared/constants/safetyProtocols.ts`

## Backend Contract

- `GET /api/policy_documents?category=<handbook_policy|safety_protocol>`
- `POST /api/policy_documents`, `PUT /api/policy_documents/:id`,
  `DELETE /api/policy_documents/:id`
- `GET /api/policy_acknowledgments` (caller's own), `POST /api/policy_acknowledgments`
  (`{ data: { policyDocumentId } }` → acknowledges the current version)
- `GET /api/policy_acknowledgments/report` (manager report for current tenant
  scope: summary totals, per-document completion, and per-staff statuses)

A `policy_documents` row carries: `title`, `body`, `category`, `tag`, `author`
(display name of the creating user, server-set), `steps` +
`autism_considerations` (JSONB string arrays — author-filled structured content
for safety protocols), `version` (bumped on title/body/steps/considerations
change), `active`, tenant `organizationId` + nullable `campusId`.

## Behavior

- **Handbook**: `HandbookPolicy` calls `usePoliciesPage` and renders
  `PoliciesView` (hero, create/edit form, filters, list, cards, empty state).
  Sub-category maps to/from `tag`. Full add/edit/delete.
- **Safety Protocols**: `SafetyProtocolsModule` lists `safety_protocol` docs,
  rendering author-filled `steps` + autism considerations with a static per-`tag`
  icon. Managers get a FRAME-style authoring flow (header *New Protocol* →
  `SafetyProtocolForm`, per-card *Edit*/*Delete*) with **dynamic** steps +
  considerations rows (`SafetyDynamicListEditor`, add/remove per protocol).
- **Acknowledgment is persisted** (`usePolicyAcknowledgments` /
  `useAcknowledgePolicy`, shared by both pages) — it replaced the former
  session-local set. Re-acknowledgment is required after a version bump and is
  idempotent within a version.
- **Acknowledgment report** is available to owner, superintendent, principal,
  registrar, and director. Super/system admins can read it only while drilled
  into a tenant. The report counts active director/office_manager/teacher/
  support_staff accounts in the current scope.
- Management is gated by effective policy-document permissions, mirroring the backend grant.
- Both pages are seeded from `20260611050000-policy-documents-seed.ts`.

## Tests

- `business/policies/mappers.test.ts`, `business/policies/selectors.test.ts`
- `business/safety-protocols/mappers.test.ts`,
  `business/safety-protocols/selectors.test.ts`

## Verification

- `npm run typecheck`, `npm run lint`, `npm run test` pass.
