Studio Power Tools

Phase 4 adds five surfaces on top of the read and write APIs. They’re optional — none of them change the CRUD contract — but they’re what makes Studio useful as an admin tool rather than just a row browser.

SQL preview

Renders the SQL Studio would run for an operation without touching the database. Lets you understand what the abstraction is doing before pulling the trigger, or copy it into a query tool to tweak by hand. Bound parameters are returned alongside the SQL text so you don’t have to read the placeholders.
API-backed targets return 501 UNSUPPORTED — Studio doesn’t render SQL it doesn’t run.

Drift

Compares the schema’s declared columns to the live database (information_schema on Postgres, PRAGMA table_info on SQLite) and reports the result per model:
The UI renders a small ⚠ drift chip next to drifting models in the sidebar and ✕ table for missing tables.

CSV/JSON export

Pulls up to limit rows (capped at 10 000) through cursor pagination internally and returns one body. Sets Content-Disposition: attachment; filename="<target>-<table>.<ext>" so the browser downloads the file straight from the link. CSV uses RFC-4180-style escaping (quote-wrap on commas, quotes, or newlines; double up embedded quotes). JSON is a flat array of objects, field names as keys.
The export endpoint is bounded — it’s for “developer pulling a sample for a notebook,” not “ETL.” For multi-million-row dumps, hit the database directly.
Case-insensitive substring over models, fields (including the Model.field path and the field’s type), enums and their variants, mixins, types, and procedures. Empty query returns { "hits": [] }.
Hit kind is one of model, field, type, enum, mixin, procedure. The UI renders an inline dropdown directly under the search bar in the header.

Audit log

Studio holds every successful write (CREATE / UPDATE / DELETE) in an in-memory ring buffer, capped at 500 entries, FIFO when full. Entries are returned newest-first:
The buffer lives in process memory only — Studio is a local admin tool, not a logging pipeline. Restarting the binary clears the log. The UI’s “Audit” button in the header opens an overlay listing the most recent 100 entries.

Constraint errors → VALIDATION_ERROR

Studio used to surface driver constraint failures as DATABASE_ERROR (500). Phase 4 maps the well-known codes back to the same per-field VALIDATION_ERROR envelope as the in-process validators: Unrecognized errors still come back as DATABASE_ERROR. The wire envelope is identical to the in-process validator path (see the write API page), so the UI doesn’t care whether the rejection came from Studio’s pre-flight check or the database’s constraint engine.