Adds a full CRUD system for user-defined violation types stored in a new
violation_types table. Custom types appear in the violation dropdown alongside
hardcoded types, grouped by category, with ✦ marker and a green Custom badge.
- db/database.js: auto-migration adds violation_types table on startup
- server.js: GET/POST/PUT/DELETE /api/violation-types; type_key auto-generated
as custom_<slug>; DELETE blocked if any violations reference the type
- ViolationTypeModal.jsx: create/edit modal with name, category (datalist
autocomplete from existing categories), handbook chapter reference,
description/reference text, fixed vs sliding point toggle, context field
checkboxes; delete with usage guard
- ViolationForm.jsx: fetches custom types on mount; merges into dropdown via
mergedGroups memo; resolveViolation() checks hardcoded then custom; '+ Add
Type' button above dropdown; 'Edit Type' button appears when a custom type is
selected; newly created type auto-selects; all audit calls flow through
existing audit() helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Establishes AI agent and developer guidelines covering data integrity rules
(immutable scoring fields, soft-delete contract, audit log append-only),
tier system canonical source, migration patterns, coding standards for both
backend and frontend, schema change checklist, PDF generation notes, and
forward-thinking development constraints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds express.static middleware for the demo/ directory mounted at /demo,
placed before the SPA catch-all so /demo/index.html resolves to the
standalone stakeholder demo page instead of the React app.
The /api/employees/:id/score endpoint previously only returned data from
the active_cpas_scores view (active_points + violation_count for the 90-day
window). The EmployeeModal score cards reference total_violations and
negated_count which were undefined, causing blank displays.
Now queries the violations table directly for all-time totals alongside
the rolling 90-day active data.
- Added acknowledgment signature workflow to "Logging a Violation" section (step 7)
- Added toast notification step to violation logging workflow (step 9)
- Updated Violation History section: amend now includes acknowledged-by/date fields
- Added PDF acknowledgment rendering note to Violation History
- Added "Toast Notifications" as standalone feature section
- Updated Amendable Fields to include acknowledged_by and acknowledged_date
- Updated Immutability Rules table with ack fields
- Moved acknowledgment signature and toast system to Shipped in roadmap
- Removed acknowledgment signature from Near-term (already shipped)
- Moved acknowledgment signature field from Proposed to Completed (Phase 7)
- Added toast notification system to Completed (Phase 7)
- Updated Violation Form features with acknowledgment section and toasts
- Updated Employee Profile Modal features with toast notifications
- Added Toast Notification System as standalone feature section
- Updated PDF Generation section: logo loaded from disk, ack rendering
- Updated Amendable Fields table with acknowledged_by and acknowledged_date
- Updated Database Schema section with new violation columns
- Updated Project Structure tree with ToastProvider.jsx and template.js description
- Updated API reference for POST /api/violations to note new fields
- Toast success/error on PDF download, negate, restore, hard delete
- Toast success on employee edit and violation amendment via modal callbacks
- Error details from API responses included in error toasts
- Reads mpm-logo.png from filesystem at startup, converts to base64 data URI dynamically
- Removes massive hardcoded LOGO_B64 constant (~5KB of source code eliminated)
- Falls back gracefully if logo file is not found (dev environments)
- Tries both dist/ and public/ paths for dev vs production compatibility
- Adds acknowledgment rendering: if acknowledged_by is set, shows filled name/date
instead of blank signature lines, with green "Acknowledged" badge on section header
- Blank signature lines still shown when acknowledgment is not provided