← All projects

Prototype · Workflow · RBAC

DMS Document Management System

A working prototype of a scanning and approval system that became the reference for the production DMS.

HTML5CSS3JavaScript (ES modules)No framework, no build steplocalStorageSHA-256 (hand-written)Node.js test harnessesPython (HTTPS dev server)

A records-digitisation programme needed its scanning, quality-control and approval process agreed before development began. The usual route would have been a clickable mockup in Figma or Sketch. I built a working prototype instead, in plain HTML, CSS and JavaScript, from the business-rules spreadsheet and the workflow diagram, because a prototype that behaves like the real system can be explored far further than one that only looks like it. Every screen reads and writes the same application state, so a decision made by one role shows up for the next.

I presented it to the stakeholders and the team, and it landed well. Instead of clicking through fixed screens, they could sign in as any role, push a document through the whole workflow and try the edge cases themselves, so their feedback was specific because they had actually used it. We refined the prototype through that feedback until it was signed off as the final reference, and the production DMS was then built on it.

Each document moves through twelve stages (file intake, scanning, AI processing, QC review, final master, compression, supervisor, manager and department review, department approval and eGov submission), plus six exception and rework states. Every move goes through one guarded state machine. Each transition names the roles allowed to perform it and the rule that can block it, so there are no dead buttons: a disabled action always says why, in the business rule’s own terms.

Ten roles, from Super Admin down to Scanning Operator, including a read-only Auditor. Access is enforced in three independent layers: what a role may do, which data it may see (everything, its departments, or only its own files), and which file versions it may open. Screens are not just hidden: typing the URL of a page your role can’t use shows an access-denied page and writes an audit entry.

The Super Admin console manages admins and a three-level department hierarchy, edits a central permission matrix and custom roles, and shows activity reports with trends and drill-down by admin, department and manager. Admins can be scoped to one department tree, several, or the whole organisation, or granted specific cross-department rights.

Scanning follows the rules a real floor needs: a scan can’t start without an available scanner, paper sizes come from the selected device, unrecognised sizes are held for the operator, and captured pages survive a failed save. QC staff work through six quality parameters on a page grid, rescan individual pages, and hold files whose page count doesn’t match. Reviewers get a three-screen view (raw scan, final master and QC report side by side), and clicking an issue jumps both documents to that page.

The approval chain is strict. The Department’s approval pins the exact compressed file, and only the Manager can submit to eGov, and only that copy. Files sent back for rework carry their history. The audit trail is append-only, with no edit or delete path, and a permission change records its before and after.

It is honest about what is simulated. There is no back end, so scanner hardware, AI results, email and the eGov upload are simulated deterministically and labelled in the interface. The workflow, permissions, validation, audit, task queues with SLAs, search and reporting all use real application logic. No password exists in the code: accounts store SHA-256 digests, using a small hand-written implementation that runs the same in the browser and in tests.

Every business rule in the requirements spreadsheet is traced to the code that implements it and a step that shows it working. Four headless Node harnesses, with no dependencies, run against the same modules the browser loads: 640 business-rule assertions, 414 screen renders, and 941 route renders covering every route for every role.

Around 32,000 lines of plain HTML, CSS and JavaScript, with no framework, no dependencies and no build step. The prototype runs by serving the folder.