676 lines
20 KiB
Markdown
676 lines
20 KiB
Markdown
# Project Files Guide
|
|
|
|
This document explains the role of the main files in this project in a way that should be easy to follow for a junior developer.
|
|
|
|
The project is split into a few clear parts:
|
|
- server code in [src/app.js](src/app.js) and the rest of [src](src)
|
|
- browser frontend files in [public](public)
|
|
- database structure and example data in [sql](sql)
|
|
- environment and local development helpers in the root folder and [scripts](scripts)
|
|
|
|
## How The Application Works At A High Level
|
|
|
|
The project has two big sides:
|
|
- the backend, which provides templates, lookups, configuration, report storage, and audit logging through REST API endpoints
|
|
- the frontend, which runs in the browser, stores drafts locally, and uses the backend for centrally managed configuration and report submission
|
|
|
|
In simple terms:
|
|
1. Express starts the server.
|
|
2. The server exposes API endpoints under `/api/v1/...`.
|
|
3. The server also serves the frontend files from the [public](public) folder.
|
|
4. The browser loads the frontend entry point [public/app.js](public/app.js) which imports modules from [public/js/](public/js).
|
|
5. The frontend downloads templates and config from the API using a single batch request.
|
|
6. The frontend stores reports and images locally in IndexedDB.
|
|
7. Reports can be submitted to the server via `POST /api/v1/reports`.
|
|
|
|
## Root Files
|
|
|
|
### [package.json](package.json)
|
|
|
|
Role:
|
|
Defines the Node.js project itself.
|
|
|
|
What it contains:
|
|
- project name and version
|
|
- npm scripts such as `start`, `dev`, and `test:environment`
|
|
- dependency list such as `express`, `mariadb`, and `dotenv`
|
|
|
|
Why it matters:
|
|
When you run `npm install` or `npm start`, Node uses this file to know how the project should behave.
|
|
|
|
### [README.md](README.md)
|
|
|
|
Role:
|
|
Main entry document for developers.
|
|
|
|
What it contains:
|
|
- project purpose
|
|
- setup steps
|
|
- available endpoints
|
|
- development notes
|
|
|
|
Why it matters:
|
|
This is the first file a new developer should read before touching the code.
|
|
|
|
### [docker-compose.yml](docker-compose.yml)
|
|
|
|
Role:
|
|
Starts the full local development environment.
|
|
|
|
What it contains:
|
|
- the application container
|
|
- the MariaDB container
|
|
- the phpMyAdmin container
|
|
- port mappings and volume configuration
|
|
|
|
Why it matters:
|
|
Instead of installing and configuring everything manually, you can start the full stack with one command.
|
|
|
|
### [.env.example](.env.example)
|
|
|
|
Role:
|
|
Example environment configuration.
|
|
|
|
What it contains:
|
|
- default port values
|
|
- database host, name, user, and password placeholders
|
|
|
|
Why it matters:
|
|
It shows which environment variables the application expects.
|
|
|
|
### [.env](.env)
|
|
|
|
Role:
|
|
Real environment file used on the current machine.
|
|
|
|
What it contains:
|
|
- actual local values for ports and database credentials
|
|
|
|
Why it matters:
|
|
The backend reads this file during startup through `dotenv`.
|
|
|
|
## Public Folder
|
|
|
|
The [public](public) folder contains files that are sent directly to the browser.
|
|
|
|
### [public/user.html](public/user.html)
|
|
|
|
Role:
|
|
Operator workspace HTML shell.
|
|
|
|
What it contains:
|
|
- shared sidebar with template selector, sync button, report list, and search/filter
|
|
- report editor main area with hero, summary cards, form, inspector panel
|
|
- report list item `<template>` for runtime rendering
|
|
|
|
When you edit it:
|
|
- when you need to change the report editing layout
|
|
- when adding new user-facing controls or sections
|
|
|
|
### [public/admin.html](public/admin.html)
|
|
|
|
Role:
|
|
Administrator workspace HTML shell.
|
|
|
|
What it contains:
|
|
- simplified sidebar with template selector and sync button (no report list)
|
|
- admin main area with image policy editor form and admin summary panel
|
|
|
|
When you edit it:
|
|
- when adding new admin configuration panels
|
|
- when changing the image policy form fields
|
|
|
|
### [public/index.html](public/index.html)
|
|
|
|
Role:
|
|
Legacy combined app shell (no longer served by routes).
|
|
|
|
Note:
|
|
This file has been superseded by [user.html](public/user.html) and [admin.html](public/admin.html).
|
|
It remains in the repository for reference but is not routed to by the Express server.
|
|
|
|
### [public/portal.html](public/portal.html)
|
|
|
|
Role:
|
|
Simple chooser page that lets the user open either the user area or the admin area.
|
|
|
|
What it contains:
|
|
- a short explanation of the two entry points
|
|
- a link to `/user`
|
|
- a link to `/admin`
|
|
|
|
What it does:
|
|
It is the landing page served at `/`. It does not contain complex logic. Its job is only to separate the entry points.
|
|
|
|
### [public/app.js](public/app.js)
|
|
|
|
Role:
|
|
Thin orchestrator entry point for the frontend.
|
|
|
|
What it contains:
|
|
- imports from all ES modules under `public/js/`
|
|
- startup flow (`init()`, `cacheElements()`, `bindEvents()`)
|
|
- report CRUD operations (create, open, delete, submit)
|
|
- sync logic with the API using batch template fetch
|
|
- dirty-flag autosave loop
|
|
- admin image-policy save
|
|
- event delegation for the report list
|
|
- search/filter event wiring
|
|
- null guards for page-specific elements (user vs admin)
|
|
|
|
What changed:
|
|
This file was originally a monolithic ~1700-line file. It has been split into modules (A1)
|
|
and now acts as a controller. It is shared between user.html and admin.html — it detects
|
|
which DOM elements exist and only binds behavior for the current page.
|
|
|
|
### [public/styles.css](public/styles.css)
|
|
|
|
Role:
|
|
Main styling file for the frontend.
|
|
|
|
What it contains:
|
|
- color variables
|
|
- layout rules
|
|
- sidebar and panel styles
|
|
- form field styles
|
|
- admin and user page styles
|
|
- responsive behavior for smaller screens
|
|
|
|
What it does:
|
|
It controls how the application looks on desktop and mobile.
|
|
|
|
When you edit it:
|
|
- when spacing or sizing is wrong
|
|
- when a section needs a new visual style
|
|
- when mobile layout needs improvement
|
|
|
|
### [public/sw.js](public/sw.js)
|
|
|
|
Role:
|
|
Service worker for offline behavior.
|
|
|
|
What it contains:
|
|
- cache name
|
|
- app shell file list (including all new JS modules)
|
|
- install, activate, and fetch event handlers
|
|
- LRU cache trimming for dynamic entries (P5)
|
|
|
|
What it does:
|
|
It tells the browser how to cache frontend files and API responses.
|
|
|
|
Important behavior:
|
|
- static files use cache-first strategy
|
|
- API calls use network-first strategy
|
|
- dynamic cache is bounded to prevent unbounded storage growth
|
|
|
|
### [public/icon.svg](public/icon.svg)
|
|
|
|
Role:
|
|
SVG icon used by the PWA manifest (F5).
|
|
|
|
### Frontend ES Modules (public/js/)
|
|
|
|
These modules were extracted from the original monolithic `app.js` (A1).
|
|
All render functions include null guards so the shared `app.js` can safely run on
|
|
both user.html (operator workspace) and admin.html (administrator workspace).
|
|
|
|
### [public/js/constants.js](public/js/constants.js)
|
|
|
|
Role:
|
|
Shared constants used across frontend modules.
|
|
|
|
What it contains:
|
|
- IndexedDB name, version, and store names
|
|
- API base path (`/api/v1`)
|
|
- autosave interval, render debounce timing, cache limits
|
|
|
|
### [public/js/state.js](public/js/state.js)
|
|
|
|
Role:
|
|
Centralized state management for the frontend.
|
|
|
|
What it contains:
|
|
- `state` object with all application state (including dirty flag, search query, filter)
|
|
- `elements` object for cached DOM references
|
|
- `getCurrentReport()` and `getTemplateRecord()` helpers
|
|
- `stateHelpers` bundle used by other modules to avoid circular imports
|
|
|
|
### [public/js/i18n.js](public/js/i18n.js)
|
|
|
|
Role:
|
|
Internationalization locale extraction (F7).
|
|
|
|
What it contains:
|
|
- English locale with ~80 UI string keys
|
|
- `t(key, ...params)` translation function with placeholder replacement
|
|
- `setLocale()` for future language support
|
|
|
|
### [public/js/utils.js](public/js/utils.js)
|
|
|
|
Role:
|
|
Pure utility and formatting functions.
|
|
|
|
What it contains:
|
|
- `prettifyStatus()`, `formatDateTime()`, `formatTime()`, `formatRelativeTime()`, `formatFileSize()`
|
|
- `sanitizeForFilename()`, `generateReportNumber()`, `buildGeneratedFilename()`
|
|
- `makeTemplateKey()`, `deriveTemplateCatalog()`
|
|
- `debounce()` helper for rate-limiting function calls (P2)
|
|
|
|
### [public/js/db.js](public/js/db.js)
|
|
|
|
Role:
|
|
IndexedDB operations with multi-store transaction support.
|
|
|
|
What it contains:
|
|
- `openDatabase()` with schema version 2
|
|
- CRUD helpers: `dbGetAll()`, `dbGet()`, `dbPut()`, `dbDelete()`, `dbGetAllByIndex()`
|
|
- `dbTransaction()` for atomic multi-store operations (A5)
|
|
- `saveSetting()` and `loadSetting()` for UI preferences
|
|
|
|
### [public/js/api.js](public/js/api.js)
|
|
|
|
Role:
|
|
API communication layer with versioned base path (A3).
|
|
|
|
What it contains:
|
|
- `fetchJson(path, options)` that prepends the API base path automatically
|
|
- `registerServiceWorker()`
|
|
|
|
### [public/js/validation.js](public/js/validation.js)
|
|
|
|
Role:
|
|
Shared validation logic for reports and admin forms (A7).
|
|
|
|
What it contains:
|
|
- `validateReport()` — checks required fields, number ranges, attachment counts
|
|
- `validateImageRulesPayload()` — validates image policy form submissions
|
|
- `evaluateRequiredWhen()` — conditional field requirement logic
|
|
- `isBlankValue()` — blank check by field type
|
|
|
|
### [public/js/images.js](public/js/images.js)
|
|
|
|
Role:
|
|
Image optimization with Web Worker support (P1).
|
|
|
|
What it contains:
|
|
- `optimizeImage(file, imageRules)` — automatically detects Web Worker support
|
|
- Worker path: delegates to `image-worker.js` via `OffscreenCanvas`
|
|
- Falls back to main-thread canvas when OffscreenCanvas is unavailable
|
|
|
|
### [public/js/image-worker.js](public/js/image-worker.js)
|
|
|
|
Role:
|
|
Web Worker for background image processing (P1).
|
|
|
|
What it contains:
|
|
- `self.onmessage` handler using `createImageBitmap` and `OffscreenCanvas`
|
|
- Sends optimized blob back to main thread with matching message ID
|
|
|
|
### [public/js/forms.js](public/js/forms.js)
|
|
|
|
Role:
|
|
Dynamic form field creation from template JSON.
|
|
|
|
What it contains:
|
|
- `createFieldNode(field, report, callbacks)` — renders fields with callback pattern
|
|
- `createAttachmentFieldNode()` with IntersectionObserver for lazy-loading thumbnails (P3)
|
|
- `escapeHtml()` for XSS prevention
|
|
|
|
### [public/js/renderer.js](public/js/renderer.js)
|
|
|
|
Role:
|
|
All DOM render functions with search and filter support (F4).
|
|
|
|
What it contains:
|
|
- `render()` orchestrator — conditionally calls user or admin renders
|
|
- `renderReportList()` — filters by search query and status
|
|
- `renderCurrentReport(fieldCallbacks)` — accepts callbacks for field changes
|
|
- `renderTemplateSelector()`, `renderTemplateSummary()`
|
|
- `renderSyncSummary()`, `renderImagePolicy()`, `renderAdminImageRules()`
|
|
- `updateConnectionBadge()`, `updateSaveBadge()`
|
|
- Uses `t()` for all user-visible strings
|
|
- Null guards on all page-specific functions for safe user/admin coexistence
|
|
|
|
### [public/js/export.js](public/js/export.js)
|
|
|
|
Role:
|
|
Report data export functionality (F2).
|
|
|
|
What it contains:
|
|
- `exportReportCSV()` — generates CSV from template fields and report answers
|
|
- `exportReportAttachments()` — triggers download for each attachment blob
|
|
- `csvEscape()` and `downloadBlob()` helper functions
|
|
|
|
### [public/manifest.webmanifest](public/manifest.webmanifest)
|
|
|
|
Role:
|
|
Basic PWA metadata file.
|
|
|
|
What it contains:
|
|
- app name
|
|
- short name
|
|
- theme color
|
|
- start URL
|
|
|
|
What it does:
|
|
Helps the browser treat the app more like an installable web application.
|
|
|
|
## Source Folder
|
|
|
|
The [src](src) folder contains backend code.
|
|
|
|
### [src/server.js](src/server.js)
|
|
|
|
Role:
|
|
Real server startup file.
|
|
|
|
What it contains:
|
|
- startup function
|
|
- database connection check
|
|
- Express app startup
|
|
- graceful shutdown logic
|
|
|
|
What it does:
|
|
This is the file Node runs when the backend starts.
|
|
|
|
Simple mental model:
|
|
- load the Express app
|
|
- make sure MariaDB is reachable
|
|
- start listening on a port
|
|
- close cleanly when the process is stopped
|
|
|
|
### [src/app.js](src/app.js)
|
|
|
|
Role:
|
|
Express application configuration file.
|
|
|
|
What it contains:
|
|
- middleware registration
|
|
- API v1 route registration under `/api/v1/` prefix (A3)
|
|
- static file serving
|
|
- frontend entry page routes
|
|
- global error handling
|
|
|
|
Important routes:
|
|
- `/api/v1/...` for versioned backend endpoints
|
|
- `/` for the chooser page
|
|
- `/user` and `/admin` for the frontend app shell
|
|
|
|
## Source Subfolders
|
|
|
|
### [src/config/env.js](src/config/env.js)
|
|
|
|
Role:
|
|
Loads and validates environment variables.
|
|
|
|
What it contains:
|
|
- `dotenv` setup
|
|
- required environment key checks
|
|
- normalized `env` object export
|
|
|
|
What it does:
|
|
It reads raw values from `.env` and converts them into a safer object the rest of the code can use.
|
|
|
|
Why this is useful:
|
|
Instead of reading `process.env` everywhere, the app reads from one clean place.
|
|
|
|
### [src/db/pool.js](src/db/pool.js)
|
|
|
|
Role:
|
|
Creates and manages the MariaDB connection pool.
|
|
|
|
What it contains:
|
|
- one shared database pool
|
|
- `query()` helper
|
|
- `closePool()` helper
|
|
|
|
What it does:
|
|
It gives the service layer a standard way to run SQL queries.
|
|
|
|
Why it matters:
|
|
Without this file, each route or service would have to manage its own connections, which would be messy and error-prone.
|
|
|
|
### [src/middleware/errorHandler.js](src/middleware/errorHandler.js)
|
|
|
|
Role:
|
|
Handles not-found routes and server errors.
|
|
|
|
What it contains:
|
|
- `notFoundHandler`
|
|
- `errorHandler`
|
|
|
|
What it does:
|
|
When a route does not exist, or when code throws an error, this file creates a JSON response instead of letting the app fail in an uncontrolled way.
|
|
|
|
### [src/middleware/validateParams.js](src/middleware/validateParams.js)
|
|
|
|
Role:
|
|
URL parameter validation middleware (A7).
|
|
|
|
What it contains:
|
|
- `validateParam(name)` — checks route params against safe patterns (code or UUID)
|
|
- `validateNumericParam(name)` — validates numeric route parameters
|
|
|
|
What it does:
|
|
It rejects malformed URL parameters at the middleware level before they reach route handlers.
|
|
|
|
### [src/routes/healthRoutes.js](src/routes/healthRoutes.js)
|
|
|
|
Role:
|
|
Defines the health-check endpoint.
|
|
|
|
What it contains:
|
|
- `GET /api/health`
|
|
|
|
What it does:
|
|
Checks whether the server and database are working.
|
|
|
|
Why it matters:
|
|
This endpoint is used by tests and is also useful when debugging container problems.
|
|
|
|
### [src/routes/templateRoutes.js](src/routes/templateRoutes.js)
|
|
|
|
Role:
|
|
Defines template-related API endpoints.
|
|
|
|
What it contains:
|
|
- list endpoint for active templates
|
|
- batch endpoint with `?include=definitions` for single-request sync (A2)
|
|
- endpoint for one active template
|
|
- endpoint for a specific template version
|
|
- version listing for a template (F3)
|
|
- version publishing endpoint (F3)
|
|
- parameter validation middleware
|
|
- LRU cache integration (P4)
|
|
|
|
### [src/routes/lookupRoutes.js](src/routes/lookupRoutes.js)
|
|
|
|
Role:
|
|
Defines lookup-related API endpoints.
|
|
|
|
What it contains:
|
|
- list endpoint for lookup sets
|
|
- endpoint for one lookup set
|
|
- parameter validation and LRU cache integration
|
|
|
|
### [src/routes/configRoutes.js](src/routes/configRoutes.js)
|
|
|
|
Role:
|
|
Defines configuration-related API endpoints.
|
|
|
|
What it contains:
|
|
- image rule read and update endpoints
|
|
- export profile endpoint
|
|
- general app config endpoint
|
|
- LRU cache read-through and invalidation (P4)
|
|
- audit trail logging on image rules update (F6)
|
|
|
|
### [src/routes/reportRoutes.js](src/routes/reportRoutes.js)
|
|
|
|
Role:
|
|
Defines report submission API endpoints (F1).
|
|
|
|
What it contains:
|
|
- `GET /` — list submitted reports with filters (status, templateCode, limit, offset)
|
|
- `GET /:reportId` — single report by UUID
|
|
- `POST /` — submit or update a report (UPSERT by UUID, audit-logged)
|
|
|
|
### [src/services/templateService.js](src/services/templateService.js)
|
|
|
|
Role:
|
|
Handles template-related database queries.
|
|
|
|
What it contains:
|
|
- SQL for active template list
|
|
- `getAllActiveTemplates()` — batch query returning all templates with definitions (A2)
|
|
- `listTemplateVersions()` — all versions of a given template (F3)
|
|
- `publishTemplateVersion()` — retire current active, activate specified version (F3)
|
|
- template row mapping logic
|
|
|
|
### [src/services/lookupService.js](src/services/lookupService.js)
|
|
|
|
Role:
|
|
Handles lookup-related database queries.
|
|
|
|
### [src/services/configService.js](src/services/configService.js)
|
|
|
|
Role:
|
|
Handles configuration-related database queries.
|
|
|
|
### [src/services/reportService.js](src/services/reportService.js)
|
|
|
|
Role:
|
|
Handles report submission and retrieval (F1).
|
|
|
|
What it contains:
|
|
- `submitReport(report)` — UPSERT by report UUID
|
|
- `getReport(uuid)` — fetch single report
|
|
- `listReports({ status, templateCode, limit, offset })` — filtered listing
|
|
|
|
### [src/services/auditService.js](src/services/auditService.js)
|
|
|
|
Role:
|
|
Audit trail logging for admin mutations (F6).
|
|
|
|
What it contains:
|
|
- `logAuditEvent({ entityType, entityCode, action, oldValue, newValue })` — writes to audit_log table
|
|
- `getAuditLog()` — reads audit entries with optional filters
|
|
|
|
### [src/services/cacheService.js](src/services/cacheService.js)
|
|
|
|
Role:
|
|
In-memory LRU cache with TTL for server-side data (P4).
|
|
|
|
What it contains:
|
|
- `createCache({ maxEntries, ttlMs })` factory function
|
|
- Pre-configured singletons: `templateCache`, `lookupCache`, `configCache`
|
|
- Each cache instance has `get()`, `set()`, `delete()`, and `clear()` methods
|
|
|
|
### [src/utils/asyncHandler.js](src/utils/asyncHandler.js)
|
|
|
|
Role:
|
|
Small helper for async Express routes.
|
|
|
|
What it contains:
|
|
- `asyncHandler()` wrapper
|
|
|
|
What it does:
|
|
It catches rejected async route errors and forwards them to Express error middleware.
|
|
|
|
Why it matters:
|
|
Without it, every async route would need repetitive `try/catch` blocks.
|
|
|
|
### [src/utils/json.js](src/utils/json.js)
|
|
|
|
Role:
|
|
Small helper for parsing JSON values coming from MariaDB.
|
|
|
|
What it contains:
|
|
- `parseJsonColumn()`
|
|
|
|
What it does:
|
|
It safely converts JSON strings into objects and arrays.
|
|
|
|
Why it matters:
|
|
Several database columns store JSON text, and this helper prevents the same parsing logic from being repeated in multiple files.
|
|
|
|
## SQL Folder
|
|
|
|
### [sql/schema.sql](sql/schema.sql)
|
|
|
|
Role:
|
|
Creates the database structure.
|
|
|
|
What it contains:
|
|
- database creation
|
|
- table definitions
|
|
- keys and foreign keys
|
|
|
|
What it does:
|
|
It defines how templates, lookups, image rules, export profiles, and app config are stored.
|
|
|
|
### [sql/seed.sql](sql/seed.sql)
|
|
|
|
Role:
|
|
Inserts example data.
|
|
|
|
What it contains:
|
|
- one example checklist template
|
|
- lookup values
|
|
- one image policy
|
|
- one export profile
|
|
- app config values
|
|
|
|
What it does:
|
|
It gives the frontend and API something real to work with immediately after startup.
|
|
|
|
## Scripts Folder
|
|
|
|
### [scripts/test-environment.js](scripts/test-environment.js)
|
|
|
|
Role:
|
|
Simple smoke test for the local environment.
|
|
|
|
What it contains:
|
|
- API health checks
|
|
- template endpoint checks
|
|
- direct database checks
|
|
- phpMyAdmin checks
|
|
|
|
What it does:
|
|
It verifies that the main development services are working together.
|
|
|
|
When to use it:
|
|
- after starting Docker containers
|
|
- after changing infrastructure-related code
|
|
- after big refactors when you want a quick confidence check
|
|
|
|
## Recommended Reading Order For A Junior Developer
|
|
|
|
If you are new to this project, a good reading order is:
|
|
1. [README.md](README.md)
|
|
2. [PROJECT_FILES_GUIDE.md](PROJECT_FILES_GUIDE.md)
|
|
3. [src/server.js](src/server.js)
|
|
4. [src/app.js](src/app.js)
|
|
5. [src/routes/templateRoutes.js](src/routes/templateRoutes.js)
|
|
6. [src/services/templateService.js](src/services/templateService.js)
|
|
7. [public/js/constants.js](public/js/constants.js) and [public/js/state.js](public/js/state.js)
|
|
8. [public/app.js](public/app.js) — the thin orchestrator that wires everything together
|
|
9. [public/js/renderer.js](public/js/renderer.js) and [public/js/forms.js](public/js/forms.js)
|
|
7. [public/index.html](public/index.html)
|
|
8. [public/app.js](public/app.js)
|
|
9. [sql/schema.sql](sql/schema.sql)
|
|
10. [sql/seed.sql](sql/seed.sql)
|
|
|
|
That order helps because it moves from the high-level entry points into the deeper details.
|
|
|
|
## Practical Rule Of Thumb
|
|
|
|
When you are trying to change something, use this shortcut:
|
|
- if the browser layout looks wrong, check [public/index.html](public/index.html) and [public/styles.css](public/styles.css)
|
|
- if browser behavior is wrong, check [public/app.js](public/app.js)
|
|
- if an API endpoint is wrong, check [src/routes](src/routes) first and then [src/services](src/services)
|
|
- if database data is wrong, check [sql/schema.sql](sql/schema.sql), [sql/seed.sql](sql/seed.sql), and the service file that runs the query
|
|
- if the app does not start, check [src/server.js](src/server.js), [src/config/env.js](src/config/env.js), and [docker-compose.yml](docker-compose.yml)
|
|
|
|
This simple rule is often enough to help you find the right file quickly. |