Response.ok(Map.of(...)).build() with class-level @Produces(TEXT_HTML)
caused Quarkus to call Map.toString() instead of the Jackson writer,
producing {key=value} output that r.json() can't parse. Explicitly
serialize with ObjectMapper and set Content-Type to application/json.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
Qute processes all {...} in .html files including <script> blocks.
JS function bodies like function(d) { return y(d); } were silently
eaten, causing a syntax error that killed the entire chart script.
Moving the rate chart IIFE into admin.js (static, Qute-never-touches)
fixes the root cause. Axes (Y: 0/50/100%, X: -6m/-3m/now) and
live % label now render correctly.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
Y-axis shows 0/50/100% of rate limit with grid lines.
X-axis shows -6m / -3m / now time labels.
Live label also shows current utilisation percentage.
Chart height increased to 96px to accommodate axes.
Cache-busted admin.js to v4.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
Quarkus defaults to Cache-Control: immutable, max-age=86400 for static files.
The immutable flag means browsers ignore hard-refresh and serve stale JS for 24h.
Fix: version query string on admin.js URLs, max-age=300 (5min), clear immutable-paths.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
Blink bug: agent visits were gated behind registrarLat != null — sandboxes
without a declared location showed no blinks at all. Now always enters the
sandbox branch when __D.sandboxId is present; registrar star still conditional.
Rate chart: rolling D3 area chart (72 buckets x 5s = 6min window) polls
GET /sandbox/{uuid}/poll every 5s, computes delta→rpm, renders with
CatmullRom curve. Red dashed limit line. Live value shown in stat box and
chart header. Poll endpoint added to DashboardResource (JSON, no HTML).
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
Qute cannot evaluate + and * as arithmetic operators at runtime even with
requireTypeSafeExpressions=false — it tries to look them up as map keys.
Pre-compute hasPrev/hasNext/displayPage/prevPage/nextPage in the resource.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>
requireTypeSafeExpressions=false allows {page+1} and (page+1)*size
in pagination conditions. JS template literals with ${days} replaced
with string concatenation to avoid Qute consuming the {days} token.
Co-Authored-By: Mira Rehfeld <noreply@anthropic.com>