Files
supabase/apps
Charis e126b68390 feat(studio): make the notebook wire schema the source of truth for query sources (#49069)
First of a stack. Groundwork only — additive, no behavior change,
nothing else in the tree touched.

The notebook content schema is the contract shared with the API and the
agent tool surface, so it is where source parameters and their
validation belong. A follow-up PR has the runtime query-source registry
borrow from here instead of keeping its own parallel definitions, which
had already drifted (different discriminant, different field names, a
narrower set of relative units).

## What changed

- **`timeRangeSchema` is exported**, and picks up the two validations
that existed only in the registry's copy and not here: a positive
integer `amount`, and an absolute range whose end follows its start.
- **`databaseSourceSchema` / `logsSourceSchema`** give each backend's
parameters a single definition. They are spread flat into their cells
with `...shape` rather than nested under a `source` key, so the JSON an
agent has to author stays shallow.
- **`database_identifier`** lets a database cell persist a read-replica
selection, which it previously had no field for. Named that rather than
`identifier` because every cell already carries an `id`.
- **`queryCellBaseSchema`** holds what every runnable cell shares
(`title`, `view`, `chart`), which was duplicated across `database_cell`
and `log_cell`. `sql` deliberately stays on the members so the domain
transform can brand it per dialect and generic code holding a query cell
can't hand it to the wrong wire boundary.
- **`CELL_KINDS` + `isQueryCell`** classify cells for query-generic UI.
The `satisfies Record<Cell['_tag'], CellKind>` clause makes this the
registration point for a new backend: adding a cell type fails to
compile until it is classified, and `QueryCell` widens on its own once
it is.

## Wire compatibility

The only wire shape change is the new optional `database_identifier`, so
`schema_version` stays at 1 and no persisted content needs migrating.
Notebooks are still behind the `explorer` flag, so there is no saved
`user_content` to worry about either way.

`view` keeps master's current handling — optional on the wire, defaulted
to `'table'` in the domain transform — and `chart` stays persisted
independently of it, so switching to the table view and back returns the
user's chart settings rather than rebuilding them.

## Tests

`notebook-schema.test.ts` covers the new validations (unit set,
non-positive/fractional amounts, absolute ordering, which field an
invalid bound is reported against), `database_identifier`, `isQueryCell`
narrowing, and that a chart survives alongside `view: 'table'`.

Typecheck, Prettier, and the lint ratchet all clean; 120 tests pass
across `data/content/notebooks` and `lib/ai/tools`.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added support for database identifiers in notebook query
configurations.
- Improved handling of database and log query cells for more consistent
notebook behavior.
  - Preserved chart configuration when switching to a table view.

- **Bug Fixes**
- Time ranges now require valid dates, positive whole-number relative
amounts, and correctly ordered absolute start and end times.
- Validation errors now identify the specific time-range field with
invalid date values.

- **Tests**
- Expanded coverage for query-cell detection, time-range validation,
optional database identifiers, and chart settings.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-14 13:18:41 +07:00
..