# Check List Proof of Concept This repository contains a proof-of-concept implementation for the Check List hybrid reporting solution described in the project documentation. ## What is included - Node.js REST API (v1) for template, configuration, report, and audit delivery - static frontend PoC served by Express, split into focused ES modules - MariaDB schema for configuration data, submitted reports, and audit trail - seed data with one sample inspection checklist template - lookup values, image policy, and export profile - Docker Compose and VS Code Dev Container setup for local development - service worker with bounded LRU cache for offline support ## Scope of this PoC Included: - all endpoints under versioned `/api/v1/` prefix - batch template endpoint with `?include=definitions` for single-request sync - template version listing and publishing management - lookup endpoints with parameter validation - image rule endpoint with server-side LRU cache and audit trail - export profile and generic application config endpoints - report submission endpoint (POST) with UPSERT - audit log recording for admin mutations - offline-capable frontend shell split into ES modules - IndexedDB-based local drafts with multi-store transactions - dynamic form rendering from template JSON - local attachment storage with Web Worker image optimization - report search and status filter - CSV export for report data - i18n locale extraction for UI strings - PWA manifest with SVG icon - debounced renders and dirty-flag autosave Not included: - authentication and authorization - file attachment upload to server (binary upload requires multer) - XLSX or ZIP generation (CSV is provided; advanced formats require library vendoring) - production-grade frontend bundling - automated test suite The PoC keeps template content inside a JSON column to reduce initial complexity and speed up delivery. This is deliberate for phase 1 proof-of-concept work. ## Project structure ```text . ├── .devcontainer/ ├── docker-compose.yml ├── package.json ├── public/ │ ├── admin.html ← administrator workspace │ ├── app.js ← thin orchestrator entry point │ ├── icon.svg ← PWA icon │ ├── index.html ← legacy combined shell (unused) │ ├── manifest.webmanifest │ ├── portal.html │ ├── styles.css │ ├── sw.js │ ├── user.html ← operator workspace │ └── js/ │ ├── api.js ← API communication (versioned base path) │ ├── constants.js ← shared constants (DB, API, limits) │ ├── db.js ← IndexedDB operations, multi-store tx │ ├── export.js ← CSV export and attachment download │ ├── forms.js ← dynamic form field creation │ ├── i18n.js ← English locale, t() translation │ ├── image-worker.js ← OffscreenCanvas Web Worker │ ├── images.js ← image optimization with worker fallback │ ├── renderer.js ← all render functions with search/filter │ ├── state.js ← centralized state management │ ├── utils.js ← utility functions │ └── validation.js ← shared validation (client-side) ├── scripts/ │ └── test-environment.js ├── sql/ │ ├── schema.sql │ └── seed.sql └── src/ ├── app.js ├── server.js ├── config/ │ └── env.js ├── db/ │ └── pool.js ├── middleware/ │ ├── errorHandler.js │ └── validateParams.js ← URL parameter validation ├── routes/ │ ├── configRoutes.js │ ├── healthRoutes.js │ ├── lookupRoutes.js │ ├── reportRoutes.js ← report submission endpoints │ └── templateRoutes.js ├── services/ │ ├── auditService.js ← audit trail logging │ ├── cacheService.js ← in-memory LRU cache with TTL │ ├── configService.js │ ├── lookupService.js │ ├── reportService.js ← report CRUD operations │ └── templateService.js └── utils/ ├── asyncHandler.js └── json.js ``` ## File guide For a junior-friendly explanation of what each main file does, see [PROJECT_FILES_GUIDE.md](PROJECT_FILES_GUIDE.md). ## Run with Docker and Dev Containers 1. Copy `.env.example` to `.env` if you want custom local credentials. 2. In VS Code, run `Dev Containers: Reopen in Container`. 3. Or start the stack directly with `docker compose up -d --build`. Services: - API: `http://localhost:3000` - phpMyAdmin: `http://localhost:8080` - MariaDB: `localhost:3306` The workspace is bind-mounted into the `app` container, so project files remain editable from VS Code. ## Database bootstrap On a fresh MariaDB volume, Docker loads `sql/schema.sql` and `sql/seed.sql` automatically. If you already have an older local database volume, either recreate it with `docker compose down -v` or import the SQL files manually: ```bash docker compose exec -T db sh -lc 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" < /docker-entrypoint-initdb.d/schema.sql && mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" < /docker-entrypoint-initdb.d/seed.sql' ``` ## Validate the environment Run the smoke test after the containers are up: ```bash npm run test:environment ``` The test verifies: - the API health endpoint at `/api/v1/health` - seeded template data via `/api/v1/templates` - direct MariaDB connectivity - phpMyAdmin availability ## Frontend PoC Open `http://localhost:3000` after the stack is running. Entry points: - `http://localhost:3000/` opens the chooser portal - `http://localhost:3000/user` opens the user workspace directly - `http://localhost:3000/admin` opens the administrator workspace directly The frontend demonstrates: - template sync from the API via batch endpoint - offline cache via IndexedDB and service worker (LRU-bounded) - local report creation, switching, search, and filtering - dynamic form rendering based on the seeded template - local attachment storage and preview with lazy-loading - Web Worker image optimization (OffscreenCanvas) with main-thread fallback - debounced re-renders and dirty-flag autosave - report submission to backend - CSV export for report data and individual attachment downloads - administrator mode for editing image requirements with audit trail - i18n-ready UI strings extracted to locale file This frontend is intentionally lightweight and framework-free so the proof of concept stays easy to inspect and adapt. The monolithic app.js has been split into focused ES modules under `public/js/`, and the UI is served as two separate HTML shells (`user.html` for operators, `admin.html` for administrators) sharing a single `app.js` orchestrator with null-guarded element access. ## Administrator mode Open `http://localhost:3000/admin` or use the chooser page at `http://localhost:3000/`. The current PoC administrator flow supports: - policy name changes - allowed MIME types - maximum file size - maximum width and height - JPEG quality - oversize behavior - maximum attachments per field The frontend saves these values to the backend through `PUT /api/v1/config/image-rules` and refreshes the local cache after save. All admin mutations are recorded in the audit log. ## API endpoints All endpoints are under the `/api/v1/` prefix. ### Service health `GET /api/v1/health` ### Templates - `GET /api/v1/templates` — list active templates - `GET /api/v1/templates?include=definitions` — batch: all templates with definitions in one request - `GET /api/v1/templates/:code` — single active template with definition - `GET /api/v1/templates/:code/versions` — list all versions of a template - `PUT /api/v1/templates/:code/versions/:versionNumber/publish` — publish a specific template version ### Lookups - `GET /api/v1/lookups` — list all lookup sets - `GET /api/v1/lookups/:code` — single lookup set with values ### Configuration - `GET /api/v1/config/image-rules` — active image policy - `PUT /api/v1/config/image-rules` — update image policy (audit-logged) - `GET /api/v1/config/export` — export profile - `GET /api/v1/config/app-config` — generic app configuration ### Reports - `GET /api/v1/reports` — list submitted reports (supports `?status=`, `?templateCode=`, `?limit=`, `?offset=`) - `GET /api/v1/reports/:reportId` — single submitted report - `POST /api/v1/reports` — submit or update a report (UPSERT by UUID) ## Example response `GET /api/v1/templates/incoming-inspection` ```json { "code": "incoming-inspection", "name": "Incoming Inspection Checklist", "description": "PoC template for supplier or incoming goods quality inspection.", "version": 1, "status": "active", "publishedAt": "2026-04-09T10:00:00.000Z", "definition": { "templateId": "incoming-inspection", "templateName": "Incoming Inspection Checklist", "version": 1, "sections": [] } } ```