Files
CLProject/PROJECT_FILES_GUIDE.md
T
2026-04-21 23:26:13 +02:00

14 KiB

Project Files Guide

A junior-friendly walk-through of every folder and file that matters in this repository. Read it alongside README.md: the README tells you how to run the project, this guide tells you where things live once it is running.

How the application is organised

There are three parts:

  1. Backend — Node.js + Express in src/. Talks to MariaDB, serves the API under /api/v1/, and serves the static frontend files.
  2. Frontend — two single-page shells in public/: user.html for operators and admin.html for administrators. Both are ES-module based (no bundler) and use Bootstrap 5.
  3. Database — MariaDB. Schema and seed data are in sql/. Docker loads them automatically on a fresh volume.

End-to-end request flow (simplified)

  1. docker compose up starts three containers: app, db, phpmyadmin.
  2. src/server.js boots Express and connects to MariaDB.
  3. The browser loads /portal.html (chooser page).
  4. The user clicks a link and goes to /login-admin or /login-user.
  5. After login, /admin or /user is served — both require a valid auth_token cookie (see src/middleware/authMiddleware.js).
  6. The frontend shell loads either admin-app.js or user-app.js, which hands off to public/js/admin.js or public/js/user.js.
  7. The frontend calls /api/v1/admin/all to bulk-load every entity needed for rendering, and keeps working drafts in IndexedDB.

Root files

package.json

Defines the Node project: scripts (start, dev, test:environment), dependencies (Express, MariaDB driver, cookie-parser, cors, dotenv), and the minimum Node version.

docker-compose.yml

Spins up app, db, and phpmyadmin containers with the right volumes and ports for local development.

.env.example / .env

.env.example documents the variables the backend expects. Copy it to .env and fill in real values; src/config/env.js loads them at startup and fails fast if a required one is missing.

.devcontainer/

VS Code Dev Containers definition so the editor opens directly inside the app container.

docker/mariadb/init/

Mount point for extra init scripts. sql/schema.sql and sql/seed.sql are placed here by Docker Compose so they run the first time the DB volume is created.

public/ — what the browser gets

HTML shells

  • public/portal.html — the neutral landing page at /. Two links: one to the user login, one to the admin login.
  • public/login-admin.html and public/login-user.html — login forms. They POST to /api/v1/auth/admin/login or /api/v1/auth/user/login and follow the JSON redirect on success.
  • public/admin.html — Bootstrap sidebar + main area for the admin console. Loads admin-app.js. The sidebar opens on the Reports panel by default; nav categories are ordered Reports → CheckLists → Sites → Users → Settings.
  • public/user.html — Bootstrap shell for the operator task workflow. Loads user-app.js. Contains a Sync button in the Assigned Tasks header that refreshes the task list from the server without a full page reload.

Top-level scripts

  • public/admin-app.js — opens the shared IndexedDB (check-list-poc-db), reads the cached image rules, then calls initAdmin() from public/js/admin.js.
  • public/user-app.js — opens the shared IndexedDB (check-list-poc-db) and calls initUser() from public/js/user.js. user.js additionally opens a second database (user-portal-db) for per-task record data and images.

Static assets

  • public/styles.css — custom styles layered on top of Bootstrap 5. Includes .admin-table (full-width, striped header, hover rows), .admin-table-compact (denser column padding for wide entity tables), and .admin-table-actions (shrink-wraps the actions column so data columns take all remaining space).
  • public/icon.svg — PWA icon referenced by public/manifest.webmanifest.

public/js/ — frontend modules

Each file has a single responsibility and imports only what it needs.

  • public/js/constants.js — store names, API base path, timings.
  • public/js/state.js — tiny shared object holding the current IndexedDB handle. Kept deliberately small; most feature-specific state lives inside admin.js or user.js.
  • public/js/api.jsfetchJson(path, options) wrapper that prepends the versioned base path and turns { message } error bodies into thrown errors.
  • public/js/db.js — opens and wraps check-list-poc-db (the shared IndexedDB used by both admin and user consoles) with generic CRUD helpers: get, put, delete, transaction.
  • public/js/user-db.js — opens and wraps user-portal-db (a second, separate IndexedDB used only by the user console). Stores per-task record answers, visit dates, and image dataUrl blobs keyed by numeric task ID.
  • public/js/validation.js — pure validators for reports and image-rule forms. No DOM or state dependencies, so the same logic can be reused server-side.
  • public/js/images.js — image optimisation entry point. Detects Web Worker + OffscreenCanvas support and falls back to main-thread canvas when not available. Preserves the EXIF block so the backend gets the same metadata the user saw.
  • public/js/image-worker.js — the worker implementation used by images.js.
  • public/js/exif.js — lightweight JPEG EXIF parser (IFD0 + GPS tags) used by both the user flow and the admin lightbox.
  • public/js/admin.js — the admin console controller. Navigation, render functions, and CRUD handlers for every admin category. The Users table includes a Tasks column with a badge showing how many tasks are assigned to each user (blue if > 0, grey if 0).
  • public/js/user.js — the operator workflow controller. Key responsibilities:
    • loadFromServer() — fetches /api/v1/admin/all; on 401 (stale cookie after a server restart) it redirects to /login-user; on any other failure it falls back to the IndexedDB cache.
    • filterTasksByUser() — keeps only tasks where task.userId matches the ?userId= URL parameter.
    • showDetailView(id) — chains maybeHydrateFromServer() (seeds IndexedDB from the server if the task has no local data) → maybeDownloadImages() (fetches image blobs from the server if they were previously uploaded) → renderTaskDetail().
    • forceSyncWithServer() — called by the Sync button; re-fetches live data without a page reload.
    • Record editing, image attachment, save-as-draft, and submit-as-final with image optimisation and validation.

