> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Training

> View, filter, and add staff training records for Recovery Housing, with expiry alerts, training type filters, and dialog-based creation.

The Training screen at `/rh/staff-operations/training` displays a list of staff training records for the current organization, with filters for training type and expiration window, an expiring-soon alert, and the ability to add new training records.

## Overview

The page loads training records via `useStaffTrainings`, which queries the `rh_staff_trainings` table scoped to `organization_id`, ordered by `expiry_date` ascending (nulls last). The hook computes a `days_until_expiry` field client-side using `differenceInDays` from `date-fns`. On mount, the page also queries trainings expiring within 30 days and with `is_current = true`; if any are found, a destructive `Alert` banner is shown with the count.

Filters: training type (`narr`, `slh`, `safety`, `other`), expiring-within window (`7`, `30`, `60`, `90` days), and a "Current Only" toggle (`is_current`). The **Add Training Record** button is gated by `PermissionGate` with `rh.staff-operations.create` and opens `StaffTrainingDialog`. Filters are applied both server-side (training type, `isCurrent`) and client-side (expiring-within-days).

## Who it's for

No route-level `RequirePermission` beyond the outer `RHViewGuard` (`rh.dashboard.view`). The **Add Training Record** button uses an inline `PermissionGate` requiring `rh.staff-operations.create`. Viewing records requires only `rh.dashboard.view`.

## Before you start

* Hold `rh.dashboard.view` to access the RH module and view training records.
* Hold `rh.staff-operations.create` to add new training records.
* Understand the training type taxonomy used by your organization (confirm with SME).

## Steps

<Steps>
  <Step title="Open Training">
    Navigate to `/rh/staff-operations/training`. The table loads all training records ordered by expiry date ascending.
  </Step>

  <Step title="Review the expiring-soon alert">
    If any current training records expire within the next 30 days, a destructive alert banner appears at the top of the page showing the count.
  </Step>

  <Step title="Filter by training type">
    Use the **Training Type** dropdown to filter by `NARR`, `SLH`, `Safety`, or `Other`. Select "All Types" to clear the filter.
  </Step>

  <Step title="Filter by expiration window">
    Use the **Expiring Within** dropdown to show only records expiring within 7, 30, 60, or 90 days. Select "All Trainings" to clear.
  </Step>

  <Step title="Show only current records">
    Toggle **Current Only** to limit the table to records where `is_current = true`.
  </Step>

  <Step title="Add a new training record">
    Click **Add Training Record** (visible to users with `rh.staff-operations.create`). The `StaffTrainingDialog` opens. Complete the form and save.
  </Step>
</Steps>

## Key concepts

<AccordionGroup>
  <Accordion title="Training types">
    Observable values: `narr`, `slh`, `safety`, `other`. The regulatory significance of each type (e.g., accreditation standards, licensing requirements) should be confirmed with a subject-matter expert.
  </Accordion>

  <Accordion title="Expiry calculation">
    `days_until_expiry` is computed client-side by `useStaffTrainings` using `differenceInDays(parseISO(expiry_date), today)`. Records with a null `expiry_date` have a null `days_until_expiry`.
  </Accordion>

  <Accordion title="Expiring-soon banner">
    The page queries `useStaffTrainings` with `{ expiringWithinDays: 30, isCurrent: true }` on load. If the result array is non-empty, a destructive `AlertTitle` "Expiring Trainings" banner is rendered above the filter controls.
  </Accordion>

  <Accordion title="Current-only filter">
    `is_current` is a boolean column on `rh_staff_trainings` applied as a server-side filter. Its definition (e.g., whether it reflects a manual flag or computed state) should be confirmed with a subject-matter expert.
  </Accordion>
</AccordionGroup>

## Creating a training record

The path `/rh/staff-operations/training/new` is not registered as a `<Route>` in `src/routes/rh.tsx` and does not resolve to a standalone component.

New staff training records are created via the `StaffTrainingDialog` modal, which opens from the "Add Training Record" button on the Staff Training list page at `/rh/staff-operations/training`. The "Add Training Record" button is wrapped in a `PermissionGate` requiring `rh.staff-operations.create`. The dialog renders `StaffTrainingForm`, which accepts staff employee ID, training type (`narr`, `slh`, `safety`, `other`), training name, completion date, optional expiry date, optional certification number, an `is_current` toggle, and optional notes.

Requires `rh.staff-operations.create` (on the "Add Training Record" button), plus the inherited `rh.dashboard.view` from `RHViewGuard`. Navigate to `/rh/staff-operations/training` and ensure you hold the `rh.staff-operations.create` permission to see the "Add Training Record" button.

<Steps>
  <Step title="Open Staff Training list">Navigate to `/rh/staff-operations/training`.</Step>
  <Step title="Click Add Training Record">Click the accent "Add Training Record" button (visible only with `rh.staff-operations.create` permission).</Step>
  <Step title="Fill in the form">Select the staff employee, training type, and enter the training name and completion date. Optionally add expiry date, certification number, and notes. Toggle "Current Only" to mark the record as currently valid.</Step>
  <Step title="Submit">Click the submit button to save the training record.</Step>
</Steps>

<AccordionGroup>
  <Accordion title="Expiring trainings alert">
    The Staff Training list page displays a destructive alert banner when one or more training records are expiring within 30 days (checked via `useStaffTrainings` with `expiringWithinDays: 30`).
  </Accordion>

  <Accordion title="Training types">
    Code-visible training type values are: `narr`, `slh`, `safety`, `other`. <Tooltip tip="SME: confirm what NARR and SLH stand for — not determinable from code.">Hover for note.</Tooltip>
  </Accordion>
</AccordionGroup>

## Related

<Columns cols={2}>
  <Card title="Recovery Housing" icon="house" href="/rh/references">
    Recovery Housing references and overview.
  </Card>

  <Card title="Governance & parity" icon="scale-balanced" href="/governance/index">
    Documentation coverage and governance.
  </Card>
</Columns>

<Note>
  This page documents shipped product behavior. It is not medical, legal, or
  billing advice. Verify against your organization's policies and applicable
  regulations before using it for clinical, compliance, or billing decisions.
  Protected health information (PHI) shown in the product is governed by your
  tenant's access controls and is never exposed in this documentation.
</Note>

<Accordion title="Documentation sources">
  * src/routes/rh.tsx
  * src/cores/rh/pages/StaffTrainingsPage.tsx
  * src/cores/rh/hooks/useStaffTrainings.ts
  * src/cores/rh/components/forms/StaffTrainingDialog.tsx
  * src/cores/rh/components/forms/StaffTrainingForm.tsx
  * src/cores/rh/types/index.ts
</Accordion>
