{
  "schema_version": 1,
  "type": "app",
  "slug": "safety-app",
  "title": "Safety App — Adom safety & health program",
  "brief": "Run the full Adom safety & health program: policy reader, periodic-task tracker, incident reporting, CAPA, risk register, OSHA forms, LOTO, HazCom, hourly Google Chat TODO digest, audit log. SQLite-ba",
  "version": "0.1.0",
  "tags": [],
  "license": "MIT",
  "discovery_triggers": [
    "safety program",
    "safety app",
    "Adom safety",
    "OSHA 300",
    "incident report",
    "near-miss report",
    "near miss",
    "log incident",
    "permit-to-work",
    "hot work permit",
    "confined space permit",
    "LOTO procedure",
    "lockout tagout",
    "hazardous energy",
    "HazCom",
    "SDS lookup",
    "safety data sheet",
    "chemical inventory",
    "PPE assessment",
    "PPE hazard assessment",
    "training records",
    "corrective action",
    "CAPA",
    "ISO 9001",
    "risk register",
    "facility inspection",
    "quarterly inspection",
    "audit log",
    "TODO digest",
    "hourly digest",
    "Google Chat reminder"
  ],
  "discovery_pitch": "Run an OSHA-compliant safety & health program out of one app — incidents, CAPA, risks, permits, LOTO, HazCom, OSHA forms, training, supplies, audit log. Hourly Google Chat TODO digest pings only when something changes. SQLite-backed, deploys on git push, 34-check Puppeteer e2e.",
  "install": {
    "binary_name": "safety-app",
    "install_dir": "",
    "install_hint": "",
    "version_cmd": ""
  },
  "readme": "# Adom Safety & Health Program\n\nA web app that runs the entire safety program for an Adom-style facility — policy reader, periodic-task tracker, incident reporting, OSHA recordkeeping, lockout/tagout register, hazard communication, and more — all backed by a SQLite database, a Google Chat reminder daemon, and an audit log of every mutating action.\n\n## Live URL\n\n**[r1fapjfs5ruv.adom.cloud](https://r1fapjfs5ruv.adom.cloud/)** — auto-deployed from `origin/main` every 2 minutes via watchdog cron on a dedicated `default-light` service container (`drew2-service-smokey`).\n\n## What's in it\n\nThe app has 16 left-nav tabs, each handling one slice of the safety program:\n\n- **Dashboard** — open obligations, overdue tasks, open CAPAs, high risks, upcoming compliance\n- **Policy** — five OSHA-aligned sub-programs (main program + EAP + HazCom + LOTO + PPE), versioned on every edit. Internal toggle for the assembled binder-ready full document.\n- **Periodic Tasks** — recurring obligations with cadence in days. \"Log completion\" rolls next-due forward.\n- **Incidents** — auto-numbered `INC-YYYY-####`. Root cause, corrective actions, OSHA recordable flag, CSV export.\n- **Corrective Actions** — ISO 9001-style CAPA register sourced from incidents / inspections / risks / audits.\n- **Risk Register** — 5×5 likelihood × severity heat map with current and residual scoring.\n- **Inspections** — template-driven checklists. Pass/fail/N/A per item; failure auto-creates a 14-day-due CAPA.\n- **Permits-to-work** — hot work, confined space, electrical, line break. Approval chain + expiry reminders.\n- **Chemical Exposures** — per-employee × per-chemical ledger with 30-year retention per HazCom.\n- **OSHA Forms** — printable HTML for Form 300 / 300A / 301. Browser → File → Print → PDF.\n- **Chemicals & SDS** — inventory with GHS hazard pills. New chemicals trigger a PubChem auto-lookup (CAS / SDS / hazards) → admin gets a Google Chat ping with a \"Review in app\" button.\n- **Equipment / LOTO** — 29 CFR 1910.147. Energy sources, written procedure per machine, audit cadence.\n- **PPE Assessments** — per-work-area hazard assessment + required PPE. Annual review reminder.\n- **Training Records** — append-only log of who-was-trained-on-what + expiry.\n- **Supplies & Ordering** — vendor links per category, bound to the policy that requires each item.\n- **Audit Log** — every mutating action stored with actor + before/after JSON. Tamper-evident.\n\nA QR-tag scan landing at `/scan/eq/:id` shows quick-action buttons for any equipment record.\n\n## What's special\n\n**Hourly Google Chat TODO digest.** A single Card v2 message lists every item that needs attention right now: due tasks, open CAPAs, expiring permits, open incidents, chemicals missing CAS/SDS, equipment missing LOTO procedures, PPE assessments past review. The card is sent **only when the list changes** and **at most once per hour** (top of hour). Completing items in the app rolls into the next hourly digest — no immediate ping. The dedup state is a single `reminder_digest` row keyed on a SHA-256 hash of the canonical TODO set.\n\n**PubChem auto-lookup with Google Chat approval.** Adding a new chemical triggers a fire-and-forget PubChem PUG-REST call that proposes CAS / IUPAC name / GHS signal word / H-codes / Sigma-Aldrich SDS URL. Admin gets a Google Chat ping with a \"Review in app\" button that lands them on a per-field accept/reject modal. Daily quota cap (80,000 req/day) and 5-req/sec pacer protect against tripping PubChem's published rate limits.\n\n**34-check Puppeteer e2e suite** runs against the live URL — every route, every CRUD round-trip, OSHA exports, QR-scan API, audit-log capture. Asserts no JS console errors and no failed network requests.\n\n**Audit log captures everything.** Every create / update / delete writes a row with actor email, action type, entity ID, IP, user-agent, request id, and full before-and-after JSON snapshots. Page versions are kept indefinitely for inspector review.\n\n**App-creator compliant UI.** Dark theme always (`#0d1117` page / `#161b22` panels), Familjen Grotesk + Satoshi + JetBrains Mono fonts, monochrome white SVG icons, frosted-glass cards, hover-delayed tooltips on every button (500ms, body-appended `position:fixed` per `human-ui-patterns §1d`), `GET /api/state` + `GET/POST /api/console` + dev-gated `POST /api/eval` for AI drivability, fixed Adom top-header bar on every page.\n\n## Architecture\n\n```\nService container (drew2-service-smokey, default-light)\n├── Express + SQLite    safety-app server, port 8090, public proxy URL\n├── reminder-daemon     ticks every 60s, fires hourly TODO digest to Google Chat\n└── cron watchdog       pulls origin/main every 2 min and bounces processes on change\n```\n\nA `.env` file at `/etc/safety-app.env` holds the GChat webhook URL, public base URL, and (optional) `SHUTDOWN_TOKEN`.\n\n## Repo\n\n`https://github.com/adom-inc/safety-app` (private, `adom-inc` org). Watch the [demo walkthrough video](https://github.com/adom-inc/safety-app/blob/main/demo/safety-app-walkthrough.mp4) for a 79-second tour of every left-nav tab.\n\n## Install on a fresh service container\n\n```bash\n# 1. Provision the container (only if you don't have one)\nadom-cli carbon user repo-create service-safety\nadom-cli carbon containers create --image-id 69b43b3e58d13e5ce628cdc5 \\\n  --repo-id <repo-id> --class small\n\n# 2. SSH in and run the idempotent provisioner from the repo\nssh <slug>@adom.cloud\ngit clone [email protected]:adom-inc/safety-app.git /home/adom/safety-app\nsudo tee /etc/safety-app.env > /dev/null <<EOF\nGCHAT_WEBHOOK_URL='https://chat.googleapis.com/v1/spaces/.../messages?key=...&token=...'\nPUBLIC_BASE_URL='https://<port-mapping-host>.adom.cloud'\nGCHAT_WEBHOOK_NAME='gchat-safety'\nEOF\nsudo chown adom:adom /etc/safety-app.env && sudo chmod 0600 /etc/safety-app.env\nbash /home/adom/safety-app/scripts/provision-service-container.sh\n\n# 3. Add a port mapping for 8090\nadom-cli carbon containers port-add <slug> --port 8090\n```\n\nThe watchdog cron pulls `origin/main` every 2 minutes, so future updates ship with `git push`.\n\n## Authored with\n\nClaude Code (Opus 4.7, 1M-context).\n",
  "author": {
    "name": "Kyle Bergstedt",
    "email": "[email protected]"
  },
  "visibility": {
    "public": true
  },
  "hero": null,
  "sample_prompts": [],
  "metadata": {},
  "created_at": "2026-05-28T05:29:01.895Z",
  "updated_at": "2026-05-28T05:29:01.895Z",
  "skills": []
}