Files
member-console/status/operator-ux.md
Christian Galo 1012a01028 Add Phase A operator UX walkthrough evidence
Deterministic capture of the operator panel: per-slug evidence
(screenshots, console/network dumps, a11y and tab-order data) stored
under docs/operator-ux-walkthrough-evidence. Add Phase A task briefing
and update status files to mark 7a progress and note downstream issues
2026-05-11 10:55:14 -05:00

9.2 KiB
Raw Blame History

Operator UX Foundation (M7)

Working journal for the Milestone 7 effort. Research findings, IA sketches, design-system decisions, audit results, and convention drift land here as they happen. Authoritative milestone tracking lives in milestones.md; this file is the long-form companion.

Why This Milestone Exists

The operator panel grew organically across M1M6 as new tabs were added per capability. The "six tabs" framing undercounts what is actually there — Persons, Organizations, Sites, Org Types, Products (with nested Prices), Entitlement Sets (with nested Rules), Plan Ladders (with nested Tiers), Grants, and four Billing surfaces (accounts, subscriptions, invoices, payments) are all distinct surfaces flattened into a single tab strip. The seams are visible:

  • Cross-tab state synced via custom HTMX events (productMutation, entitlementMutation, planLadderMutation) — fragile and easy to forget when adding a new tab.
  • Stale-dropdown bugs recur (e.g., creating a plan ladder doesn't refresh the Org Types default-plan dropdown until the page is refreshed). The symptom was patched via the HX-Trigger event mesh; the architectural cause (flat tab IA + DOM-cached revealed partials) is what M7 retires.
  • URL state shoehorned into a ?tab= query param; no real route per capability. Specific entities (an org, a product, a ladder, a grant) never appear in URLs — nothing is bookmarkable, shareable, or reload-stable.
  • data-switch-tab attribute pattern + operator-tabs.js to make cross-tab navigation work under strict CSP.
  • Form, confirmation, and feedback patterns vary tab to tab — there's no shared design vocabulary.
  • Accessibility has not been audited; keyboard navigation is patchy.
  • FedWiki sites sit at the same IA level as catalog/runtime tabs, entrenching the assumption that FedWiki is the only integration the member-console will ever have. NextCloud and Discourse are on the horizon; the IA must not bake FedWiki in.

These are SPA-pattern symptoms in a tool whose mental model is a navigation hierarchy with three orthogonal axes — catalog (org types, products, entitlement sets, plan ladders), runtime (per-org enrollment and billing), and integrations (FedWiki today; more later). M7 reshapes the panel to match that grain. The integration/extension contract itself is its own scope (proposed M10); M7 only needs to not entrench the FedWiki-first-class assumption.

Phase Tracker

See milestones.md for the canonical scope. Brief status here:

Phase Status Notes
7a — Operator surface inventory & walkthrough In progress Reframed into three sub-tracks. 7a.1 Code archaeology — done 2026-05-08; docs/operator-ux-research.md. Surfaced four cross-cutting findings handed to 7b: catalog/runtime/integrations as the three IA axes, the per-org composite view as the missing route, integrations carve-out into proposed M10, and read-only-operator role considerations. 7a.2 Deterministic walkthrough capture — not started; chrome-devtools-mcp single pass over every operator screen; outputs to docs/operator-ux-walkthrough-evidence/. 7a.3 Subjective walkthrough (multi-LLM) — not started; briefing doc docs/operator-ux-walkthrough-task.md + per-agent outputs docs/operator-ux-walkthroughs/{agent-id}.md.
7b — Information architecture Ready to start OpenSpec change operator-ia will land alongside docs. Inputs from 7a: route-surface inventory, dependency direction (catalog → runtime), hot paths (1) per-org composite view, (2) per-org grant adjustment, (3) catalog reconfigure. Must reserve real estate for an Integrations section without designing it (see M10).
7c — Design system foundation Blocked by 7a
7d — SPA → MPA conversion Blocked by 7b, 7c OpenSpec change operator-mpa-conversion (BREAKING ?tab=)
7e — Form & action patterns Blocked by 7c
7f — Audit & docs Blocked by 7d, 7e

Personas (refined in 7a)

  • Operator (primary): internal staff administering people, orgs, plans, entitlements, and billing. Integrations (FedWiki today) are administered through a separate axis — see "Why This Milestone Exists" above. Frequency varies sharply by task: runtime work (enrollment lookups, billing reconciliation) is potentially daily; catalog work (creating products, editing ladders) is weeks-to-months apart. Needs efficiency on hot paths and recoverability on cold paths.
  • Read-only operator: someone who needs to inspect operator state without being able to mutate. Useful for support handoffs and for keeping principle-of-least-authority intact when the team grows past one person. Same screens, action affordances suppressed.
  • Hard constraint on 7b: URL structure must not bake the operator role. A read-only operator viewing /operator/organizations/{orgID} and a full operator viewing the same URL land on the same route — what differs is which actions render.

Design Principles (placeholder — fleshed out in 7c)

Working list, refined as research and design-system work proceeds:

  1. URL is the source of truth. Every operator capability is bookmarkable, refreshable, shareable.
  2. Frequency-weighted IA. High-frequency tasks get top-level placement; rare tasks live deeper without cluttering the surface.
  3. No surprise destruction. Destructive actions are confirmed; confirmation copy names the affected entities; nothing is hidden in dropdowns.
  4. Server-rendered first. HTMX enhances; JavaScript is for the small set of interactions that genuinely need it. Strict CSP stays strict.
  5. Accessible by default. Keyboard parity with mouse; color is not the sole channel; WCAG 2.1 AA is the floor.
  6. Conventions over configuration. Forms, tables, modals, and feedback follow shared patterns so operators learn the system once.

7a.1 Findings Handed to Downstream Phases

From the code-archaeology sub-track only. 7a.2 (deterministic capture) and 7a.3 (multi-LLM walkthrough) will append their own findings sections when they land. Full 7a.1 detail in docs/operator-ux-research.md.

  • The IA has three axes, not one tab strip. Catalog (org types, products, entitlement sets, plan ladders) → runtime (per-org enrollment + billing) is one-way and dependency-shaped. Integrations is orthogonal to both. 7b owns the IA call but starts from this finding.
  • The per-org composite view is the single biggest unmet need. "What's the state of org X?" is a daily lookup that today requires threading Organizations → click → Billing tab → scan. A bookmarkable /operator/organizations/{orgID} route is the highest-leverage screen for 7b.
  • Two grant paths are intentional, not accidental. Plan grants (ladder-aware, via IssueGrant) and non-plan grants (legacy, via CreateGrant) handle different product_type values. 7b should keep both but make the distinction visible — and consider co-locating them on the per-org page.
  • Tier rank reorder is the highest-criticality recurring catalog action. Sole-writer invariants in entitlements.Transition; per-affected-org pool_provision_transitions audit row. Worth the most-careful screen design in M7. 7e should require cascade-preview on this and on entitlement-set / product edits at Crit ≥ 4.
  • Product retirement, not delete. Local products are 1:1 mapped to Stripe via stripe.product_mappings; M6a already plans lifecycle_status (draft/published/retired). 7b/7c surface the Stripe mapping; 7e exposes "retire" rather than "delete." See status/issues.md "Product retirement and Stripe-mapping visibility in operator UI."
  • Org type CRUD deferred. Schema supports it; UI deliberately doesn't expose it. Will need to grow when non-personal org types arrive. See status/issues.md "Org type CRUD when non-personal types arrive."
  • Integrations carve-out (proposed M10). FedWiki must not be at the same IA level as Products / Org Types / Billing. 7b reserves the URL real estate (/operator/integrations/... or similar); the extension contract itself is M10's job. See status/issues.md "Integration / extension architecture (and operator IA placement)" and the proposed M10 in milestones.md.
  • No usage telemetry exists. All frequency / criticality annotations in 7a.1 are code-introspection estimates. An action-counter middleware spike was considered and deferred — folded into proposed M11 phase 11b (auto-instrumentation middleware) since there is no immediate consumer between now and M11. 7b should not block on telemetry; if any IA decision ends up load-bearing on a specific cell, revisit then.

Foundations Reused Downstream

The artifacts below are explicit deliverables of M7 and prerequisites for member-side UX work in M8/M9:

  • docs/operator-ux-research.md — methodology and findings reusable for member persona work.
  • docs/operator-ia.md — IA principles transferable to member panel.
  • docs/design-system.md — component primitives, tokens, accessibility baseline used everywhere.
  • docs/operator-ux-conventions.md — form/action/confirm patterns adopted by member flows.