feat(kiosk): implement kiosk report submission functionality with offline support test(outbox): add tests for outbox functionality including report submission and error handling feat(outbox): create outbox management for queued reports with IndexedDB persistence feat(uuid): add UUID generation utility for client IDs feat(qr): implement QR code generation for reporting links by site and area feat(kiosk): create Kiosk page for reporting incidents without an account
6.7 KiB
6.7 KiB
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 |
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 |
| 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.jsxintopages/,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)
- Recordability wizard; days away / restricted / transferred tracking
- OSHA 300, 300A and 301 form generation; privacy-case handling
- ITA (Injury Tracking Application) CSV export
- Hours worked per site per month; TRIR, DART and lost-time rates
Phase 5: Analytics
- Trends, location breakdown, top root causes, corrective-action closure time
- Leading vs lagging indicators; filters and saved dashboards
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.