Files
rdbms-playground/docs/requirements.md
T
claude@clouddev1 4fca862c6c Project storage runtime: ADR-0015 + ADR-0004/0007 amendments
Designs track-2 lifecycle and persistence end-to-end: per-command
write-through to db+yaml+csv+history.log gated by the combined db
persistence logic with commit-db-last ordering; existence-only load
with explicit rebuild command; --resume CLI flag backed by
<data-root>/last_project; in-TUI list-with-browse picker; lock file
for single-instance enforcement; fatal-banner-then-quit failure
model (with --resume making restart cheap); fatal CSV row-load
errors with full diagnosis; YYYYMMDD-word-word-word temp naming
with display-name prettifier; collision-checked names for both
temp and user-supplied projects. Project name lives only on the
filesystem (not duplicated in YAML). ADR-0004 and ADR-0007 amended
in place. requirements.md and CLAUDE.md updated; OOS-6 (global
rolling history) tracked as deferred.
2026-05-07 19:53:47 +00:00

453 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RDBMS Playground — Requirements (Phase 1)
This document is the **consolidated Phase 1 requirements
checklist** for RDBMS Playground. It captures everything the
project has committed to so far, derived from the design
conversation and the ADRs in `docs/adr/`.
**Purpose.** Phase 5 verification at every milestone measures
delivered work against this checklist. An item not on this list
was not promised; an item silently dropped without confirmation
is a process failure.
**Scope.** The list is intentionally coarse — each item is a
unit of "satisfied / not satisfied" judgement. When an item is
taken up for implementation, it is decomposed further in a
backlog (initially in this repo, later in GitHub issues once the
repo is pushed).
## Status legend
- `[ ]` — open, not yet implemented
- `[x]` — satisfied (implemented + tested)
- `[~]` — deferred, awaiting an ADR or further design before any
implementation
- `[-]` — explicitly out of scope (rationale at the bottom)
## Test baseline
No test suite exists yet — the repo currently contains only
docs. The baseline is therefore "0 passing, 0 failing, 0
skipped." Subsequent phases establish the suite and measure
against it.
---
## Distribution and install
- [ ] **D1** Cross-platform binaries: Linux, macOS, Windows on
x86_64 and aarch64.
- [ ] **D2** Single static binary, no runtime dependencies.
- [ ] **D3** Released via prebuilt binaries plus Homebrew, Scoop,
`winget`, and `cargo binstall`.
## TUI shell
- [ ] **S1** Three-region layout: items list (left), output
panel (right), input field (bottom).
- [ ] **S2** Items list shows tables and per-table indexes;
designed to extend to additional element kinds (relations,
views, etc.) without restructuring.
*(Progress: tables are listed live from the database; indexes
pending alongside C3 index support.)*
- [ ] **S3** Output panel renders a visualization of the
currently selected item and supports multiple tabs.
- [ ] **S4** Hint area below the input field; keyboard-toggleable
for inspecting hints about the current input or last error.
- [ ] **S5** Mode label and distinct border style on the input
field communicate the current input mode at all times.
## Input field
- [ ] **I1** Multi-line entry that auto-expands; Ctrl-Enter (or
equivalent) submits, plain Enter inserts a newline.
- [ ] **I1a** In-line cursor editing in the input field: Left /
Right arrows move the cursor by character (UTF-8 boundaries
honoured), Home / End jump to the extremes, Delete removes the
character at the cursor, Backspace removes the character
before. Insertion happens at the cursor position. *(Implemented;
multi-line editing per I1 still pending.)*
- [ ] **I1b** Readline-style cursor shortcuts: Ctrl-A / Ctrl-E
as aliases for Home / End for users on keyboards without those
keys (and for ergonomics in command-driven workflows). Likely
followed by Ctrl-W (delete previous word), Ctrl-K (delete to
end), Ctrl-U (delete to start). Pending.
- [ ] **I2** Persistent navigable input history (project-scoped,
with a global rolling history also available).
*(Progress: in-memory navigable history (Up/Down arrows, draft
preservation, dedup of consecutive duplicates) is implemented;
persistence across sessions arrives with track 2's project
storage.)*
- [ ] **I3** Tab completion for app commands, DSL keywords, table
names, column names, and SQL keywords.
- [ ] **I4** Syntax highlighting for both the DSL and SQL.
- [ ] **I5** In-flight query/command cancellation (Ctrl-C in the
output area or input field).
## Input modes (per ADR-0003)
- [ ] **M1** Simple mode is the default. It accepts DSL data
commands and the canonical app-level commands; raw SQL is
rejected with a friendly hint.
- [ ] **M2** Advanced mode accepts SQL plus the canonical
app-level commands without any sigil.
- [ ] **M3** Prefixing a single line with `:` in simple mode is a
one-shot advanced escape (with the prompt label updated). The
`mode simple` / `mode advanced` command switches modes
persistently.
## App-level commands (per ADR-0003)
- [ ] **A1** All canonical app-level commands implemented and
available in both modes: `save`, `save as`, `load`, `new`,
`rebuild`, `export`, `import`, `seed`, `replay`, `undo`,
`redo`, `mode`, `help`, `hint`, `quit`.
*(Progress: `quit`/`q` and `mode simple|advanced` implemented;
the rest land alongside the features they belong to — `save`,
`load`, `new`, `rebuild`, `export`, `import` in track 2
(ADR-0015), `seed` in the seeding iteration, etc.)*
## DSL data commands
- [ ] **C1** Table operations: create / drop / rename.
*(Progress: create + drop done; rename pending.)*
- [ ] **C2** Column operations: add / drop / rename / change
type, including the rebuild-table dance behind the scenes
where SQLite ALTER cannot do it directly.
*(Progress: add done; drop/rename/change-type pending — the
rebuild-table dance is the gating piece, B2.)*
- [ ] **C3** Schema constraints: primary key (single and
compound), foreign key with `ON DELETE` / `ON UPDATE` referential
actions, indexes, `NOT NULL`, `UNIQUE`, `CHECK`, `DEFAULT`.
*(Progress: PK including compound done at create-table time;
FK with `ON DELETE` / `ON UPDATE` actions done (ADR-0013) —
declared via `add 1:n relationship`; symmetric outbound +
inbound view in the structure renderer; type compatibility
validated at declaration via `Type::fk_target_type()`. Index,
`NOT NULL`, `UNIQUE`, `CHECK`, `DEFAULT` still pending.)*
- [~] **C3a** Modify relationship: `modify relationship <name>
[on delete <action>] [on update <action>]`. Users can achieve
the same via drop + add today; one-step modify is a small
follow-up using the existing rebuild-table machinery. ADR
pending.
- [ ] **C4** Convenience: `create m:n relationship from <T1> to
<T2>` produces an auto-named junction table the user can rename;
pulls primary keys and FK definitions automatically.
- [x] **C5** Data operations: insert / update / delete via DSL.
*(ADR-0014. INSERT short and long forms, UPDATE/DELETE with
required WHERE plus `--all-rows` opt-in, `show data <T>`,
per-column-type value-literal validation, FK enforcement
with metadata-driven error enrichment, auto-show after
writes. Bulk insert, complex WHERE expressions, and SELECT
in advanced mode are explicitly tracked separately — see
C5a below.)*
- [~] **C5a** Complex WHERE expressions (AND/OR/comparison
operators/LIKE) for UPDATE/DELETE/show-data filtering. Tracks
the natural progression from DSL into real SQL fluency that
motivates the playground; design and ADR pending.
## SQL handling
- [ ] **Q1** SQL parsed via `sqlparser-rs`; supported subset is
defined (specifics deferred to a future ADR).
*(Progress: DSL is parsed via `chumsky` (ADR-0009); SQL
handling in advanced mode is still a placeholder echo.)*
- [ ] **Q2** Non-standard syntax rejected with a clear message
pointing at the supported subset.
- [x] **Q3** User-facing simplified types map transparently to
SQLite STRICT types in generated DDL. *(All ten types implemented
and tested.)*
- [~] **Q4** Supported SQL subset specification — design and ADR
pending. Q1 cannot be marked satisfied without it.
## Database backend (per ADR-0002)
- [x] **B1** SQLite via `rusqlite`; all tables created `STRICT`;
`PRAGMA foreign_keys = ON` per connection. *(Database accessed
through a dedicated worker thread per ADR-0010.)*
- [ ] **B2** Schema evolution uses the rebuild-table technique
internally where SQLite `ALTER TABLE` cannot.
*(Progress: rebuild-table primitive landed (ADR-0013) and is
used by `add_relationship` / `drop_relationship`. Reuse for
column drops/renames/type changes pending; the primitive is
designed to support those without further architectural work.)*
- [ ] **B3** Query timeout and cancellation supported (no
cartesian-join-of-doom can hang the app).
*(Progress: the worker-thread architecture is in place; the
cancellation/timeout protocol on top of it is pending.)*
## Type system (per ADR-0005)
- [x] **T1** All ten user-facing types implemented: `text`,
`int`, `real`, `decimal`, `bool`, `date`, `datetime`, `blob`,
`serial`, `shortid`. *(Mapping to SQLite STRICT covered by
ADR-0005; FK target type rule by ADR-0011.)*
- [x] **T2** `shortid` generation: base58, 1012 characters,
omits ambiguous characters; generated client-side at insert.
*(Implemented per ADR-0014; auto-fills omitted shortid
columns and validates user-supplied values against the same
alphabet and length range.)*
- [ ] **T3** Compound primary keys handled end-to-end (DSL,
storage, display, FK reference).
*(Progress: DSL grammar (`with pk a:int,b:int`), storage, and
table-info description are all present; the FK iteration
references single-column PKs only — compound-key FK references
remain pending.)*
## Visualizations
- [ ] **V1** Single-element views render in the output pane: a
selected table as its structure (columns, types, keys,
constraints); a selected relationship as two tables joined by
a line.
*(Progress: a basic structure view (column rows with SQLite
type names) is rendered after each successful DDL; pretty
rendering, selection nav, and relationship line-art pending —
see V4 for the broader direction.)*
- [ ] **V2** SQL query results render as a dynamic table view in
the output pane, with multiple result tabs supported.
*(Progress: a basic aligned-column data view is rendered for
`show data` and after every write (ADR-0014). Pretty
box-drawing tables with truncation/scroll handling, plus
multi-tab support, remain in V4 territory.)*
- [~] **V3** Full ER-diagram export (whole-database graph, viewed
outside the TUI) — low priority; design and ADR pending.
- [~] **V4** Output panel as a *scrollable per-session log* with
inline rich rendering. Direction agreed in conversation: the
output area is a chronological journal of operations and
selections (e.g. a "selected table X" entry with the rendered
structure underneath); structure renderings choose between a
compact ASCII-table form and a vertical line-per-column form
based on dimensions; the log is exportable to Markdown so
learners can keep a record of their session. Design and ADR
pending before any implementation.
*(Partial: PageUp / PageDown scrolling of the existing line
buffer is in, with new output snapping the view to the most
recent. The full V4 scope — smart structure rendering, log
styling, Markdown export, scroll indicator — remains pending.)*
- [ ] **V5** `show <kind> [<name>]` family of commands for
redisplaying schema info on demand. *(Progress: `show table
<name>` and `show data <Table>` implemented;
`show tables`, `show relationships`, etc. pending.)*
## Project lifecycle (per ADR-0004)
- [ ] **P1** An auto-named temporary project is created on
startup unless a project is specified, and stored in a
platform-standard path
(e.g. `~/.rdbms-playground/projects/temp-<name>`).
- [ ] **P2** `save` elevates a temp project to a named project at
a chosen location.
- [ ] **P3** Project is always saved as changes occur — there is
no manual dirty state.
- [ ] **P4** `load` opens a picker listing temp projects with
timestamps, with the option to browse to an arbitrary location.
- [ ] **P5** `playground.db` is a derived artifact: rebuilt
silently when missing; rebuilt explicitly via the new
`rebuild` app-level command, which prompts with a change
summary before reconstructing from `project.yaml` + `data/`
(per ADR-0004 amendment 2 and ADR-0015 §7).
- [ ] **P-NAME-1** Temp project directory naming pattern:
`<YYYYMMDD>-<word>-<word>-<word>` from a built-in wordlist
(ADR-0015 §2). Date-sortable; collisions checked against
existing folders and the slug is regenerated on the rare
collision. User-supplied save names that already exist as
folders are refused with a friendly error.
- [ ] **P-NAME-2** Display-name prettifier converts a project
directory name to a human-readable display name: strip a
leading `YYYYMMDD-` for temp projects; split kebab / snake /
camel; title-case each word (ADR-0015 §2).
- [ ] **P-NAME-3** The current project's display name is shown
in the UI status bar at all times, prefixed with `Project:`
(ADR-0015 §2).
## Project file format (per ADR-0004)
- [ ] **F1** `project.yaml` with `version` field carries schema,
relationships, and project metadata; `data/<table>.csv` carries
table data (UTF-8, header row, RFC 4180).
- [ ] **F2** A `.gitignore` template (excluding `playground.db`)
is created in each new project.
- [ ] **F3** Project file format includes a registered-migrator
mechanism so older `version` values load cleanly as the format
evolves. (Exercised once `version` increments past 1; the
mechanism itself is built in v1.)
## Undo and replay (per ADR-0006)
- [ ] **U1** Auto-snapshot before destructive operations into a
ring buffer (initial size N=10, tunable).
- [ ] **U2** `undo` restores the most recent snapshot; `redo`
re-applies; both prompt for confirmation showing the snapshot
timestamp and a summary of the changes that will be discarded.
- [ ] **U3** `history.log` records every successfully executed
command in append-only form.
- [ ] **U4** `replay` runs commands from a `history.log` or
`.commands` file.
## Sharing and export (per ADR-0007)
- [ ] **E1** `export` produces a zip excluding `playground.db`;
default filename `YYYYMMDD-<projectname>-export-NN.zip` with a
non-clobbering two-digit sequence.
- [ ] **E2** User documentation includes sharing recipes for
git, email, and direct file transfer.
## Sample data / seeding
- [ ] **SD1** `seed <table> [count]` generates plausible fake
data; junction tables are seeded with valid foreign-key
references drawn from existing parent rows.
- [~] **SD2** Detailed seeding rules (per-type generators,
locale, determinism, override hooks) — design and ADR pending.
## Query analysis
- [ ] **QA1** `EXPLAIN QUERY PLAN` is run on demand for queries;
output is rendered as an annotated tree highlighting full
scans, index use, and join order.
- [~] **QA2** Plan rendering specifics (tree layout, annotation
taxonomy, colour scheme) — design and ADR pending.
## Hints, help, errors
- [ ] **H1** Friendly error-rewriting layer translates SQLite
error messages into learner-friendly equivalents.
*(Progress: foreign-key constraint failures are enriched
with both inbound and outbound relationship listings (so
RESTRICT errors point at the children that still reference
this table); full SQL → English translation pending.)*
- [ ] **H1a** Strong syntax-help in parse errors. When the user
types something near-correct (e.g. `insert into T ('Oli')` —
forgotten `values`; or `update T set x=1` — missing WHERE),
the error should *name the missing keyword or clause* rather
than just point at the unexpected character. This is a
separate effort from H1 (which targets database errors); it
targets parser errors. Pending — multiple targeted fixes
shipping piecemeal so far (e.g. `values` becoming optional in
INSERT removes one such case).
- [ ] **H2** `hint` provides contextual help for the current
input or the most recent error.
- [ ] **H3** `help` provides general reference and per-command
help.
## CLI
- [ ] **L1** Load a project via a positional CLI argument.
- [ ] **L1a** `--resume` CLI flag opens the most recently used
project (path tracked in `<data-root>/last_project`). Errors
cleanly if no previous project exists or the recorded path is
gone; mutually exclusive with a positional path argument
(ADR-0015 §7).
- [~] **L2** Submit a command alongside project load — deferred,
not v1.
## Tutorials and lessons
- [~] **TU1** Tutorial / lesson system — design and ADR pending
before any implementation. Out of v1 unless an ADR is written.
## Testing (per ADR-0008)
- [ ] **TT1** Tier 1: `cargo test` + `proptest` covering
pure-logic modules (parser, dispatcher, type mapping, project
I/O, snapshot ring buffer, replay log).
- [ ] **TT2** Tier 2: Ratatui `TestBackend` + `insta` snapshots
for representative views.
- [ ] **TT3** Tier 3: synthetic event-loop integration tests
covering the user-facing flows in this checklist.
- [ ] **TT4** Tier 4: PTY-based end-to-end for the four critical
flows named in ADR-0008 (cold launch → DDL → quit; save →
reopen; export → import → rebuild; undo after DROP).
- [ ] **TT5** CI runs all tiers on Linux, macOS, and Windows on
stable Rust.
## Cross-cutting
- [ ] **X1** Comprehensive logging via the project's logging
infrastructure per `CLAUDE.md` (decision points, parameter
values, fallback paths).
- [~] **X2** Language: English-only for v1; multi-language is an
open question to revisit later.
- [~] **X3** Accessibility: TUI screen-reader support is
best-effort and not a v1 commitment; revisit if user need
emerges.
---
## Non-functional requirements
NFRs are quality bars rather than discrete features. Where a
target is measurable, it is stated numerically; where it is
necessarily qualitative, the criterion is named and the bar is
"reviewer judgement against the criterion."
- [ ] **NFR-1 Performance — startup.** Cold launch to first
rendered frame under 500ms on commodity hardware (developer
laptop, mid-range desktop). Measured in CI on the Linux runner
as a regression gate.
- [ ] **NFR-2 Performance — input latency.** Keystroke-to-render
latency under 16ms during normal editing; long-running queries
must execute off the UI thread so the interface remains
responsive (typing, scrolling, mode switching) while a query is
running.
- [ ] **NFR-3 Performance — resource footprint.** Idle memory
under 50MB on the smallest target platform; no busy-loops; CPU
near zero when waiting for input.
- [ ] **NFR-4 Visual quality — distinctive design.** Colour
palette and typography are deliberate and consistent across
views; layout uses Unicode box-drawing and symbols where they
add clarity; rendering avoids the generic flat-default look
that ships with most TUI frameworks. Criterion: a reviewer can
identify the app from a screenshot of any view.
- [ ] **NFR-5 Visual quality — colour use.** Colour conveys
information rather than decoration: mode indication, query
result types (numeric vs text vs null), error severity,
syntax highlighting categories. Foreground/background
combinations meet WCAG-AA contrast (4.5:1 for normal text)
even though we have not committed to broader accessibility.
- [ ] **NFR-6 Cross-platform parity.** Behaviour and visual
quality are equivalent across Linux, macOS, and Windows on
crossterm-supported terminals. Platform-specific divergence
(e.g. font fallbacks) is documented, not silently tolerated.
- [ ] **NFR-7 Light and dark background support.** The colour
scheme remains legible and visually coherent on both light and
dark terminal backgrounds. The mechanism (auto-detect via
terminal query, explicit user setting, or both) is an
implementation choice, but the outcome is non-negotiable: no
dark-on-dark or light-on-light readability failures on either
background.
---
## Explicitly out of scope
- [-] **N1** Hosted publishing platform — per ADR-0007. Sharing
is local-artifact based.
- [-] **N2** Real UUID column type — per ADR-0005. The `shortid`
type covers the pedagogical need at TUI-friendly width.
- [-] **N3** Cross-emulator visual regression coverage — per
ADR-0008. Crossterm abstracts terminals adequately; we revisit
only if a real regression surfaces.
- [~] **N4** Global rolling input history (cross-session,
cross-project). Mentioned in I2's wording; deferred per
ADR-0015 §12 — project-scoped history (via `history.log`) is
the v1 surface. Revisit if real demand emerges.
---
## Maintenance
This document is updated whenever:
- A new requirement is committed to (added as a new item with the
next free ID in its section).
- A deferred item is taken up (status moves from `[~]` to `[ ]`).
- An item is satisfied (status moves to `[x]`, with a reference
to the commit, PR, or test that demonstrates it).
- An item moves out of scope (status moves to `[-]` with a
rationale and a link to the decision).
IDs are stable: once assigned, they are not reused. Removing a
requirement leaves a "withdrawn" entry referencing the decision.