Recover from data disasters in a real SQLite database that runs inside your browser. Every challenge starts after the mistake has already happened. Your job is to put the data back with the least loss, and then prove it.
Live page: https://wenslink-os.github.io/undo-the-damage/ (after GitHub Pages is enabled for this repository)
| Incident | What went wrong | What makes it hard |
|---|---|---|
| The migration without a WHERE | A migration archived every order instead of the cancelled ones | Real work happened after the damage and must survive |
| The import that ran twice | Duplicate contacts that differ only in case and spaces | Notes point at both copies, and each copy has data the other lacks |
| The rename script | Paths were rewritten and a colliding file was deleted | Two separate repairs, and the evidence tables must stay untouched |
| The import over newer data | Stale stock numbers overwrote live ones | Reverting is not enough, later sales must be replayed |
- Reversible by design. Every run that changes data can be undone with one click. A statement that fails, even halfway through a batch, changes nothing.
- Evidence matters. Audit and log tables are marked as evidence. Deleting them disqualifies a recovery, because a recovery you cannot explain is not a recovery.
- A receipt, not just a green tick. When the check passes you can download a receipt (JSON and Markdown) with every statement you ran, SHA-256 fingerprints of the incident, final and expected states, whether you used hints or looked at a solution, and a hash of the whole receipt. The page can verify a receipt file and detects edits.
- No servers. The SQLite engine (sql.js, MIT, vendored in
site/vendor) and all data stay in your browser. No API keys, no accounts.
Needs Node 20 or newer, only for tests and the local server.
npm ci
npm test # runs every scenario, reference solution, wrong attempt and the receipt checks
npm run serve # http://localhost:8080
npm test fails when any of these break:
- a scenario's incident state does not count as data loss
- the reference solution does not reach the expected state with zero loss
- a documented wrong attempt is accepted
- deleting an evidence table still passes
- a failed statement changes data, or undo does not restore the previous state
- a tampered receipt still verifies
- the SHA-256 implementation differs from Node's crypto on any test input
- the vendored sql.js differs from the pinned version
The expected final rows for each scenario are written out by hand in site/scenarios.js. They are not generated from the reference solution.
See CONTRIBUTING.md.
- Code: MIT, see LICENSE.
- Explanations and written content: CC BY 4.0, see LICENSE-CONTENT.md.
- sql.js: MIT, see
site/vendor/LICENSE-sql.js.txt.