feat: SQL Workbench qbit 1.0 backend #1

Merged
KofTwentyTwo merged 10 commits from feature/1-sql-workbench-1.0 into develop 2026-10-11 18:52:05 +00:00
KofTwentyTwo commented 2026-10-11 15:52:46 +00:00 (Migrated from github.com)

What

The 1.0 backend of the SQL Workbench QBit: a super-user SQL notebook over any QQQ RDBMS backend. Sessions are read-only by default, write mode is gated, and every execution is audited. The design is in docs/DESIGN.md, already on develop.

Contents

  • SQL layer. sql/ has a dialect-aware scanner and a statement splitter/classifier (READ, EXPLAIN_ANALYZE, WRITE, DDL, FORBIDDEN), plus :named parameter binding.
  • Engine. engine/ holds the engine itself plus its supporting pieces: session guard, result collector, result cache, running-statement registry, write-preview tokens, and the auditor.
    • Read-only runs execute in a database READ ONLY transaction: Postgres SET TRANSACTION READ ONLY, MySQL session characteristic, SQLite query_only. On H2 only the classifier applies.
    • Write mode needs sqlWorkbench.write and runs as preview, then commit. The preview is a dry run that is rolled back. The commit needs a single-use token bound to the user, the SQL, and the backend. A row guard, a hard cap, and a drift check apply.
    • Limits: statement timeouts, row and byte caps, cancellation (also with a client-chosen execution id), and a per-user concurrency limit.
    • The connection is always returned clean, or aborted if it can't be restored.
    • The audit is fail-closed: a RUNNING row is written first, and audit updates are deferred until the session's connection is released.
    • Optional dedicated read-only or write credentials per backend, and support for the backend's read-only replica.
  • EXPLAIN. explain/ runs EXPLAIN and EXPLAIN ANALYZE (always rolled back) and turns the output into one plan tree for Postgres, MySQL, SQLite, and H2.
  • Schema. schema/ introspects the schema for autocomplete and maps QQQ table and field names to their SQL names.
  • Notebooks. notebook/ stores personal and shared notebooks, cells, versions with retention, and pinned result snapshots.
  • API. api/ has the REST routes under /qqq/v1/sql-workbench (Javalin 7, registered through QJavalinMetaData the way ESB does it, JSON-only bodies) and CSV/XLSX/JSON export.
  • Metadata. metadata/ holds the 5 tables, a notebook possible-value source, the SQL_WORKBENCH widget, and the sqlWorkbench app. There are no processes.
  • DDL. docs/ddl/postgres.sql for hosts' Liquibase.
  • Repo setup. CircleCI qqq-orb 0.6.8, the Maven wrapper, CLAUDE.md/AGENTS.md, and CHANGELOG, all following qbit-quick-search.

Gates

CI=true ./mvnw verify passes locally:

  • 84 unit tests (H2, SQLite, Javalin over HTTP).
  • 6 Testcontainers Postgres integration tests (postgres:16-alpine).
  • JaCoCo: 94% instruction coverage, every class covered.

Not merging

This needs review. After it merges, release/1.0 gets cut for 1.0.0-RC.1 (see the release steps in the session report).

🤖 Generated with Claude Code

## What The 1.0 backend of the SQL Workbench QBit: a super-user SQL notebook over any QQQ RDBMS backend. Sessions are read-only by default, write mode is gated, and every execution is audited. The design is in `docs/DESIGN.md`, already on `develop`. ## Contents - **SQL layer.** `sql/` has a dialect-aware scanner and a statement splitter/classifier (READ, EXPLAIN_ANALYZE, WRITE, DDL, FORBIDDEN), plus `:named` parameter binding. - **Engine.** `engine/` holds the engine itself plus its supporting pieces: session guard, result collector, result cache, running-statement registry, write-preview tokens, and the auditor. - Read-only runs execute in a database READ ONLY transaction: Postgres `SET TRANSACTION READ ONLY`, MySQL session characteristic, SQLite `query_only`. On H2 only the classifier applies. - Write mode needs `sqlWorkbench.write` and runs as preview, then commit. The preview is a dry run that is rolled back. The commit needs a single-use token bound to the user, the SQL, and the backend. A row guard, a hard cap, and a drift check apply. - Limits: statement timeouts, row and byte caps, cancellation (also with a client-chosen execution id), and a per-user concurrency limit. - The connection is always returned clean, or aborted if it can't be restored. - The audit is fail-closed: a RUNNING row is written first, and audit updates are deferred until the session's connection is released. - Optional dedicated read-only or write credentials per backend, and support for the backend's read-only replica. - **EXPLAIN.** `explain/` runs EXPLAIN and EXPLAIN ANALYZE (always rolled back) and turns the output into one plan tree for Postgres, MySQL, SQLite, and H2. - **Schema.** `schema/` introspects the schema for autocomplete and maps QQQ table and field names to their SQL names. - **Notebooks.** `notebook/` stores personal and shared notebooks, cells, versions with retention, and pinned result snapshots. - **API.** `api/` has the REST routes under `/qqq/v1/sql-workbench` (Javalin 7, registered through `QJavalinMetaData` the way ESB does it, JSON-only bodies) and CSV/XLSX/JSON export. - **Metadata.** `metadata/` holds the 5 tables, a notebook possible-value source, the `SQL_WORKBENCH` widget, and the `sqlWorkbench` app. There are no processes. - **DDL.** `docs/ddl/postgres.sql` for hosts' Liquibase. - **Repo setup.** CircleCI qqq-orb 0.6.8, the Maven wrapper, CLAUDE.md/AGENTS.md, and CHANGELOG, all following qbit-quick-search. ## Gates `CI=true ./mvnw verify` passes locally: - 84 unit tests (H2, SQLite, Javalin over HTTP). - 6 Testcontainers Postgres integration tests (`postgres:16-alpine`). - JaCoCo: 94% instruction coverage, every class covered. ## Not merging This needs review. After it merges, `release/1.0` gets cut for 1.0.0-RC.1 (see the release steps in the session report). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.