Files
jayjennings 61c876edec
CI / Lint, typecheck, test, build (push) Canceled after 0s
CI / End-to-end tests (push) Canceled after 0s
Add OSHA Form 301 and Osha page components
- Implemented Form301 component for displaying OSHA Form 301 equivalent, including employee and case information.
- Created Osha component to manage OSHA recordkeeping, including tabs for 300 Log, 300A Summary, Hours & rates, and Submit to OSHA.
- Added functionality for printing and downloading CSV files for OSHA submissions.
- Integrated loading and error handling states for data fetching.
2026-10-06 13:09:57 -07:00

8.7 KiB
Raw Permalink Blame History

Open SafetyLog EHS Roadmap

A free, open-source (AGPL-3.0) accident and safety tracking system for manufacturing.

This is a living document. Update it as decisions are made or scope changes.

Decisions

Topic Decision Status
License AGPL-3.0-only Decided
Frontend React + Vite + TypeScript, Tailwind CSS v4 Decided
Backend Node + Hono, PostgreSQL via Drizzle ORM, Zod schemas shared with the web app (shared/). Node runs the TypeScript directly (no build step for the server) Decided
Database PostgreSQL in production; embedded PGlite for local development, tests and very small installs Decided
Auth Email + password (scrypt), server-side sessions in an http-only cookie, four roles: reporter < supervisor < safety manager < admin Decided
Deployment Self-hosted, single docker compose up (app + Postgres); file storage added with photo upload Decided
Compliance scope US OSHA first; data model kept extensible for other regions (e.g. RIDDOR) Proposed
Incident PDFs Browser print-to-PDF from a print stylesheet; server-side PDF deferred (see TODO) Decided
Email SMTP via SMTP_URL; without it, logged in development and dropped in production. Delivery setup deferred (see TODO) Decided
Reporting without accounts "Reporting links": revocable, rate-limited tokens that can only file reports; used for kiosk tablets and QR codes Decided
Languages English + Spanish with typed message files; worker-facing screens first, manager screens later (see TODO) Decided
Offline Installable PWA; reports queued in IndexedDB and retried with a client-generated id so retries never duplicate Decided
OSHA rules One shared rules module (shared/osha.ts) used by API and UI; printable forms are OSHA-permitted equivalents (1904.29(b)(4)); ITA exports follow OSHA's published CSV specs Decided
Medical privacy Injured-person and medical details visible to safety managers and admins only; timeline and case CSV carry no names Decided
Charts Hand-built SVG components (no chart library) following the dataviz method: validated color slots, one axis, hairline grid, hover tooltips, a table view on every chart Decided
CI Gitea Actions (.gitea/workflows): lint, typecheck, unit tests, build, e2e Decided
Product name Open SafetyLog EHS (replaced placeholder "IA Tracker" and the prototype's "Safesite" branding) Decided

Phase 0: Foundation

  • AGPL-3.0 LICENSE
  • Convert to TypeScript
  • Split App.jsx into pages/, components/, lib/
  • Convert styling to Tailwind (remove hand-written App.css)
  • Remove unused template files
  • Bundle fonts locally (no Google Fonts dependency for offline/locked-down plant networks)
  • CI: lint, typecheck, unit tests (Vitest), build, e2e (Playwright)
  • Replace template README
  • CONTRIBUTING.md and CODE_OF_CONDUCT.md
  • About page with source-code link (AGPL section 13)
  • Remaining setup items (name, CoC contact, final source URL, CI runner): see TODO.md

Phase 1: Backend and data model

  • Database schema and first migration for all entities: Organization, Site → Area (location tree), User, Session, Incident, InjuredPerson, Attachment, Investigation, RootCause, CorrectiveAction, Comment, AuditLog, HoursWorked
  • First-run setup (creates the organization and first admin)
  • Email/password sign-in, sessions, change password, login rate limiting
  • Role-based permissions (reporters see only their own reports)
  • REST API: users, sites/areas, incidents with pagination, search, filters and gap-free sequential numbers (INC-0001); see API.md
  • Audit log of every change
  • Server tests (Vitest + in-memory PostgreSQL), demo seed data
  • Dockerfile and docker-compose.yml
  • Moved to Phase 2: magic-link sign-in and password reset by email (both need the email sending built for notifications). SSO/OIDC stays "later".

Phase 2: Core workflow (MVP)

  • Web app connected to the API: sign-in, first-run setup, every page on live data (demo data removed from the frontend)
  • Photo and PDF upload, checked by file content (not name), size-limited, served with a sandboxing security policy
  • Magic-link sign-in, password reset by email, email invitations for new users (admins can also set passwords when there's no email)
  • Incident detail page: details editing, activity log (comments + audit trail), investigation with 5 Whys and fishbone (6M) views, corrective actions (CAPA)
  • Status workflow Reported → Triage → Investigation → Corrective actions → Verification → Closed, with role rules and guards (e.g. high severity can't skip investigation; closing needs every action verified), shared between API and UI
  • "My actions" and "All actions" lists with overdue tracking; assignees can update progress on their own actions
  • Email notifications: high/critical alerts to safety managers, action assignment, daily due/overdue digest
  • CSV export of the filtered register (protected against spreadsheet formula injection); print-friendly incident page for PDF via the browser
  • Overview dashboard and Analytics computed from real data; Locations and Settings (people, roles, passwords) pages
  • End-to-end tests run against the real server: full three-role lifecycle, sign-in, visibility rules, mobile reporting

Phase 3: Shop-floor reporting

  • Installable app (web manifest, icons, service worker caching the app shell plus who-am-I and site lists)
  • Offline outbox: reports and photos saved on the device, sent automatically on reconnect; duplicate-proof retries via a client-generated id; reports only sent for the user who made them; warning on sign-out with unsent reports
  • Reporting links (managed in Settings): revocable tokens, optionally limited to one site, 30 reports per 10 minutes, photos included; kiosk page for shared tablets with large touch targets and auto-reset
  • Printable QR code sheets per site/area, for signed-in users or through a reporting link, with bilingual captions; scanning pre-fills the location
  • Anonymous reporting from the app, the kiosk and QR codes
  • English/Spanish: sign-in pages, navigation, report form, kiosk, My actions, offline messages; language toggle remembered per device; follows the browser language by default
  • Tests: outbox (IndexedDB), translations complete, reporting links and duplicate-proof retries on the server, browser tests for offline sync, Spanish kiosk via QR, QR pre-fill and installability

Phase 4: Compliance (US OSHA)

  • Injured/ill people per incident with a live recordability check (1904.4–1904.11): covered worker, work-related, new case, general criteria, special cases; most-serious-outcome classification; 14-item first-aid list and privacy-case rules shown in context
  • Day counts with the 180-day cap; days only counted when the matching outcome applies
  • Severe injury reporting (1904.39): 8-hour/24-hour deadline banner, email alert to safety managers, "reported to OSHA at" record
  • Form 300 Log (landscape print), Form 300A Summary with establishment details and certification block, printable Form 301 per case
  • Establishment details per site (address, NAICS, EIN, type) with validation
  • Monthly hours worked and headcount; TRIR, DART and LTIR
  • ITA CSV exports for the 300A summary and 300/301 case data (no names), plus OSHA's own upload checks run in the app
  • Tests: rules module unit tests, API tests incl. exact CSV output, browser test of the full recordkeeping flow

Phase 5: Analytics

  • One filter row (date range presets or custom, site, incident type) scoping every number and chart on the page
  • Leading indicators: hazards & near misses reported, near misses per injury, triaged within 24 hours, actions completed on time; each compared with the previous period
  • Lagging indicators: injuries, OSHA-recordable cases, rolling 12-month TRIR/DART, average days to close; OSHA rates by calendar year
  • Charts: reports per week/month by kind, rolling OSHA rates, locations (sites, or areas within a site), root causes, weekday × hour heatmap, actions completed on time vs late
  • Saved views (private, or shared by supervisors and above) on Analytics and the Incidents list
  • Demo seed with a year of realistic history (deterministic)
  • Tests: analytics computations (periods, groupings, rates, scoping), saved views, chart scale helper, browser tests

Phase 6: Release v1.0

  • Docker images, backup and restore
  • Demo instance with seed data
  • Documentation site and upgrade guide

Later

Inspections and audit checklists, job safety analysis (JSA), training and certification records, management of change, SDS links, public API and webhooks.