@nswses/readiness
v1.0.2
Published
NSW SES units-of-competency domain logic and reports (Fit-For-Role and more)
Readme
@nswses/readiness
The domain engine behind Slipstream — an NSW SES unit tool for tracking members' training currency. This package turns an aXcelerate units-of-competency (UoC) export into capability findings and reports:
- Parsing a UoC CSV export into typed rows.
- Capability determination — deciding which capabilities each member holds from their achieved unit codes.
- Fit for Role gap analysis — which Fit for Role assessments a member is missing.
- Currency reports — First Aid and Code of Conduct expiry/currency.
- Reminders planning — which members have an item expiring within a threshold.
It has no database or UI. It takes data in and returns plain values, so the same logic runs in the web app, the CLI, and a scheduled email job without disagreeing.
Install
npm install @nswses/readinessBuilt and tested on Node 24 (the version this repo pins). Published from CI with a
provenance attestation via npm trusted publishing (no long-lived tokens) — see
docs/readiness-publishing.md.
Usage
Parse an export and print the Fit for Role gap report:
import { readFileSync } from "node:fs";
import { parseCsv, Snapshot } from "@nswses/readiness";
const rows = parseCsv(readFileSync("units-of-competency.csv", "utf8"));
const snapshot = new Snapshot({ attainedUnitsOfCompetency: rows });
console.log(snapshot.report()); // text Fit for Role gap report
snapshot.capabilitiesByMember(); // Map<memberId, Set<Capability>>
snapshot.gapsByCapability(); // missing Fit for Role assessments, per capabilityBuild a specific report as data (the web app renders these):
import { parseCsv, reportBySlug } from "@nswses/readiness";
const rows = parseCsv(csvText);
const firstAid = reportBySlug("first-aid"); // slug: "ffr" | "first-aid" | "code-of-conduct"
const table = firstAid?.compute(rows); // MemberReportRow[] — per-member status rowsWhat's in the public API
Everything is re-exported from the package root (import { ... } from "@nswses/readiness").
The main pieces:
| Area | Exports |
|---|---|
| Parsing | parseCsv, normalizeHeader, parseDdmmyyyy, formatYmd |
| Snapshot | Snapshot, unitsOfCompetency, ffrFor |
| Capabilities | capabilitiesFor, grantingCodesFor, capabilities, Capability |
| Reports | ffrReport, reports, reportBySlug, firstAidReport, codeOfConductReport |
| Currency | classifyCurrency, Currency, SOON_DAYS |
| Fit for Role views | ffrMemberDetails, CAPABILITY_COLUMNS, CAPABILITY_LABELS |
| Reminders | planReminders, reminderItems, REMINDER_THRESHOLDS |
| Units | unitsFor, resolveUnits, UNITS |
| Members | memberSummary, resolveMemberEmail, isMemberEmail |
Configuration, not code
Two things that change with SES policy live as validated JSON, so changing them is a data edit, not a code change:
src/capabilities.json— each capability's label, the unit codes that determine it, prerequisites, and its Fit for Role assessment block.src/units.json— the registry of real NSW SES unit names, used to attribute members to units and to recover space-joined location values from the export.
Both are checked by tests (capabilities.config.test.ts, units.config.test.ts).
Dates and time zones
This package is deliberately time-zone-free. It works in date-only calendar values
(parseDdmmyyyy + formatYmd, a symmetric local-midnight round-trip). Currency
classification takes an injected today, so the calling app decides the wall-clock
(Slipstream passes Sydney time). Don't add time-zone handling here.
Development
npm test --workspace packages/readiness # Jest + ts-jest, pure logic, no DB
npm run build --workspace packages/readinessTests use inline fixtures and never real member data.
License
MIT
