Reads a database's own catalog over the [Database] port and answers
in cratefield-tables' schema vocabulary.
This is the one source the dashboard's data screen renders today: the database itself knows its tables, columns, primary keys, foreign keys and indexes, which is where Supabase's schema visualiser reads them from too. The alternative sources were considered and rejected:
- The migrations are hand-written SQL strings scattered across the module crates; parsing DDL to recover a schema is a guess dressed as a parser, and it could only ever describe the modules this repo ships, not what a database actually holds.
- The
/__surfacetables contract (harness #153) is the intended second source: a venture publishing its declared tables there is more trustworthy than a stranger's live catalog, and the renderer is written againstcratefield_tables::Schemaso it can take either without change. But publishing that contract changes a core surface and shows nothing until ventures deploy, so it is deliberately not this crate's problem.
Why this crate is the one place with dialect-specific SQL
ADR 0004's portability rule — module SQL must run on SQLite and
Postgres unchanged — is enforced by
lint_portable_sql, which fz doctor runs over a module's migrations and the Postgres migration
runner runs over its set selection. Neither path ever sees this crate:
a catalog query is not a migration, and there is no portable way to
ask a database what it contains. sqlite_master does not exist on
Postgres and information_schema does not exist on SQLite; pretending
otherwise would mean a third, blander catalog that answers about
neither. A catalog is not data — the rule is about data moving between
engines — so the dialect-specific SQL lives here, commented, and
nowhere else.
What the crate does not do
No driver is linked: statements go over dyn Database as SQL strings
with bound parameters, so the crate stays wasm32-clean alongside the
kernel and gains whatever engine the port's adapter provides. It does
not write, ever — every statement here is a SELECT.