ADR-0022 stage 8d: schema cache refresh wiring

New `AppEvent::SchemaCacheRefreshed(SchemaCache)` event +
App handler that stores it on `app.schema_cache`.

Runtime helper `refresh_schema_cache(database, event_tx)`
fetches table / column / relationship names via the
`list_names_for` worker request (added in stage 7) and posts
the assembled cache. Wired into every site that already
posts `TablesRefreshed`:
  - `seed_initial_tables` (initial project load).
  - Project-switch path in `handle_project_switch`.
  - `RebuildSucceeded` path.
  - Post-DDL path (`spawn_command`).
  - Post-replay path.

Result: schema-aware identifier completion (added in 8c)
becomes live — Tab on `show data ` offers the actual table
names from the current project, `drop column from T: ` (or
similar) offers existing columns, etc. The cache stays
fresh across DDL and rebuild without per-keystroke worker
round-trips (one refresh per schema-mutating action is
amortised across many subsequent keystrokes).

Best-effort: a failed `list_names_for` for any individual
slot kind leaves that field empty in the cache rather than
suppressing the whole refresh — partial completion beats
no completion.

Tests: 738 passing, 0 failing, 1 ignored (unchanged
total — this stage is wiring, not new test surface; the
synthetic-cache tests from stage 8c remain the regression
net for the completion logic itself). Clippy clean.
This commit is contained in:
claude@clouddev1
2026-05-11 20:57:09 +00:00
parent 51a8d9ac44
commit 7a32c13bd5
3 changed files with 51 additions and 0 deletions
+10
View File
@@ -356,6 +356,16 @@ impl App {
self.tables = tables;
Vec::new()
}
AppEvent::SchemaCacheRefreshed(cache) => {
trace!(
tables = cache.tables.len(),
columns = cache.columns.len(),
relationships = cache.relationships.len(),
"schema cache refreshed",
);
self.schema_cache = cache;
Vec::new()
}
AppEvent::PersistenceFatal {
operation,
path,