Skip to content

feat: location detail, backfill, trigger schedules and maintenance grant counts - #1386

Merged
kvlonge merged 154 commits into
mainfrom
feat/ui-locations-backfill-schedules
Nov 9, 2026
Merged

kvlonge merged 154 commits into
mainfrom
feat/ui-locations-backfill-schedules

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Why

One pull request for the UI work audited after the last combined delivery: one full Verify run, each part its own changelog entry.

Changes

  • Locations: a location detail page and a scheduler status strip, read from the server's health reads.
  • The maintenance read returns how many grants were copied to an old-name view instead of the GRANT statements. MaintenanceOldNameView.grants_copied is now a count; the TypeScript control client is regenerated and the Maintenance page shows the count.
  • Job and group launch forms can backfill over a cursor window for people granted run.rewrite_history, through the existing run request. Plain-text refusals (below 500) are shown; server failures show only the status.
  • The trigger page lists the next due time and, for calendars, the stored times from then on, the last stored time and the next refresh.

main is merged in with no content change.

Verification

  • make check-ci passes on the head, including the control client check against the native OpenAPI contract.
  • UI: vitest (152), svelte-check, vite build.
  • Grant count: orchestration crate tests on SQLite and PostgreSQL; rendered against a server built from the change, with no GRANT text or grantee in the response.
  • Each part passed its own audit.
  • Hygiene scans are clean.

DuckShop: the existing old-name view case in edge_cases/orchestration/maintenance_history.json gains copied grants, so the count is exercised; no new project shape is involved.

BEGIN_COMMIT_OVERRIDE
feat(ui): location detail and scheduler status from the server's health reads
fix(server): the maintenance read returns how many grants were copied to an old-name view, not the GRANT statements
feat(ui): backfill a job or group over a cursor window from its launch form
feat(ui): upcoming schedule times and calendar coverage on the trigger page
END_COMMIT_OVERRIDE

…use Recall relations portably

SQL Server's render_create_function stripped a table function's SELECT and
wrapped it in BEGIN RETURN (...) END, which the engine rejects. A TABLE return
now renders RETURNS TABLE AS RETURN (<query>).

sqb recall schema --backend warehouse matched state relations with
LIKE '\_sqlbuild\_%' ESCAPE '\', which ClickHouse cannot parse. A prefix
comparison with SUBSTRING needs no escape in any dialect.
A native lint response can report that the engine does not parse the project's
dialect yet. Each such file now gets one L007 warning carrying the engine's
reason, instead of looking lint-clean. A non-string reason is rejected as an
invalid response.
…n and refuse WITH source expressions

render_create_schema doubled quotes only in the sys.schemas lookup, so a schema
name with a quote broke the EXEC string. render_merge now ends with the
semicolon SQL Server requires. A source expression starting with WITH cannot
sit in a derived table on SQL Server, so it now fails with A715 and a rewrite
hint instead of a warehouse syntax error.
… of SQL library probes

The unknown-function check (B101) asked the SQL library's parser which
built-in node each unaccepted call spelling becomes, and took DuckDB's
accepted names from the library's function catalogue. The check now reads
a table of the 41 rejected spellings, each with its argument count and the
spelling the dialect accepts. Every DuckDB row was confirmed unknown to
DuckDB 2.0.0. The call scan takes the analysis dialect name, so analysis
off the library can run it unchanged.

Findings are identical on every DuckDB and Snowflake query of the compiler
differential corpus and on every candidate spelling at 0 to 9 arguments.
The workspace no longer depends on the library's function-catalogue crate
directly; resolved features are unchanged.
…le and rules run

compile and rules run kept only selected Rule codes, so an unavailable dialect
looked clean there. L007 now passes through as a warning-severity Rule
diagnostic in compile and is left out of rules run's failing-finding count.
counts_toward_exit owns the exemption.
The plan and build rules gate failed on any finding, so an L007-only project
could not plan. Rule exceptions also validate every finding's code as a rule
code and rejected L007 with an invalid-lifecycle error. The gate now counts only
findings that count toward exit, and L007 passes through rule exceptions
unsuppressed. An end-to-end test replays a cached finding as L007 and as a rule
code through compile, rules run, plan and build.
…g issues

