Quality and delivery
The platform is built by a small team that makes intensive use of AI agents. That makes automated checking not a luxury but the condition for working fast and responsibly.
Test strategy
| Type | Scope | What it protects |
|---|---|---|
| Component and unit tests | On every change, mandatory before merging; 2,816 test files | Behaviour of the interface, the business logic and the guards that record agreed rules |
| Isolation tests | On every change that touches the database and every night, against a real database; 134 series | Who may see which data, tested per role |
| End-to-end | After every deployment and every night, in three layers of complete journeys through the application | Logging in and the critical user routes |
| Deep smoke test | After every deployment on the test environment | Logging in, opening each of the eight worksheets, one generation with the real model, creating and downloading one report |
| Vulnerable packages | Every night | Whether a package the platform runs on has a known serious vulnerability |
| Models, storage and dossier | Every night | Whether the model list matches the provider's, whether storage holds files that no longer belong to a report, and whether the dossier is consistent |
| Search quality | Labelled evaluation set, run by hand when retrieval changes | Whether evidence retrieval still works as well as before |
The search-quality evaluation set deserves some explanation: labelled questions with a known correct answer, plus questions for which no good answer exists and the system has to say so. That makes it measurable whether a change improves evidence retrieval or quietly makes it worse, instead of judging it by feel. The evaluation set contains customer material and is therefore not in the repository. Whoever changes retrieval runs the measurement and attaches the result to the change.
The route to production
The golden rule: production never receives a database change that has not first been proven on the staging.
- A change goes to the staging as a proposal.
- There the migrations are applied and the isolation tests are run.
- Two gates check the outcome:
- a completeness gate that checks, per migration, that it has actually been applied;
- a parity gate that compares the schema of the staging and production.
- Only then does the same change go to production, through the same gates.
- After every deployment a smoke test runs automatically; it logs in and checks that the application works; on the test environment the deep smoke test from the table above follows as well.
Parallel processes that touch the same database are serialised, so that two deployments cannot overwrite each other. Changes that are ready go through a merge queue one at a time, which reports every step, and a change must be on the latest state of the test environment before it goes in.
One base for the schema. Since 22 October 2026 the schema consists of a single base file, made from production, plus the migrations that follow it. An empty database can be built from it in one step, with all privileges written out; a new table without its own access privileges is rejected at build time. See Data model.
Fifteen workflows in the build pipeline run at a fixed time, in Dutch time with a backup start, and each night's result is on the internal status board the next morning. A red night run appears there within minutes.
The build chain
The web application is built and developed locally with Vite; the test suite runs on a lightweight test runner without a heavy build layer on top. The build environment is pinned to one version of the operating system, and an automated package manager proposes bundled updates every week. Every night a scan checks the packages the platform runs on for known vulnerabilities: a serious vulnerability in something that runs turns the check red, and a scan that could read nothing does not count as green.
Gates come from incidents
Every automated gate above comes from something that went wrong once:
- A deployment after which users could no longer log in → smoke test after every deployment.
- Two changes developed in parallel, one of which quietly never reached production → completeness gate on migrations.
- A database change that made a login path ambiguous → structure check that looks specifically for that.
That pattern, in which an incident becomes a permanent, automated check instead of a one-off fix, is deliberate policy.
Decision-making
Architecture choices are recorded before they are built, including the alternatives considered, the drawbacks of the chosen route and the circumstances in which the choice should be reconsidered. See Architecture decisions.