Reviewed-on: #22
CPAS Violation Tracker
Single-container Dockerized web app for CPAS violation documentation and workforce standing management. Built with React + Vite (frontend), Node.js + Express (backend), SQLite (database), and Puppeteer (PDF generation).
The only requirement on your machine: Docker Desktop
Everything else — Node.js, npm, React build, Chromium for PDF — happens inside Docker.
Quickstart (Local)
# 1. Build the image (installs all deps + compiles React inside Docker)
docker build -t cpas-tracker .
# 2. Run it
docker run -d --name cpas-tracker \
-p 3001:3001 \
-v cpas-data:/data \
cpas-tracker
# 3. Open
# http://localhost:3001
Export for Unraid
docker save cpas-tracker | gzip > cpas-tracker.tar.gz
Then follow README_UNRAID_INSTALL.md.
Update After Code Changes
docker build -t cpas-tracker .
docker stop cpas-tracker && docker rm cpas-tracker
docker run -d --name cpas-tracker -p 3001:3001 -v cpas-data:/data cpas-tracker
Features
Company Dashboard
- Live table of all employees sorted by active CPAS points (highest risk first)
- Summary stat cards: total employees, elite standing (0 pts), with active points, at-risk count, highest active score
- At-risk badge: flags employees within 2 points of the next tier escalation
- Search/filter by name, department, or supervisor
- Click any employee name to open their full profile modal
Violation Form
- Select existing employee or enter new employee by name
- Employee intelligence: shows current CPAS standing badge and 90-day violation count before submitting
- Violation type dropdown grouped by category; shows prior 90-day counts inline
- Recidivist auto-escalation: if an employee has prior violations of the same type, points slider auto-sets to maximum per policy
- Repeat offense badge with prior count displayed
- Context-sensitive fields (time, minutes late, amount, location, description) shown only when relevant to violation type
- Tier crossing warning (TierWarning component): previews what tier the new points would push the employee into before submission
- Point slider for discretionary adjustments within the violation's min/max range
- One-click PDF download immediately after submission
Employee Profile Modal
- Full violation history with resolution status
- Negate / restore individual violations (soft delete with resolution type + notes)
- Hard delete option for data entry errors
- PDF download for any historical violation record
CPAS Tier System
| Points | Tier | Label |
|---|---|---|
| 0–4 | 0–1 | Elite Standing |
| 5–9 | 1 | Realignment |
| 10–14 | 2 | Administrative Lockdown |
| 15–19 | 3 | Verification |
| 20–24 | 4 | Risk Mitigation |
| 25–29 | 5 | Final Decision |
| 30+ | 6 | Separation |
Scores are computed over a rolling 90-day window (negated violations excluded).
PDF Generation
- Puppeteer + system Chromium (bundled in Docker image)
- Generated on-demand per violation via
GET /api/violations/:id/pdf - Filename:
CPAS_<EmployeeName>_<IncidentDate>.pdf - PDF captures prior active points at the time of the incident (snapshot stored on insert)
API Reference
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health |
Health check |
| GET | /api/employees |
List all employees |
| POST | /api/employees |
Create or upsert employee |
| GET | /api/employees/:id/score |
Get active CPAS score for employee |
| GET | /api/dashboard |
All employees with active points + violation counts |
| POST | /api/violations |
Log a new violation |
| GET | /api/violations/employee/:id |
Get violation history for employee (with resolutions) |
| PATCH | /api/violations/:id/negate |
Negate a violation (soft delete + resolution record) |
| PATCH | /api/violations/:id/restore |
Restore a negated violation |
| DELETE | /api/violations/:id |
Hard delete a violation |
| GET | /api/violations/:id/pdf |
Download violation PDF |
Project Structure
cpas/
├── Dockerfile # Multi-stage: builds React + runs Express w/ Chromium
├── .dockerignore
├── package.json # Backend (Express) deps
├── server.js # API + static file server
├── db/
│ ├── schema.sql # Tables + 90-day active score view
│ └── database.js # SQLite connection (better-sqlite3)
├── pdf/
│ └── generator.js # Puppeteer PDF generation
└── client/ # React frontend (Vite)
├── package.json
├── vite.config.js
├── index.html
└── src/
├── main.jsx
├── App.jsx
├── data/
│ └── violations.js # All CPAS violation definitions + groups
├── hooks/
│ └── useEmployeeIntelligence.js # Score + history hook
└── components/
├── CpasBadge.jsx # Tier badge + color logic
├── TierWarning.jsx # Pre-submit tier crossing alert
├── Dashboard.jsx # Company-wide leaderboard
├── ViolationForm.jsx # Violation entry form
├── EmployeeModal.jsx # Employee profile + history modal
├── NegateModal.jsx # Negate/resolve violation dialog
└── ViolationHistory.jsx # Violation list component
Database Schema
Three tables + one view:
employees— id, name, department, supervisorviolations— full incident record includingprior_active_pointssnapshot at time of loggingviolation_resolutions— resolution type, details, resolved_by (linked to violations)active_cpas_scores(view) — sum of points for non-negated violations in rolling 90 days, grouped by employee
Roadmap
✅ Completed
| Phase | Feature | Description |
|---|---|---|
| 1 | Container scaffold | Docker multi-stage build, Express server, SQLite schema |
| 1 | Base violation form | Employee fields, violation type, incident date, point submission |
| 2 | Employee intelligence | Live CPAS standing badge and 90-day count shown before submitting |
| 2 | Prior violation highlighting | Violation dropdown annotates types with 90-day recurrence counts |
| 2 | Recidivist auto-escalation | Points slider auto-maximizes on repeat same-type violations |
| 2 | Violation history | Per-employee history list with resolution status |
| 3 | PDF generation | Puppeteer/Chromium PDF per violation, downloadable immediately post-submit |
| 3 | Prior-points snapshot | prior_active_points captured at insert time for accurate historical PDFs |
| 4 | Company dashboard | Sortable employee table with live tier badges and at-risk flags |
| 4 | Stat cards | Summary counts: total, clean, active, at-risk, highest score |
| 4 | Tier crossing warning | Pre-submit alert when new points push employee to next tier |
| 4 | Employee profile modal | Full history, negate/restore, hard delete, per-record PDF download |
| 4 | Negate & restore | Soft-delete violations with resolution type + notes, fully reversible |
🔲 Proposed
Reporting & Analytics
- Violation trends chart — line/bar chart of violations per day/week/month, filterable by department or supervisor; useful for identifying systemic patterns vs. individual incidents
- Department heat map — grid view showing violation density and average CPAS score by department; helps supervisors identify team-level risk
- Expiration timeline — visual showing which active violations will roll off the 90-day window and when, so supervisors can anticipate tier drops
- CSV / Excel export — bulk export of violations or dashboard data for external reporting or payroll integration
Employee Management
- Employee edit / merge — ability to update employee name, department, or supervisor without losing history; merge duplicate records created by name typos
- Supervisor view — scoped dashboard showing only the employees under a given supervisor, useful for multi-supervisor environments
- Employee notes / flags — free-text notes attached to an employee record (e.g. "on PIP", "union member") visible in the profile modal without affecting scoring
Violation Workflow
- Acknowledgment signature field — a "received by employee" name/date field on the violation form that prints on the PDF, replacing the blank signature line
- Draft / pending violations — save a violation as draft before finalizing, useful when incidents need review before being officially logged
- Violation amendment — edit a submitted violation's details (not points) with an audit trail, rather than delete-and-resubmit
- Bulk violation import — CSV import for migrating historical records from paper logs or a prior system
Notifications & Escalation
- Tier escalation alerts — email or in-app notification when an employee crosses into Tier 2+ so the relevant supervisor is automatically informed
- Scheduled summary digest — weekly email to supervisors listing their employees' current standings and any approaching tier thresholds
- At-risk threshold configuration — make the "at-risk" warning threshold (currently hardcoded at 2 pts) configurable per deployment
Infrastructure & Ops
- Multi-user auth — simple login with role-based access (admin, supervisor, read-only); currently the app has no auth and is assumed to run on a trusted internal network
- Audit log — immutable log of all creates, negates, restores, and deletes with timestamp and acting user, stored separately from the violations table
- Automated DB backup — cron job or Docker health hook to snapshot
/data/cpas.dbto a mounted backup volume or remote location on a schedule - Dark/light theme toggle — the UI is currently dark-only; a toggle would improve usability in bright environments
Proposed features are suggestions based on common HR documentation workflows. Priority and implementation order should be driven by actual operational needs.
Description
Languages
JavaScript
98.8%
Dockerfile
0.9%
HTML
0.3%