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

20 KiB
Raw Blame History

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.
  • 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.
  • 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)

  • 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)

  • 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.)
  • 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.