src/ — backend

src/server.js

Boot file. Imports the Express app, confirms the DB connection, starts listening, and wires up SIGINT / SIGTERM for a clean shutdown.

src/app.js

Express wiring. Middleware stack in mount order:

  1. cors() — wide-open CORS for PoC use
  2. cookieParser() — parses the auth_token cookie
  3. express.json({ limit: '50mb' }) — accepts large base64 image payloads
  4. noCacheHtml — sets Cache-Control: no-cache on every HTML response so browsers revalidate page content after a Docker restart instead of serving a stale cached copy
  5. API routes under /api/v1/
  6. HTML page routes (/, /login-admin, /login-user, /admin, /user)
  7. express.static(public/) with setHeaders applying no-cache for .html files; JS/CSS use default ETag revalidation
  8. 404 + global error handlers

requireAnyAuth is applied to /api/v1/admin/* and /api/v1/reports/*; requireUserAuth / requireAdminAuth gate the HTML workspaces.

src/config/

  • src/config/env.js — loads .env via dotenv, checks required keys, exposes a normalised env object.

src/db/

  • src/db/pool.js — creates the shared MariaDB pool and exposes query() / closePool().

src/middleware/

  • src/middleware/authMiddleware.jsrequireAdminAuth, requireUserAuth, requireAnyAuth. For API callers (detected via req.originalUrl / Accept) an unauthenticated response returns 401 JSON; browser navigation is redirected to the relevant login page.
  • src/middleware/errorHandler.jsnotFoundHandler and global errorHandler that convert everything to a consistent JSON shape.
  • src/middleware/validateParams.js — regex / numeric URL-parameter guards used by route definitions.

src/routes/

File Prefix Notes
healthRoutes.js /api/v1/health Liveness + DB ping.
authRoutes.js /api/v1/auth Admin/user login, logout, me. Issues the auth_token cookie.
adminRoutes.js /api/v1/admin CRUD for every admin entity and /all bulk load. Gated by requireAnyAuth.
reportRoutes.js /api/v1/reports Submit/get/list/delete reports and their images. Gated by requireAnyAuth.
configRoutes.js /api/v1/config Image-rules read/write (audit-logged) and export profile.
lookupRoutes.js /api/v1/lookups Reference lookup sets and values.
templateRoutes.js /api/v1/templates Legacy template catalogue (kept for the seeded sample + smoke test).

src/services/

Thin layer between routes and SQL. Each file owns a domain.

  • adminService.js — everything under admin_* tables, plus the bulk loadAllAdminData() used by both the admin and user consoles.
  • auditService.js — writes to audit_log whenever something sensitive changes (report submit/delete, image rules update, template publish).
  • authService.js — credential verification and an in-memory session Map with 24-hour expiry. Plain-text password comparison — PoC only.
  • cacheService.js — generic LRU + TTL factory, pre-configured templateCache, lookupCache, configCache.
  • configService.js — image rules and export profile queries. (Previous app_config helpers were removed along with the table.)
  • lookupService.jslookup_sets / lookup_values.
  • reportService.jsreports and report_images. Images are stored as LONGBLOB rows; list helpers group them by record_id.
  • templateService.js — template + template_versions queries and publish flow.

src/utils/

  • asyncHandler.js — wraps async route handlers so rejected promises reach the Express error middleware.
  • json.js — safely parses JSON columns returned by MariaDB.

sql/

sql/schema.sql

Defines every table the app touches:

  • Template catalogue: templates, template_versions.
  • Reference data: lookup_sets, lookup_values, image_rules, export_profiles.
  • Reports: reports (answers as JSON) and report_images (binary blobs).
  • Audit: audit_log.
  • Admin entities: admin_categories, admin_sub_categories, admin_severities, admin_statuses, admin_handled_by, admin_projects, admin_processes, admin_users, admin_sites, admin_cl_records, admin_cl_templates, admin_cl_template_records (join), admin_tasks.
  • Credentials: admin_credentials.

sql/seed.sql

Inserts enough data for the frontend to boot: the sample incoming-inspection template, pass-fail / draft-status lookups, the default image-rules row, the default export profile, and seed admin/user credentials.

scripts/

scripts/test-environment.js

Connectivity smoke test — hits /api/v1/health, /api/v1/templates, the DB directly, and phpMyAdmin. Useful after docker compose up and after any infrastructure change.

  1. README.md
  2. docker-compose.yml
  3. sql/schema.sql
  4. src/server.jssrc/app.js
  5. src/middleware/authMiddleware.js
  6. src/routes/adminRoutes.js and src/services/adminService.js
  7. public/admin-app.jspublic/js/admin.js
  8. public/user-app.jspublic/js/user.js

Quick "where do I look" rule