9.1 KiB
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=definitionsfor 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
.
├── .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.
Run with Docker and Dev Containers
- Copy
.env.exampleto.envif you want custom local credentials. - In VS Code, run
Dev Containers: Reopen in Container. - 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:
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:
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 portalhttp://localhost:3000/useropens the user workspace directlyhttp://localhost:3000/adminopens 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 templatesGET /api/v1/templates?include=definitions— batch: all templates with definitions in one requestGET /api/v1/templates/:code— single active template with definitionGET /api/v1/templates/:code/versions— list all versions of a templatePUT /api/v1/templates/:code/versions/:versionNumber/publish— publish a specific template version
Lookups
GET /api/v1/lookups— list all lookup setsGET /api/v1/lookups/:code— single lookup set with values
Configuration
GET /api/v1/config/image-rules— active image policyPUT /api/v1/config/image-rules— update image policy (audit-logged)GET /api/v1/config/export— export profileGET /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 reportPOST /api/v1/reports— submit or update a report (UPSERT by UUID)
Example response
GET /api/v1/templates/incoming-inspection
{
"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": []
}
}