Fleet overview N+1:
- InstanceResourceService gains a 30s TTL cache with single-flight
coalescing; the overview no longer fires six live upstream requests per
device on every render (plus the re-login storm), while the per-device
detail route probes live via force:true
Event journal becomes live:
- job terminal transitions (manual executions and the interrupted sweep)
now append to the journal, so /api/v1/events SSE feeds the frontend's
invalidation controller that was built but never received events
- journal pruning moves off the append hot path (was an unindexable
full-table json_extract scan per insert) onto the retention timer
Console auth hardening:
- scrypt upgraded from N=16384 to N=2^16 (OWASP interactive guidance);
a new password_kdf column records the derivation per row and legacy
hashes rehash transparently on the next successful login without
invalidating sessions (migration 18)
Legacy stack:
- instance URL validation blocks IPv4-compatible IPv6 after WHATWG
canonicalization (::a9fe:a9fe metadata, ::7f00:1 loopback slipped past)
- status polls cool down auto-login for 60s after a failed attempt so a
stale saved password cannot hammer the device into an account lockout
Build hygiene:
- web bundle splits app (410kB) from vendor (212kB) so framework code
stays cacheable across releases; stale root package-lock.json removed
(pnpm is the only lockfile)
- Add online update workflow with plan, backup and install states.
- Expose maintenance paths, component backup jobs and connection authorization modes.
- Align auth and automation screens with the fused control plane.
Deletion now follows the published contract: prepare returns the one-time
token and the console spends it on DELETE /api/v1/instances/:id with
If-Match, where the generic execute endpoint had been rejecting it as an
operation the safe transport cannot replay.
An online device is told to release its own binding first. A refusal keeps
the record and reports UNBIND_FAILED on the job item so the console can say
why the node is still there; a node that never answers a heartbeat is
forgotten locally.
Render the Hub feature set in the existing Animal Island styling: fleet
messages, notification centre, log centre, organisation panel, per-instance
device module panels and the settings backup, connection and maintenance
surfaces.
Adopt Portainer/Beszel-style fleet controls: prominent search, status
facet chips with counts, active filter chips, result count, and
primary-row sort/select. Keep advanced filters collapsed for secondary
facets. Tests and production dist rebuild for gateway 8788.
Collapse the redundant left workspace nav (overview is already the home
surface) and move Settings into the top bar. Hide placeholder `dev`
version badges. Restyle fleet cards with softer elevation, status
summary chips, hover sheen, and reduced-motion-safe entrance motion.
Drop the redundant advanced table so fleet stays resource-first cards.
Keep multi-select batch service/system restart via prepare→execute, card
restarts, overview system ops, and progressive fleet loading.