Commit Graph

2 Commits

Author SHA1 Message Date
96f9c0ab45 feat(dashboard): operator removal UI for stale machines/sessions (SPEC-004 Task 5)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m13s
Build and Test / Build Server (Linux) (push) Successful in 11m21s
Build and Test / Security Audit (push) Successful in 4m12s
Build and Test / Build Summary (push) Successful in 11s
Admin-only per-row Remove + multi-select bulk removal on the machines view, plus
per-row purge Remove on the sessions view, wired to the Task-5 admin API
(DELETE /api/machines|sessions/:id?purge=true, POST /api/machines/bulk-remove).
Confirm modals (danger-styled, focus-trapped), TanStack refetch so purged rows
leave the console, structured ApiError surfacing, honest partial-bulk summary,
and admin-gating via useAuth().isAdmin as defense-in-depth over the server 403.
Replaces the legacy all-user delete trigger. typecheck/lint/build clean.

Implements specs/v2-stable-identity/plan.md Task 5 (dashboard portion).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:14:49 -07:00
6ecb937eb6 feat(dashboard): GuruConnect v2 Sessions view (pass 2)
All checks were successful
Build and Test / Build Agent (Windows) (push) Successful in 7m9s
Build and Test / Build Server (Linux) (push) Successful in 10m41s
Build and Test / Security Audit (push) Successful in 4m25s
Build and Test / Build Summary (push) Successful in 10s
Active-sessions table with consent-state badges, viewer-token Join,
and disconnect, built on the v2 session API and existing UI primitives.

- Sessions table: machine, mode (managed/attended), consent badge
  (granted/pending+pulse/denied/not_required), viewers, started,
  duration, status. Sticky header, skeleton load, empty/error states.
- Join action mints a session-scoped viewer token
  (POST /api/sessions/:id/viewer-token) and reveals it with the
  /ws/viewer relay URL and copy buttons. The static viewer.html is
  intentionally not targeted: it sends the raw login JWT, which the v2
  viewer plane rejects. In-dashboard web viewer ships in a later pass.
- Authz split mirrors the server mint gate: admin or control permission
  gets Control; view permission gets View only; neither hides the action.
  Server remains authoritative; the minted token carries the signed
  access claim.
- Disconnect via confirm dialog (DELETE /api/sessions/:id), invalidates
  the sessions query. List polls every 8s so consent transitions surface.

Passed Code Review (no blockers) and local gates (tsc/lint/build green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:12:04 -07:00