# Rigging Register — Project TODO

## Database & Backend
- [x] Add riggingItems table to drizzle/schema.ts with all required fields
- [x] Add serviceNotificationSettings table for email config
- [x] Generate and apply migration SQL
- [x] Add DB query helpers in server/db.ts
- [x] Add tRPC router: rigging.list, rigging.getById, rigging.create, rigging.update, rigging.delete
- [x] Add tRPC router: rigging.exportExcel (returns xlsx buffer)
- [x] Add tRPC router: settings.get, settings.update (notification email config)
- [x] Add periodic heartbeat for service due email notifications (scheduled handler at /api/scheduled/service-notifications)
- [x] Public (unauthenticated) procedure: rigging.getPublic for QR code page

## Frontend — Global
- [x] Design system: dark/industrial theme with amber accent, premium typography
- [x] Global CSS variables and Tailwind theme in index.css
- [x] DashboardLayout with sidebar navigation (Dashboard, Register, Settings)
- [x] App.tsx routes: /, /register, /item/:id, /public/item/:id, /settings

## Frontend — Pages
- [x] Dashboard page: summary cards (total, due, overdue, ok), status chart, recent items table
- [x] Register page: full CRUD table with search/filter (type, status, service date)
- [x] Add/Edit Item dialog/form with all required fields
- [x] Item Detail page (authenticated): full item view + QR code display + download
- [x] Public Item Detail page (no auth required): all item info, accessible via QR link
- [x] Settings page: notification email address, service interval days config

## Features
- [x] QR code generation per item (links to /public/item/:id)
- [x] QR code download as PNG
- [x] Excel export of full register (.xlsx)
- [x] Service interval email notifications (automated, owner-facing)
- [x] Search by name/serial number
- [x] Filter by type, status, next service date range

## Tests
- [x] Vitest: rigging CRUD procedures
- [x] Vitest: Excel export procedure
- [x] Vitest: notification settings procedure

## Gaps Addressed
- [x] Add date range filter to Register UI (dueBefore/dueAfter)
- [x] Add status distribution chart to Dashboard
- [x] Ensure notes field always shows on public item page
- [x] Heartbeat cron registered (task_uid: ULkhhzWcSLZhPAWQTzdSgm, daily 08:00 UTC) — activates on first Publish
- [x] Add success-path Vitest coverage for CRUD, Excel, and settings

## New Requests
- [x] Create dedicated QR code viewer page (download/print only, no item details)
- [x] Add type-based rigging code prefixes (e.g., RIG-CS-001 for chain slings)
- [x] Add custom "Assigned" field to rigging items table and forms