A same-run time ratio cannot see one store round trip per node: that cost is
linear. Tests now count the statements each task issues, and the wide listing
must read builds 100 nodes per statement: 17 statements for 1,000 nodes and 37
for 3,000 on SQLite and PostgreSQL, 1,008 with one node per statement. The
ratio check stays and now guards super-linear growth only.
The dynamic column contract proof parses pivot SQL with SQLQuack's shared
parser (DuckDB, MotherDuck, Snowflake) instead of Polyglot. DuckDB trees
match Polyglot's exactly; a Snowflake aggregate keeps its argument in a
call's argument list, which the proof now reads. Other dialects keep the
existing unsupported-dialect message.
Local scenario capture no longer asks Polyglot to read warehouse column
types. Postgres types go through sqlquack-syntax-postgres's type parser,
and Snowflake and BigQuery types through their SQLQuack cast-target
parse, behind one native function (parse_warehouse_type). DuckDB and
MotherDuck spellings pass through unchanged. Databricks nested types map
recursively to DuckDB's LIST, MAP and STRUCT, and a nested spelling that
cannot be mapped is refused with a named message instead of falling back
to JSON. Other types keep their integer width or fall back to VARCHAR.
SQL Server has no SQLQuack type parser, so its information_schema names
reached the generic fallback, which held datetime2, smalldatetime,
datetimeoffset and uniqueidentifier as VARCHAR. A SQL Server pre-mapper
now maps them to TIMESTAMP, TIMESTAMPTZ and UUID, bit to BOOLEAN, money
and smallmoney to exact decimals, and SQL Server's 8-byte float to
DOUBLE.

The fallback keeps 4-byte floats (FLOAT, FLOAT4, REAL) as FLOAT instead
of widening them to DOUBLE. A panic in the warehouse type parser now
surfaces as the ValueError capture already falls back on.
The Overview, where every sign-in lands, ran only on mock data, so the
server showed "Not available" there. It now reads the runs, checks,
catalog nodes, publications and platform problems the person can
already list: runs and outcomes in the last 24 hours, failed and
unresponsive runs, check outcomes, deployed models and this week's
model changes, and recent deploys.

The server has no project-wide build state, cost or group read yet, so
stale counts, cost and group status stay hidden rather than showing
zeros, as does the activity timeline. Recent deploys show the short
commit.
A person with view on only part of a target signed in to a page error,
because every listing the Overview reads needs view on the whole target.
The client now answers null for that refusal and the page explains it,
naming the target and linking the pages that do not list it. Other
errors still show as errors, and no partial counts are shown.
The partial-view message used whatever data the last load left, so
after switching location it named the new target while that target
loaded, and a failed load never showed its error. The message now
needs a settled, error-free load, and errors show in every state.
The Maintenance page ran only on mock data. It now reads the synced
maintenance history the person can list for the target: renames and
moves, the old-name views kept for them with each recorded step, and
clean-up archives and deletes. Each old-name view takes every fact from
the newest step that records it; a relation recorded without its schema
shows by its bare name.
The client check ran only as its own Verify step, so a stale client
passed make check-ci locally. check-ci now runs it, and Verify runs it
through check-ci after installing the packages.
The person page's role and account controls had no server calls behind
them. Giving a role, removing a manual one, and disabling or enabling a
person now use the server's existing admin endpoints, then read the
result back. The add control offers only what the server accepts:
built-in roles for every location, a location's own roles there, and
admin only for every location.

The page also hides its effective-access and access-checker panels and
the audit "Check this" links where the server has no read for them, and
long audit subjects wrap.
Each location row now has Test connection for people who may test that
location. The UI asks the location through the server's connection-test
request, then reads the result until the location answers or the
request expires, and shows whether it connected. The location reports
no reason, so a failure points to sqb debug in the location.
…th reads

The location page now opens from the server's target health, newest
snapshot and live problems: one process per reporting session, the
publish-time connection check, a failed reload shown as its health,
and open problems. The scheduler strip reports whether a server holds
the lease. Facts the server doesn't report (images, commits, deploy
policy, heartbeat, forwarding, problem history, tokens) stay hidden,
and the list counts open problems per location and no longer offers
the page to people who can't read the target's health.
…eturning them

The maintenance read returned each old-name view's copied GRANT
statements, which name warehouse roles, to anyone who may view the
target. It now returns only how many grants were copied, read the way
local sqb reads the stored list; the stored rows are unchanged.
People who may rewrite history can give a start and an end when they
run a job or group. Whole numbers on both ends send an integer window;
anything else goes as typed for the server to validate. Server error
bodies that aren't JSON, such as a request the route couldn't read, are
now shown as the server wrote them instead of as the bare status.
…r page

The trigger page now lists the server's next due time. For calendar
schedules it also lists the stored times from that point on, the last
stored time and when the location next works the calendar out. Later
cron times, the catch-up policy and the calendar's low-horizon warning
stay hidden until the server reports them.
@kvlonge kvlonge added the full-verify Run the full Verify matrix on this pull request label Nov 9, 2026 — with Amp for GitHub
@kvlonge
kvlonge enabled auto-merge (squash) November 9, 2026 04:46
@kvlonge
kvlonge merged commit 757a977 into main Nov 9, 2026
51 of 71 checks passed
@kvlonge
kvlonge deleted the feat/ui-locations-backfill-schedules branch November 9, 2026 05:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-verify Run the full Verify matrix on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant