Skip to content
Back to all work
Full-Stack / Workflow Engineering2026

Sealed

A working demonstration of approval routing and document sealing — a chain frozen at submission, signatures applied in-browser, and an artifact you can verify without trusting the system that produced it.

Role
Architect & sole engineer
Next.js 16React 19TypeScriptPrismaSQLite

The application

Screens, captured from the running app

Booted against its seeded database and walked route by route — these are the real pages, not mockups.

Document list showing memos, transfer instructions and expense claims with chain progress dots and status.
Each row shows how far the chain has actually got. The seed exercises rejections and changes-requested rounds, not just the happy path.
A sealed document showing its approval chain, both integrity hashes, the appended audit certificate and the full ordered action log.
A completed document: the frozen chain, both hashes, the certificate that gets appended to the PDF, and every action with its timestamp and address.
Compose screen with the approval chain resolved from the From/To/Through/CC convention before submission.
The chain is resolved before you send, from the convention the firm already used on paper — and submitting freezes it.
Append-only audit trail across all documents with actor, action, document and source address.
Append-only, and it records the views that changed nothing as well as the decisions that did.
Roster of people with roles, alongside the delegated authority table and the closed-system sign-in policy.
Delegated authority per role, and the reason there is no sign-up route: a closed system with an open front door is not a closed system.

A demo, built to show the architecture behind a confidential client platform without exposing it. The firm, the people and the paperwork are invented. The routing, sealing and audit behaviour is the real thing.

Why it exists

The production version routes real memos and bank transfer instructions for an investment firm, and can't be shown. What's interesting about it isn't the interface — it's four decisions that are almost impossible to make convincing in prose, so here they are running.

Twenty-two documents across a month: thirteen sealed, four still waiting on a middle approver, four returned for changes, one rejected outright.

1. The chain is frozen at submission

When a document is submitted, the resolved approval chain is written to it as a snapshot — names, titles, and positions as they were at that moment.

Resolving it live at read time would be less code and quietly wrong. If someone is promoted next month, or leaves, or the signing threshold changes, the record of who was required to approve last month must not change with them. Every later view of the approval history reads the snapshot rather than re-running the rule.

2. Request-changes is its own state

Modelling "please fix this" as reject-then-resubmit is the obvious shortcut, and it destroys the thing people most often need to read later: the thread of the conversation. A returned document keeps its note, its author and its place in the chain.

In this seed that distinction is visible — four documents sitting in changes requested against one outright rejected, and the notes read very differently ("beneficiary bank details differ from the record on file" versus "outside the delegated authority for this category").

3. Hash both ends, not just the output

Sealing produces two digests:

  • The original, at submission. Proves the document was not altered before the first signature.
  • The sealed artifact, certificate page included. Proves it was not altered after the last one.

Hashing only the output is the common version and it leaves the first gap wide open. Both are shown on the document, so the artifact can be verified later without trusting the system that produced it.

4. CC never gates

The firm's existing paper convention was From / To / Through / CC, so the router reads exactly that. TO and THROUGH gate progress; CC recipients are notified and recorded in the audit trail, but a document never waits on them.

A chain that stalls on someone who was only ever copied is the classic way these systems quietly stop being used.

The audit trail

Append-only, and it records the views that changed nothing alongside the decisions that did — 141 events across the seed, each with actor, timestamp and source address. Signatures carry their own address rather than inheriting one from the session, because "who signed this, from where" is the question the trail exists to answer.

Stack

Next.js 16 App Router with React Server Components, Prisma over SQLite, five routes. In production this pairs with Puppeteer for HTML-to-PDF composition and pdf-lib for signature stamping and certificate appending; the demo models the resulting artifact rather than generating it, since the PDF pipeline is the part that is genuinely just plumbing.

You have a process thatshould be a system.

Tell me what arrives, who has to act on it, and where it currently falls over. That conversation is usually enough to scope the build.