## Rebranding to Dredge Robotics
- [x] Update app title to "Dredge Robotics Rigging Register" (via Management UI Settings)
- [x] Update color scheme: dark navy blue, bright red (#d32f2f), lime green accents
- [x] Update typography: Poppins font throughout
- [x] Update DashboardLayout sidebar with full "Dredge Robotics Rigging Register" branding
- [x] Update CSS theme variables in index.css with Dredge color palette
- [x] Update Dashboard unauthenticated screen with Dredge branding
- [x] Update all status badges and accent colors to match Dredge Robotics
- [x] All tests passing, 0 TypeScript errors


## Bug Fixes Completed
- [x] Fix: Overdue items now calculated dynamically in getDashboardStats
- [x] Fix: Status calculated from next service date (overdue if date < now)
- [x] Fix: Type field deselection bug fixed with proper value binding
- [x] Fix: Applied exact Dredge Robotics colors (#1a2a3a navy, #e63946 red, #00ff00 green)


## Current Sprint: Mobile QR Scanner & Color Refinement
- [x] Refine theme colors to match Dredge Robotics visual (exact navy #0f1e2e, red #e63946)
- [x] Build mobile QR scanner page with live camera access
- [x] Implement QR code detection (jsQR library) and item lookup
- [x] Create service completion form with timestamp and notes
- [x] Add photo capture for service documentation
- [x] Add QR Scanner to sidebar navigation
- [x] Write Vitest for scanner logic and service logging (3 tests, all passing)


## Service Photo Persistence Feature
- [x] Create service_logs table with photo URL and metadata
- [x] Update logService procedure to upload photos to S3 and create service log records
- [x] Update QRScanner to pass photo data to logService
- [x] Create ServiceHistory view component with photo gallery and modal preview
- [x] Display service history on item detail pages
- [x] Write Vitest for service log creation and photo handling (6 scanner tests, all passing)


## Sprint: Search Fix + 3 Major Features [COMPLETE]
- [x] Diagnose root cause: search OR clause missing assigned column; status filter compared stored vs computed status
- [x] Fix search to filter by item name, item code, serial number, type, and assigned (case-insensitive)
- [x] Fix status filter to compute overdue/due dynamically from nextServiceDate
- [x] Fix getOverdueItems to exclude retired/quarantine items
- [x] Fix race-safe item code generation with retry-on-duplicate-key
- [x] Build "Bulk Print QR Codes" page with size presets and B&W print
- [x] Add "Bulk Print" button to Register page header
- [x] Add Inspection History Log page with filter controls (item, date range)
- [x] Add Excel export for inspection history with applied filters
- [x] Build Bulk CSV Import page with template download, preview, validation, error reporting
- [x] Add "Bulk Import" button to Register page header
- [x] Add Inspection History to sidebar navigation
- [x] Add Vitest coverage: 8 new tests for bulkCreate, inspectionHistory, exportInspectionHistory, search regression, status regression
- [x] All 35 tests passing, 0 TypeScript errors


## Sprint: Dashboard Filter Fix + Inspection Flow [COMPLETE]
- [x] Fix: Dashboard "Overdue" stat card now links to /register?status=overdue
- [x] Fix: Dashboard "Due within 30 days" stat card now links to /register?status=due
- [x] Fix: "View all" links in alert lists pass the correct status query param
- [x] Register page reads ?status= from URL and applies the filter on mount
- [x] Add Inspect action button on each Register row (ClipboardCheck icon)
- [x] Add Inspect action button on the QR Scanner result panel
- [x] Build InspectionDialog component: result (Pass/Fail/Action Required), inspector name, inspection date, next service date, notes, optional photo capture
- [x] Schema: extend service_logs with kind, result, inspector columns (migration 0004)
- [x] Backend: recordInspection procedure persists log with kind="inspection" and updates item status (pass→active, fail→quarantine, action_required→due)
- [x] Show inspections (with kind/result badges and photo) in Service & Inspection History timeline
- [x] Vitest coverage: 3 new tests for recordInspection (creates log, sets quarantine on fail, rejects bad photo) — all 53 tests passing


## Active Bug
- [x] Register "Overdue" status filter still shows items with Active status — fixed via server-side effective-status computation + 4 regression tests
- [x] Bug: Dashboard status distribution chart tooltip is too dark — fixed with solid navy background + white text + red border for readability
- [x] Bug: "Due for Service" filter on Register page is still buggy — unified by pointing dashboard card to ?status=due (same as Overdue), removing the legacy due30 date-range hack

## Sprint: Mobile Inspection UX
- [x] InspectionDialog: auto-populate inspector field from logged-in user's profile (name) and make it read-only — no manual override
- [x] InspectionDialog: default next service date to today + 3 months
- [x] PublicItemDetail (QR landing page): add a clear "Perform Inspection" button; OAuth callback now honours returnPath so visitors land back on /public/item/:id after signing in
- [x] ItemDetail (authenticated): add a top-level "Inspect" button that opens the InspectionDialog
- [x] Backend: server-side enforce inspector matches authenticated user's name (ignore any client-sent inspector value, derive from ctx.user)
- [x] Tests: 2 new regressions added — all 63 tests passing

## Sprint: Certified Inspector role
- [x] Schema: certifiedInspector enum('yes','no') column added (migration 0005), owner auto-bootstrapped to admin+certified
- [x] Backend: auth.me already returns full user row — includes certifiedInspector and role
- [x] Backend: recordInspection throws FORBIDDEN unless admin or certifiedInspector='yes'
- [x] Backend: admin-only users.list, users.setCertifiedInspector, users.setRole (with self-protection)
- [x] Frontend: Inspect buttons disabled on PublicItemDetail and ItemDetail with tooltip when not certified
- [x] Frontend: AdminUsers page at /admin/users with certify toggle + promote-to-admin link; sidebar shows Users entry only for admins
- [x] Tests: 6 new regressions added — all 69 tests passing

## Sprint: Dashboard Recent Inspections card + 5x5mm QR hardening
- [x] Backend: getDashboardStats now returns inspectionsLast30Days (filtered to kind='inspection')
- [x] Frontend: 5th stat card 'Inspections (30d)' deep-links to /inspection-history?from=...&to=...
- [x] InspectionHistory page reads ?from / ?to URL params and pre-populates dateFrom/dateTo filters
- [x] QR hardening: client-side /q/:id redirect route added (registered in App.tsx, no server hop needed)
- [x] QRViewer + BulkPrintQR: small preset encodes /q/:id, renders inline SVG (vector), uses ECC=M for smallest matrix
- [x] Amber scannability warning shown beneath BulkPrint Small preset asking user to test-print before mass producing
- [x] Tests: 8 new regressions added — 77/77 passing

## Sprint: Type Management + Rename to Inspection Register
- [x] Rename app title from "Rigging Register" to "Inspection Register" across all pages
- [x] Rename all "Rigging Item" → "Inspection Item" in forms, dialogs, and labels
- [x] Rename RIGGING_TYPES → INSPECTION_TYPES constant; generateRiggingCode → generateInspectionCode
- [x] Update AdminTypes page title and descriptions to use "Inspection Types" terminology
- [x] Add canManageTypes enum column to users schema (migration 0006)
- [x] Backend: add users.setCanManageTypes admin procedure
- [x] Backend: add types.list, types.create, types.delete procedures (gated by canManageTypes)
- [x] Frontend: build AdminTypes management page with CRUD UI and permission gating
- [x] Frontend: add sidebar nav entry "Types" (admin-only, visible only if canManageTypes=yes)
- [x] Frontend: AdminUsers page now shows canManageTypes toggle for each user
- [x] Tests: all 77 tests passing (no new failures from terminology changes)
- [x] Bug fix: ItemFormDialog now fetches types from server (types.list) instead of hardcoded constant, so Add Item dropdown matches Types management page
- [x] Bug: Types management is non-functional — created inspection_types DB table (migration 0007), seeded 17 default types, wired real CRUD
- [x] Types.create persists to DB (inspection_types table)
- [x] Types.delete removes from DB
- [x] Types.list reads from inspection_types table; ItemFormDialog fetches from same source

## Sprint: Access Approval + Type Hierarchy
- [x] Schema: add `approved` enum column to users (default 'no'); owner auto-approved
- [x] Schema: replace flat inspection_types with `main_types` (id, name, code) and `sub_types` (id, mainTypeId, name, code)
- [x] Backend: approvedProcedure guard blocks unapproved users from all protected procedures
- [x] Backend: admin approve/revoke user access procedures (users.setApproved)
- [x] Backend: main_types and sub_types CRUD (listMainTypes, listSubTypes, createMainType, deleteMainType, createSubType, deleteSubType)
- [x] Frontend: "Pending Approval" screen for unapproved users after login
- [x] Frontend: admin Users page — Approved toggle added
- [x] Frontend: AdminTypes page redesigned with hierarchical main type → sub type management
- [x] Frontend: ItemFormDialog updated with cascading Main Type → Sub Type dropdowns
- [x] Item code generation: compose as MainCode-SubCode-sequence (e.g. RIG-CS-0001)
- [x] Seeded 4 main types (Rigging, Lifting, Safety, Mooring) with 17 sub types
- [x] All remaining user-visible 'rigging' text replaced with 'inspection'
- [x] Tests: 77/77 passing after code format + terminology updates

## Sprint: Bulk Import/Export + Filters + WLL Removal
- [ ] Update CSV import template to include type and subType columns
- [ ] Update CSV parser to handle type+subType fields
- [ ] Update bulk export to include type and subType columns
- [ ] Add type and subtype filter dropdowns to Register page
- [ ] Remove WLL field from ItemFormDialog (add item form)
- [ ] Remove WLL column from Register table
- [ ] Clear all items from the database
