10 KiB
Technical Specification
HSE Incident Management System — Build Spec for Claude Code
This document tells Claude Code how to build what 01_PRD_HSE_Incident_Management_System.md describes. Give Claude Code both files together. If you're new to coding: you don't need to understand every line below — just hand this file to Claude Code and let it explain each decision to you as it builds.
1. Recommended Tech Stack
Chosen for one reason above all: you're a beginner, so fewer moving parts = fewer things that can break and fewer things you need to host/manage yourself.
| Layer | Choice | Why |
|---|---|---|
| Frontend + backend | Next.js (React) | One framework handles both the web pages and the server logic — no separate backend project to manage |
| Database + Auth + File Storage | Supabase (hosted Postgres) | Gives you a database, user login system, and file storage (for photos/videos) in one dashboard, with a generous free tier. You don't manage servers. |
| Hosting | Vercel (frontend) + Supabase cloud | Both have simple free/low-cost tiers, deploy with a few clicks, no server administration |
| AI features | Claude API (Anthropic) | For triage suggestions, RCA/CAPA drafting, and the JKKP form auto-fill logic described in the PRD §8 |
| Notifications | Resend or SendGrid (email) + WhatsApp Business Cloud API (Meta) | Matches PRD §7 |
| QR codes | qrcode npm package (generates codes for each site/zone, no external cost) |
|
| PDF generation (JKKP forms) | pdf-lib (fills the official JKKP 6/7 PDF templates with stored data) |
Alternative stack (if you later hand this to a professional dev team instead of building it yourself): Python/FastAPI backend + PostgreSQL + AWS S3 for storage + React frontend. Same schema and logic below applies either way — this spec is written to be stack-agnostic where it matters.
Budget note: Video evidence storage is the main cost driver as usage grows. Start on Supabase's free/starter storage tier; if video volume grows heavy in Phase 3+, migrate large-file storage to Cloudflare R2 (cheaper for large files, still simple to set up) while keeping structured data in Supabase.
2. System Architecture (module view)
┌─────────────────────────────────────────────────────────┐
│ Reporter mobile/web app → QR scan → incident form │
└───────────────────────────┬─────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ Next.js application │
│ - Incident intake & workflow engine │
│ - CAPA module │
│ - Dashboard & analytics │
│ - Admin (users, sites, roles) │
└───────┬───────────────┬───────────────┬───────────────────┘
▼ ▼ ▼
┌───────────────┐ ┌──────────────┐ ┌─────────────────────┐
│ Supabase DB │ │ Supabase │ │ Claude API │
│ (Postgres) │ │ Storage │ │ - triage suggestion │
│ + Auth (RLS) │ │ (photos/ │ │ - RCA/CAPA drafting │
│ │ │ videos/docs)│ │ - JKKP form drafting │
└───────────────┘ └──────────────┘ └─────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Notifications: Email (Resend) + WhatsApp Cloud API │
└─────────────────────────────────────────────────────────┘
3. Database Schema
Core tables (Postgres). Claude Code should generate this as Supabase migrations. Field lists are the minimum required — add more as needed during build, don't remove any listed here.
sites — id, name, address, region, active zones — id, site_id (FK), name (e.g. "Dock A", "Cold Storage"), qr_code_token (unique) users — id, name, email, phone, role (enum: reporter/supervisor/hse/capa_owner/management/admin), department, site_id, active incidents — id, reference_no (unique, auto-generated), incident_type (enum: injury/near_miss/hazard/asset_damage/environmental/security/fire), site_id, zone_id, reported_by, reported_at, description, severity (1-5, nullable until triaged), status (enum: reported/triaged/investigating/capa_pending/verification/closed), injury_involved (bool), asset_involved (bool), medical_status (enum: none/first_aid/medical_treatment/lti, nullable), lost_days (int, nullable), closed_at (nullable) evidence_files — id, incident_id (FK), stage (enum: report/response/investigation/capa/verification), file_url, file_type, file_hash, uploaded_by, uploaded_at investigations — id, incident_id (FK), investigator_id, method (enum: five_why/fishbone/other), findings_text, root_cause_summary, alcohol_test_result (nullable), witness_statement_refs, completed_at capa_actions — id, incident_id (FK), root_cause_ref, description, owner_user_id, department, due_date, priority (enum: low/med/high), status (enum: open/in_progress/overdue/pending_verification/verified/reopened/closed), completed_at, verified_by, verified_at, effectiveness_recheck_date dosh_reports — id, incident_id (FK), form_type (enum: jkkp6/jkkp7/jkkp8), status (enum: not_required/pending/submitted), submitted_at, submitted_by, file_url (generated PDF) notifications_log — id, incident_id or capa_id, channel (email/whatsapp/in_app), recipient, sent_at, status audit_log — id, table_name, record_id, action, changed_by, changed_at, old_value, new_value
Row-level security (RLS): Enforce role-based access at the database level using Supabase RLS policies — e.g., a capa_owner can only see/update capa_actions rows where owner_user_id or department matches their own; a reporter can only see incidents where reported_by = themselves. This is safer than hiding buttons in the UI alone (per PRD §11).
4. Screens / Pages to Build
Organize as Claude Code build tasks in roughly this order (also see the phased roadmap doc):
- Login / role-based home redirect
- Report incident (mobile-first form, QR pre-fills site/zone, photo/video upload, offline-capable)
- My reports (reporter's own submission status tracker)
- Incident inbox (supervisor/HSE view — list + filters by site/status/severity)
- Incident detail (full timeline: report → response → investigation → CAPA → verification, with evidence gallery per stage)
- Triage panel (severity + classification, shows AI suggestion + regulatory checklist from PRD §9)
- Investigation workspace (RCA template picker: 5-Why / fishbone, findings entry, AI-drafted root cause/CAPA suggestions to accept or edit)
- CAPA board (Kanban + table view, filters, overdue highlighting)
- CAPA detail (owner uploads completion evidence, HSE verifies)
- Dashboard (KPIs, heatmap by site/zone, leading/lagging split, DOSH filing status — per PRD §10)
- DOSH register (JKKP 6/7 draft generator, JKKP 8 annual register export)
- Admin (manage users, sites/zones + QR generation, form field config)
5. AI Integration Details (Claude API)
Map directly to PRD §8. Each is a server-side call from Next.js to the Claude API, never client-side (keep your API key secret):
- Report quality check: on form submit, send description + evidence count to Claude; return a short list of missing items (e.g., "no photo attached for an injury report").
- Severity/category suggestion: send description + incident type; return suggested severity (1-5) + confidence + category, for the triaging user to confirm.
- Similar-incident retrieval: use vector embeddings (Supabase supports
pgvector) on incident descriptions; on new report, query top-5 similar past incidents by embedding distance + same site/zone. - RCA/CAPA drafting assistant: send investigation findings text; return suggested root cause categories and 2-3 draft CAPA descriptions for HSE to edit/accept.
- JKKP form drafting: send structured incident + investigation data in a prompt that asks Claude to produce the JKKP 6/7 field values as JSON; feed that JSON into
pdf-libto fill the actual form template.
All AI calls are logged (which incident, which suggestion, what the human ultimately chose) — this creates a useful dataset over time and keeps a clear line between "AI suggested" and "human decided," which matters if a record is ever audited.
6. Security & Auth
- Supabase Auth with email/password or phone OTP (phone OTP likely better adoption for warehouse floor staff without corporate email).
- Role stored in
users.role, enforced via RLS (see §3) — never trust role checks only in the frontend. - File uploads scanned/validated for type and size before storage.
- All admin actions (user role changes, site config) logged to
audit_log.
7. Deployment Recommendation
- Supabase project (free tier to start) → run schema migrations from §3.
- Next.js app → deploy to Vercel, connect to Supabase via environment variables (never commit API keys to code).
- Custom domain (e.g.
hse.setiacorp.com) once MVP is validated. - Set up Resend/WhatsApp Cloud API credentials as environment variables.
- Claude API key as environment variable, called only from server-side API routes.
This matches the phased build order in 03_Development_Roadmap_and_Claude_Code_Brief.md — start with local development, deploy to a free-tier staging environment after Phase 1 (MVP) so real users can start testing early.