12 KiB
2026-06-06 — GuruRMM ClientDetail reprioritization (beta) — RESUME NEEDED (reboot)
RESUME POINT: The ClientDetail redesign is BUILT, 3-way reviewed, MERGED to
main, and LIVE on rmm-beta (v0.2.51). Pick up at "Pending / Next" — the open items are: promote-to-prod decision, the "0 agents vs 16 offline" data-hygiene finding, a small agent-count/offline UX consistency fix, and the submodule-pointer bump. Nothing is half-finished mid-edit; the branch is merged and clean.
User
- User: Mike Swanson (mike)
- Machine: GURU-5070
- Role: admin
Session Summary
Reprioritized the GuruRMM dashboard ClientDetail page (the redesigned dashboard that's live on the
beta channel), driven by Mike's live critique of the Cascades of Tucson client page. Captured the page via
the CDP Chrome driver, then loaded full context on "yesterday's rebuild" (the 2026-06-05 multi-phase
dashboard redesign: 3-way audit → dashboard-redesign-SPEC.md → Phases 1-5, all merged to main and live
on beta). Confirmed the 5 UX "bugs" I initially cited were the pre-redesign main-site findings, not the
current beta — the redesign already fixed them.
Mike's ClientDetail critique: no priority ordering; Effective Policy should be collapsed (marker on
override); Code/#Sites/Created over-prominent as cards; Update Channel rarely used at client level; the
"Add Agent" button was dead (bounced to global /agents); Email Alerts exposed Graph integration creds
inline. We chatted through the mail-creds decision first: keep it per-client for now (plumbing
untouched — alert_email_settings.rs, secret encrypted + write-only via has_secret), demote to a
collapsed flyout, migrate to the Integration Catalog later (SPEC-005, still Proposed/not built).
Ran a 3-way design review (Gemini + Grok + Claude) on a consolidated brief → produced
clientdetail-reprio-SPEC-LOCKED.md. Mike decided the two forks: (1) Add-Agent client selector locked
when launched from ClientDetail (mutable only from a future global entry), (2) Credentials stays Tier-2
(no Tier-1 peek). Built in 3 phases, each via a Coding Agent and each 3-way code-reviewed: A extract
EnrollmentModal/MsiDownloadButton/install-urls (behavior-preserving), B new EnrollAgentModal
wrapper (client-locked + mandatory target-confirm gate) + fix the dead Add-Agent, C the ClientDetail
layout. Grok caught real scope-safety issues in B (lock bypass + enroll-handoff race) and Gemini caught an
email-form load race in C — all fixed and re-verified.
Merged redesign/clientdetail-reprio → main (3ff0da5); the webhook rebuilt beta to v0.2.51
(index-v7UH_Hfi.js). CDP-screenshotted the live Cascades ClientDetail (saved PNGs). The new exceptions
band immediately surfaced a real discrepancy — Cascades shows "0 agents" (site-based) but "16 offline"
(client_id-based); a cross-client check (AZ Computer Guru = 2 critical/4 offline) proved the band filter is
correct, so it's a data/definition mismatch, not a UI bug.
Key Decisions
- Mail creds: Option A (demote, keep per-client). Don't move to the Integration Catalog yet (SPEC-005 isn't built); collapse the creds on ClientDetail, leave the per-client plumbing + write-only secret intact, tag for SPEC-005 migration.
- Add-Agent client lock (the scope-safety call). Enrollment is per-site only; from ClientDetail the client is LOCKED, with a mandatory "Enrolling into Client X › Site Y (code ZZZ)" confirm gate before any installer is shown. The mutable-client picker is reserved for a future global "Add Agent" entry. Decided against Mike's original freely-changeable-client idea after both reviewers flagged it as a footgun + a context-spine violation. The component is still globalizable (build the prop), just locked from the client page.
- Lock made intrinsic (Grok): the modal itself never renders the mutable picker when invoked locked —
not relying on the caller passing a good value; call site passes the null-checked
client.id. - Confirmed target is snapshotted at confirm-click and EnrollmentModal renders from the snapshot (not a re-derived value) — closes a race where a sites-list change between confirm and render could strand the modal.
- "What's broken" band = v1 from available data (active alerts via
alertsApi.list({status,client_id})- offline agents from the shared
["agents"]fleet cache); full per-domain compliance rollup deferred to the SPEC-025 server endpoint (TODO left in code).
- offline agents from the shared
- Credentials Tier-2 only (Grok's position; Gemini wanted a Tier-1 peek — Mike chose Tier-2).
- GuruRMM session log → root
session-logs/(per File Placement; the submodule is a separate repo). Wiki Phase 3 skipped (root path); the guru-rmm wiki article can absorb this later via/wiki-compile project:guru-rmm --full.
Problems Encountered
- Initial staleness: I cited 5 UX bugs that were actually pre-redesign main-site findings. Resolved by
pulling the full redesign doc set (SPEC/decisions/session/nits/VERIFIED audit) from the submodule
main. - CDP screenshot inner-scroll quirk: the page scrolls in an inner
<main>(overflow-y-auto), sowindow.scrollTodid nothing; find the largest overflow element and set itsscrollTop. Top vs bottom captured by scrolling that element. - Grok Phase B REQUEST-CHANGES: lock bypass (nullable
lockedClientId→ fell back to global picker) + enroll-handoff desync race. Fixed: intrinsic lock (isClientLockedderived; nosetClientId; picker only in!isClientLocked; call siteclient.id) +confirmedSitesnapshot. - Gemini Phase C: removing EmailAlertsCard's
if (isLoading) return null(so the closed marker renders) exposed a form-overwrite race if a user expands+types mid-fetch. Fixed by guarding the expanded body withsettingsLoading(keep the marker, gate the form). Also memoized the band counts. - Beta curl 403: Cloudflare bot-blocks non-browser UAs; used the CDP browser (authenticated, real) to verify/screenshot instead. Build status confirmed via SSH to the build log on .30.
Configuration Changes
All in the gururmm submodule (projects/msp-tools/guru-rmm), merged to main:
- NEW
dashboard/src/components/EnrollmentModal.tsx(extracted from SiteDetail, Phase A) - NEW
dashboard/src/components/MsiDownloadButton.tsx(Phase A) - NEW
dashboard/src/lib/install-urls.ts(Phase A — BASE_URL vs API_BASE_URL, getEnrollUrls/getMsiInstallerUrl/cleanup consts) - NEW
dashboard/src/components/EnrollAgentModal.tsx(Phase B — locked-client enroll wrapper + confirm gate) - MOD
dashboard/src/pages/SiteDetail.tsx(consume extracted modal; -339 lines) - MOD
dashboard/src/pages/ClientDetail.tsx(Phase C full layout rewrite; +CopyButton/CollapsibleCard/ClientExceptionsBand)
Commits (gururmm): cfde337 (A) → dc5c849 (B) → 83b876b (C) → merge 3ff0da5 on main. CI bump be5ddc9 (v0.2.51).
Reference docs (machine-local, gitignored tmp): .claude/tmp/redesign-docs/ — clientdetail-reprio-SPEC-LOCKED.md,
clientdetail-reprioritization-brief.md, review-out/ (design review), phaseA|B|C/ (per-phase reviews).
Screenshots: .claude/tmp/cdp/cascades-NEW-top.png, cascades-NEW-bottom.png (live beta render).
ClaudeTools repo: this session log only. Submodule pointer NOT bumped (lagging main, expected).
Credentials & Secrets
- None newly discovered/created this session. No secrets typed into the UI (password rule honored, even via CDP).
- SSH
guru@172.16.3.30works key-based for read commands from GURU-5070. Sudo (needed for prod promote) is in vaultinfrastructure/gururmm-server.sops.yaml(credentials...password).
Infrastructure & Servers
- Beta: https://rmm-beta.azcomputerguru.com — dashboard beta channel; auto-builds from gururmm
mainon push (webhook →build-dashboard.sh), deploys to/var/www/gururmm/dashboard-betaon 172.16.3.30. BETA banner; does NOT affect prod. Build log/var/log/gururmm-build-dashboard.log. Current: v0.2.51. - Prod: https://rmm.azcomputerguru.com — promote-only via
sudo /opt/gururmm/promote-dashboard.sh --confirm(do NOT hand-rsync). Currently still the pre-this-change dashboard until promoted. - CDP driver:
.claude/scripts/cdp.py(launch/status/nav/shot/click/type/key/eval), port 9222, profile~/.claude/cdp-chrome-profile(authenticated to beta), screenshots.claude/tmp/cdp/. - Gitea (gururmm repo): internal
http://172.16.3.20:3000/azcomputerguru/gururmm.git.
Commands & Outputs
# beta build status / fingerprint (SSH, key-based read)
ssh guru@172.16.3.30 'tail -8 /var/log/gururmm-build-dashboard.log; grep -oE "assets/index-[A-Za-z0-9_-]+\.(js|css)" /var/www/gururmm/dashboard-beta/index.html'
# -> "Dashboard beta build complete: v0.2.51 (be5ddc9...)"; assets/index-v7UH_Hfi.js
# CDP: screenshot the live page the user is on
py .claude/scripts/cdp.py status # shows active tab URL
py .claude/scripts/cdp.py nav "<url>"
py .claude/scripts/cdp.py eval "(()=>{const els=[...document.querySelectorAll('*')].filter(e=>e.scrollHeight-e.clientHeight>40 && /auto|scroll/.test(getComputedStyle(e).overflowY)); els.sort((a,b)=>b.scrollHeight-a.scrollHeight); const m=els[0]; window.__sc=m; m.scrollTop=0; return {sh:m.scrollHeight};})()"
py .claude/scripts/cdp.py shot .claude/tmp/cdp/out.png
# band cross-check (per-client filter verified): AZ Computer Guru = "2 critical · 4 offline" vs Cascades "16 offline"
Pending / Incomplete Tasks (RESUME HERE)
- Promote beta → prod? When happy:
ssh guru@172.16.3.30thensudo /opt/gururmm/promote-dashboard.sh --confirm(sudo pw in vault). NOT done — awaiting Mike's go. - Data-hygiene finding (real): Cascades shows "0 agents" (sum of site
agent_count) but the exceptions band shows "16 offline" (agents withclient_id=Cascades, any site). Band filter is CORRECT (cross-checked). So ~16 offline agents are tagged to Cascades but not under its single (0-agent) site — likely siteless/orphaned agents carryingclient_id. Investigate (orphans? stalesite_id? cleanup). This is a genuine data issue the new band exposed. - Small UX consistency fix: the strip's agent count (site-based) and the band's offline (client_id-based) use different denominators → a user can see "0 agents · 16 offline." Align both to the same source (likely client_id-based) so they're consistent. Small ClientDetail change; would go through the same branch→beta flow.
- Bump the claudetools submodule pointer for gururmm →
3ff0da5/current main, whenever desired (currently lagging — expected per CLAUDE.md; not required). - Continue iterating ClientDetail (e.g., the "what's broken" band can grow into the full compliance rollup once the SPEC-025 endpoint exists), or move to other pages.
- (Separate threads from the prior 2026-06-05 session, tracked in coord todos, NOT this resume: GuruConnect remediation P0-P5 + issues #10-22; multi-session git isolation L2/L3
e84ac521.)
Reference Information
- Beta: https://rmm-beta.azcomputerguru.com · Prod: https://rmm.azcomputerguru.com
- Cascades ClientDetail:
/clients/42e1b0e3-f8b7-4fc5-86bd-06bdbb073b7f - gururmm commits: A
cfde337, Bdc5c849, C83b876b, merge3ff0da5, CI bumpbe5ddc9(v0.2.51) - Branch (merged):
redesign/clientdetail-reprio - Locked spec:
.claude/tmp/redesign-docs/clientdetail-reprio-SPEC-LOCKED.md - Reviews:
.claude/tmp/redesign-docs/{review-out,phaseA,phaseB,phaseC}/ - Live screenshots:
.claude/tmp/cdp/cascades-NEW-{top,bottom}.png - Original redesign docs (in submodule
main):docs/dashboard-redesign-{SPEC,decisions,session}.md,docs/specs/SPEC-005-integration-catalog.md - Promote prod:
sudo /opt/gururmm/promote-dashboard.sh --confirmon 172.16.3.30