Captures up-front design decisions for RDBMS Playground: stack (Rust + Ratatui + SQLite), input modes, project file format, type vocabulary, undo snapshots and replay log, sharing/export, and testing approach. ADR-0000 establishes the ADR practice itself and mandates index upkeep alongside any ADR change.
3.4 KiB
ADR-0006: Undo snapshots and replay log
Status
Accepted
Context
Two related features address the same underlying need — making the application safe and reproducible for learners:
- Accidental destruction. A student typing
DROP TABLE Customersand then realising what they did is a near-certain event in this audience. Without a recovery path, the experience is hostile and the learning moment is lost to panic. - Replay and scripting. A persistent record of every executed command is useful for tutorials, debugging, sharing reproducible problem reports, and rebuilding a project from a blank slate.
Both features are cheap to implement and high-leverage.
Decision
Undo snapshots
Before any destructive operation — DROP, DELETE, TRUNCATE,
schema-rebuild migrations, restore, etc. — the application takes a
snapshot of the database using SQLite's online backup API into a
ring buffer of recent snapshots (size to be tuned; initial target
N = 10).
An undo command (available in both modes as an app-level
command per ADR-0003 — no sigil) restores the most recent
snapshot. Each undo step is itself snapshotted to keep redo
possible.
Undo requires confirmation. Snapshots are taken only before destructive operations, so the "current" state may include non-destructive work (inserts, updates, schema additions) done since the last snapshot. Restoring a snapshot therefore can discard data the user has not been explicitly warned about.
Before restoring, the application displays a confirmation prompt that includes:
- The snapshot's timestamp (local time, with a relative form such as "12 minutes ago").
- A short summary of the operation that triggered the snapshot
(the command text, e.g.
DROP TABLE Customers). - A summary of changes that will be discarded if the undo proceeds — at minimum, counts of rows added/modified/deleted per table and any schema changes since the snapshot.
The user must explicitly confirm. A keyboard shortcut for "confirm" is provided so power users are not slowed down, but there is no flag to suppress the prompt — undo is rare enough, and consequential enough, that the prompt is always shown.
Replay log (history.log)
Every successfully executed command — DSL or SQL — is appended to
history.log in the project directory, one command per record,
with a timestamp and the resulting status. The format is
deliberately simple and human-readable so it can be hand-edited
and replayed.
The same format serves three purposes:
- A persistent input history surfaced via the TUI history feature.
- A scripting format:
.commandsfiles (orhistory.logitself) can be replayed via areplaycommand. - A reproducible bug-report artifact when a project is shared.
The log is append-only during a session. It is not the
authoritative state of the project (that lives in project.yaml
data/, ADR-0004) — it is an audit and replay trail.
Consequences
- Snapshots add modest overhead per destructive operation. The cost is bounded; learners care about safety far more than microseconds.
- The ring buffer size must be tuned later based on realistic database sizes; an initial value is fine for now.
- The replay log enables a future
replay/ scripting feature with no additional storage commitment. - Tutorial authors gain a natural "starter script" format for exercises.