Case study
From email chains to a tamper-evident traceability platform
A small team, three months, from blank repository to a working multi-tenant traceability platform for industrial decommissioning: one shared record per project, custody events for every material hand-off, and a cryptographically chained audit trail.
- Client
- Digital platform company in industrial metal trading (anonymized)
- Industry
- Circular economy, metal recycling, industrial decommissioning
- Scope
- Custom multi-tenant SaaS product, from blank repository to working proof of concept
- Engagement type
- Fixed-scope product development
- Team and timeline
- A small team, three months

The challenge
Our client, a digital platform company in the industrial metal trading space, wanted to expand beyond trading into orchestration: coordinating the full decommissioning of heavy industrial assets across a network of partners, on behalf of an enterprise customer running a circular-economy programme. The process they needed to digitize is months long, multi-party, hazardous, and heavily regulated. A single project involves the asset owner, the orchestrating enterprise, dismantlers, oil processors, carriers, smelters, sometimes manufacturers, plus compliance officers and external auditors.
Today that process runs on email chains, scanned PDFs, spreadsheets, and phone calls. The cost shows up in five places: sustainability claims resting on evidence scattered across inboxes, licenses expiring unnoticed, weight differences argued over email instead of resolved against a shared record, hours spent chasing status, and every new partner onboarded through one-off conversations.
No off-the-shelf product covers this. Our client needed a custom platform, and they needed a working system in front of their enterprise partner fast.
What we built
We built a multi-tenant coordination and traceability platform. Each participating company sees only its own data and only the slice of a shared project that concerns it. The core idea: one shared record per project, with every hand-off of material recorded as a first-class custody event, every document uploaded by the party that holds it, and every regulatory export generated from the same operational data that ran the project. The audit trail is not a separate artefact built after the fact - it is the work itself, read in order.
In three months, a small team took this from an empty repository to a working application covering the full lifecycle:
- Partner onboarding with license verification and expiry monitoring
- A five-step project wizard, including a fully editable execution chain (the ordered plan of who does what, where, with which loss tolerances)
- Pickup scheduling, transport legs with custody transfers at pickup and delivery, and weight-variance resolution with evidence windows
- Dismantling, smelting, and manufacturing records with material piles as the accounting unit and lineage from source asset to finished output
- Loss controls with colour-coded thresholds: moderate losses require written explanation and photo evidence, severe losses automatically pause the project until an administrator reviews
- Compliance document gates that block process steps until required evidence (test reports, weighbridge tickets, quality certificates) is on file
- Closure certificates, final reports, and a carbon-footprint report generated from operational data, each carrying a cryptographic content hash so auditors can verify the PDF they hold matches what the platform produced
- A role-based Control Tower dashboard and a notification system spanning email and in-app channels
The delivered proof of concept comprises roughly 60,000 lines of TypeScript, around 195 business-logic modules, 75 database tables, and 576 screen components.
Technology choices
We chose a deliberately mainstream, maintainable stack and spent the boldness budget on architecture instead:
- Next.js 15 with TypeScript in strict mode - one framework for UI and API, no
anyallowed anywhere in the codebase - GraphQL, schema-first - the
.graphqlschema files are the contract; code generation produces typed resolvers and client hooks, so the API can never silently drift from its types - PostgreSQL with Prisma - every schema change must ship with a matching migration, enforced by pre-commit hooks and CI
- Material UI, React Hook Form, and Zod - typed, validated forms from schema to submission
- AWS - containerized application, managed Postgres, S3 for documents and generated PDFs
Two architectural decisions carried the most weight:
Policy-based access control as the single source of truth. With ten different personas across competing companies on one platform, scattering role checks through the UI was never an option. Every authorization decision flows through a central policy engine - in GraphQL resolvers via a schema directive, server-side via a single evaluation function, client-side via permission flags delivered with the data. A linting rule blocks inline role checks outright, and a coverage test enforces that every declared permission action has a seeded policy decision. Authentication includes SSO foundations (SAML), two-factor authentication via TOTP and email codes, full password lifecycle, and four-eyes approval workflows for sensitive operations.
A cryptographically chained audit trail. Every meaningful action is logged with who, what, before/after state, and request fingerprint. Each log entry carries a SHA-256 hash of the previous entry, forming a per-tenant hash chain: any tampering with historical records is detectable by walking the chain, in line with German GOBD record-keeping requirements. Even audit exports are themselves logged, so you can audit the auditors.
Engineering discipline at speed
Three months with a small team only works if quality is enforced by machines, not by heroics. The guardrails ran from day one:
- More than 16,000 automated test cases across unit, integration, and end-to-end suites (Jest and Playwright), with coverage gates of 80 percent overall and 90 percent for business-logic services
- ESLint configured aggressively: maximum cyclomatic complexity of 10, functions capped at 100 lines, files at 500, zero warnings tolerated
- Pre-commit hooks running lint, formatting, and schema-drift checks; CI blocking any merge that fails a gate
- Strict layering - routes and resolvers stay thin, business logic lives in services, which is exactly where the 90 percent coverage requirement bites
These rules were not aspirational documentation. They were enforced on every commit, which is what allowed a small team to move fast on a compliance-grade system without accumulating the debt that usually comes with PoC speed.
Why fixed scope and a small team works
Custom product development fails most often through drift: scope grows, the team grows to match, and the feedback loop with the client stretches until the product no longer fits the need. Keeping the team at five, the timeline at three months, and the quality gates automated meant every week produced reviewable, working software - and the client's domain experts could correct course while correcting was still cheap.
The outcome
What the client walked away with
A real, working application - not a slideshow or a clickable mockup - with every core workflow from the contract present, ready to put in front of the enterprise partner and real operating partners
Commercial proof that a multi-company industrial process can run on one shared, auditable record, with circular-economy claims resting on verifiable chain-of-custody evidence instead of inbox archaeology
A pilot phase under way on that basis: production cloud infrastructure, independent penetration testing, accessibility audit, and the first controlled real-world projects
Need a custom product on a startup timeline?
If you need a custom product built to enterprise standards in months rather than years, get in touch and we will talk through scope, team, and timeline.