Commit Graph
19 Commits
Author SHA1 Message Date
adminandClaude Sonnet 4.6 a95273b182 feat(db): Drizzle DAL with withUser/asAdmin GUC wrapper (Phase 2)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 15:50:57 +08:00
adminandClaude Sonnet 4.6 6c1ad71643 feat: validate transport incident requires truck_id
Add 'transport' to INCIDENT_TYPES; add truck_id field to IncidentInput;
reject transport submissions missing truck_id.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
2026-07-13 10:50:13 +08:00
adminandClaude Sonnet 4.6 d10c690c12 feat: switch embeddings from Voyage AI to Google Gemini text-embedding-004
- embedText: call Gemini REST API (768-dim) instead of Voyage (1024-dim)
- Migration: drop+recreate incidents.embedding as vector(768), update
  match_incidents function, swap VOYAGE_API_KEY → GOOGLE_AI_API_KEY in app_settings
- Settings UI: relabel to "Google AI API Key (Embeddings)"
- All call sites updated (incidents POST, similar GET)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
2026-07-13 06:50:35 +08:00
adminandClaude Sonnet 4.6 614c792225 fix(security): VULN-009 magic-byte MIME validation + UTC date fix
- uploadEvidenceFile: validate file type via file-type magic bytes, reject
  client-supplied MIME, derive extension from detected type, upload ArrayBuffer
- getEscalationThreshold: use setUTCHours instead of setHours so date-only ISO
  strings (always UTC midnight) compare consistently in any timezone
- Tests: mock file-type, update upload expectation to ArrayBuffer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
2026-07-13 06:37:59 +08:00
adminandClaude Fable 5 576557181a feat: Phase 5 & 6 — usability, compliance hardening, analytics
Phase 5 (usability + compliance):
- In-app notification bell/badge: migration 016 adds read state + per-user
  RLS + create_in_app_notification SECURITY DEFINER RPC; /api/notifications;
  wired into incident creation, CAPA assign/verify, escalation cron
- Incident closure: new POST /api/incidents/[id]/close (requires verification
  status + all CAPAs verified); migration 017 locks closed incidents at DB
  level (update/delete triggers) with append-only incident_addenda + UI panel
- Server-side pagination on HSE/supervisor incident inboxes (.range, 25/page)
- Investigation form: alcohol/urine test result + witness statement refs
  (existing schema columns, now editable)
- Type-specific intake fields: migration 018 adds incidents.type_details
  JSONB; whitelist validation; environmental/asset/security/fire field
  groups in report form; EN/MS/ZH labels; offline queue support
- JKKP 8 annual register CSV export (/api/reports/jkkp8) + dashboard button
  + January statutory deadline banner
- Admin page: user invite (service-role client), role/site/active management,
  site + zone CRUD with QR report links — replaces Phase 0 stub
- Evidence gallery thumbnails via Supabase render transform with fallback

Phase 6 (analytics):
- 12-month stacked trend chart (leading/lagging/other) + top root causes
  (lib/dashboard/trends.ts pure helpers)
- AI rising-risk zones: /api/dashboard/ai/risk-flags aggregates 90-day
  zone stats, claude-opus-4-8 forced tool_use, panel on HSE + management
  dashboards, suggestion audit-logged

Also fixes 9 pre-existing missing /ims basePath prefixes in client fetches
and download links.

132 tests passing, tsc clean, next build clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPf5Rc8QPx6V8KLEEgfKEQ
2026-07-12 10:25:08 +08:00
admin c048878600 feat: PWA offline capture — IndexedDB queue, service worker cache, auto-sync on reconnect 2026-07-11 19:07:35 +08:00
adminandClaude Sonnet 4.6 87264a5497 feat: i18n — EN/MS/ZH translations with cookie-based locale switching, report form translated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 19:01:44 +08:00
adminandClaude Sonnet 4.6 b9def9c957 feat: CAPA effectiveness re-check cron — 30/60/90-day email + WhatsApp notifications
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 18:55:27 +08:00
adminandClaude Sonnet 4.6 a47f3aabc9 feat: WhatsApp notifications — new incident alert and CAPA overdue escalation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 18:50:25 +08:00
admin 121433ddf8 Revert "feat: WhatsApp notification helper + phase 4 migration (recheck_round, WhatsApp settings)"
This reverts commit b6845f5bb5.
2026-07-11 18:47:08 +08:00
admin b6845f5bb5 feat: WhatsApp notification helper + phase 4 migration (recheck_round, WhatsApp settings) 2026-07-11 18:43:57 +08:00
adminandClaude Sonnet 4.6 ebaa98d9f4 feat: Claude client + Voyage AI embed helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 16:10:26 +08:00
adminandClaude Opus 4.8 54332d0297 feat: JKKP 6/7 PDF generation via pdf-lib, download from incident detail
Also excludes node_modules.nosync from vitest test discovery to fix pre-existing bleed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 15:24:18 +08:00
adminandClaude Opus 4.8 75fa2605bf feat: CAPA overdue escalation cron — 4 thresholds, once-per-threshold via notifications_log
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr
2026-07-11 15:20:15 +08:00
admin 8b00c72014 feat: DOSH obligation pure function with NADOPOD 2004 rules 2026-07-11 14:51:35 +08:00
admin 2239b6e2df feat: email notifications via Resend on new incident 2026-07-10 13:24:44 +08:00
admin 3f8da5bd91 feat: incident report form, API route, middleware shared-route + redirect 2026-07-10 13:19:45 +08:00
admin a40a0f7c59 fix: signed URLs for private bucket, 10MB server-side limit, safe auth destructuring 2026-07-10 12:00:52 +08:00
admin 8a9758c8a6 feat: Phase 1 foundation - incident components, storage, and migrations 2026-07-10 10:48:56 +08:00