supporthub-api's 010-identity-auth (built after this spec's initial approval) established that agent/admin login is supporthub-api's own authentication, never SaaS-delegated — this spec and the project constitution's Principle I still assumed the opposite. Adds User Story 0 (sign-in, P1) and FR-000/SC-006 for the login screen and session-guard this frontend must now own, and rewords FR-011/the affected Edge Case to reference the supporthub-api session role instead of a "SaaS-provided role." Only end-customer identity remains SaaS-delegated. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
22 KiB
Feature Specification: Agent and Admin UI
Feature Branch: 001-agent-admin-ui
Created: 2026-09-07
Status: Draft
Input: User description: "Phase 10 of supporthub-api's docs/10-implementation-roadmap.md: Agent workspace (continues from AI context), admin configuration surfaces for every configurable subsystem above (SaaS/products, product knowledge, AI support, ticketing, support organization, orchestration/assignment, SLA/escalation, problem resolution) — built against the existing (support)/(admin) route groups already scaffolded in this project, consuming supporthub-api's now-complete backend."
User Scenarios & Testing (mandatory)
User Story 0 - An agent or admin signs in (Priority: P1)
Before any other story in this feature can matter, an agent or admin needs a way to actually
get a session: a sign-in screen that calls supporthub-api's own login (010-identity-auth,
POST /auth/login), and a portal that redirects to it — rather than rendering with absent or
default data — whenever no valid session exists. This did not exist as a requirement when this
spec was first drafted, because agent/admin identity was mistakenly assumed to arrive the same
way customer identity does (pre-authenticated, delegated from the parent SaaS host, needing no
frontend-owned login screen at all). supporthub-api's 010-identity-auth feature established that
agent/admin identity is supporthub-api's own, separate authentication — so unlike the customer
portal, this frontend must own a real sign-in flow for the (support)/(admin) portals.
Why this priority: Nothing in User Stories 1-7 has a session to act as, or a role to gate on, without this. It is more foundational than US1 itself.
Independent Test: With no existing session, navigate to any (support) or (admin) URL;
confirm a redirect to sign-in; sign in with a valid agent account; confirm landing on the agent
dashboard with a session that subsequent API calls carry.
Acceptance Scenarios:
- Given no session, When a
(support)or(admin)URL is requested directly, Then the user is redirected to a sign-in screen instead of the portal rendering with absent or default data. - Given the sign-in screen, When correct credentials are submitted, Then the
resulting session is stored and the user lands on the role-appropriate landing page (agent
dashboard for
AGENT, admin dashboard forADMIN). - Given the sign-in screen, When incorrect credentials are submitted, Then the backend's own identical-failure response (010's FR-002) is shown as one generic error, never a hint about which part was wrong.
- Given an active session that supporthub-api no longer honors (expired, revoked, or the
account deactivated — 010's own
GET /auth/mere-validation), When the next API call is made, Then the user is signed out and redirected to sign-in, not left looking at stale data or a silent failure. - Given a signed-in session, When the user explicitly signs out, Then
supporthub-api's own logout (010's
POST /auth/logout) is called and the session is cleared locally, redirecting to sign-in.
User Story 1 - An agent sees and opens their assigned work (Priority: P1)
A support agent logs into the workspace and immediately sees the tickets currently assigned to them — enough context (customer, product, priority, SLA status, age) to decide what to work on next — and can open any one of them to see its full detail.
Why this priority: Nothing else in the agent workspace matters if an agent can't even see what they're supposed to be working on. This is the entry point for every other agent-facing story.
Independent Test: Sign in as an agent with tickets assigned via the backend's own assignment engine; confirm the dashboard lists exactly those tickets with correct, live status/ priority/SLA information, and that opening one navigates to its detail view.
Acceptance Scenarios:
- Given an agent with two tickets currently assigned to them, When they open the dashboard, Then both tickets appear, each showing customer/product, priority, current status, and time remaining (or overdue) against its SLA.
- Given an agent with zero assigned tickets, When they open the dashboard, Then it clearly shows an empty state, never a loading spinner that never resolves or a blank screen.
- Given a ticket reassigned away from the agent while they're viewing the dashboard, When the dashboard's data next refreshes, Then that ticket no longer appears in their list.
User Story 2 - An agent works a ticket end-to-end (Priority: P1)
From a ticket's detail view, an agent can read its full message history (customer, AI, and prior agent messages, with internal notes visible only to agents), post a new message or internal note, and move the ticket through its lifecycle — recording an investigation, root cause, proposed and implemented solution, its verification, and finally a resolution — using the same workflow doc 04 defines and supporthub-api's problem-resolution feature already enforces.
Why this priority: This is the actual value the whole workspace exists to deliver — an agent resolving a real customer problem. Every backend capability from tickets through problem resolution has no user-facing path without this.
Independent Test: Open an assigned ticket already in HUMAN_ESCALATION/IN_PROGRESS; post
a message; record an investigation, root cause, solution, implementation, and successful
verification; record a resolution; confirm the ticket reaches RESOLUTION_PENDING_CUSTOMER and
every record is visible on the same screen afterward.
Acceptance Scenarios:
- Given a ticket's detail view, When an agent posts a customer-visible message, Then it appears in the thread in the correct visibility styling, distinct from an internal note.
- Given a ticket with no investigation on file yet, When the agent tries to record a root cause first, Then the UI reflects the backend's own rejection (409) with a clear message, never a silent failure or a client-side guess that lets the action appear to succeed.
- Given a ticket whose problem now has a successfully verified solution, When the agent records a resolution, Then the ticket's displayed status updates to "Pending Customer Confirmation" without a manual page reload.
- Given a solution verification recorded as failed, When the agent chooses to escalate rather than re-investigate, Then the ticket's status and assignment update to reflect the automatic re-assignment supporthub-api's orchestration already performs.
User Story 3 - An admin sets up the support organization (Priority: P1)
An admin creates teams, adds agents to them, assigns agent skills, and builds the support hierarchy (nodes, scope, required skills, assignment strategy) that orchestration resolves against — all from configuration screens, never a database script.
Why this priority: Nothing can be assigned or routed — and therefore User Stories 1-2 have nothing to show — until a support organization actually exists. This is the necessary precondition for the entire agent workspace to have real data.
Independent Test: Create a team, add an agent to it, grant the agent a skill, create a hierarchy node scoped to a product with that skill required; confirm the same data is visible and editable from the admin screens afterward, matching exactly what the backend's own read endpoints return.
Acceptance Scenarios:
- Given the teams admin screen, When an admin creates a team and adds an agent, Then both are immediately visible in the roster.
- Given the hierarchy admin screen, When an admin creates a node with a product scope, required skills, and an assignment strategy, Then it's retrievable exactly as configured and appears in the hierarchy tree in its correct position.
- Given an attempt to create a hierarchy node that would make itself its own ancestor, When it's submitted, Then the UI surfaces the backend's own cycle-detection rejection clearly, not a generic error.
User Story 4 - An admin configures SLA policies and business calendars (Priority: P2)
An admin defines business calendars (working hours, holidays) and SLA policies (response/ resolution time limits, scoped to product/category/priority, referencing a calendar) from configuration screens.
Why this priority: Depends on User Story 3 existing (a hierarchy/product context to scope policies against). SLA visibility (User Story 6) and the whole point of Phase 8's backend work have no admin-facing configuration path without this.
Independent Test: Create a business calendar with working hours and a holiday, then an SLA policy referencing it scoped to a specific product; confirm both are retrievable and editable exactly as configured.
Acceptance Scenarios:
- Given the business calendar screen, When an admin defines working hours per weekday and adds a holiday, Then both are saved and displayed back exactly as entered.
- Given the SLA policy screen, When an admin creates a policy scoped to a product with a calendar reference, Then it appears in the policy list with its scope and time limits visible at a glance.
- Given two policies that could both apply to the same context, When viewing either in the list, Then the UI indicates which one is more specific (mirrors the backend's own most-specific-match resolution), so an admin isn't left guessing which one actually applies.
User Story 5 - An admin configures escalation policies and rules (Priority: P2)
An admin defines escalation policies and rules — trigger type, target hierarchy node, and notification target — from configuration screens, and can manually escalate a specific ticket to a specific node when needed.
Why this priority: Depends on User Story 3 (a hierarchy to target) and pairs with User Story 4 (the SLA breaches that trigger escalation). Without this, escalation stays entirely invisible and unconfigurable outside direct API calls.
Independent Test: Create an escalation policy and a rule for resolution_breach targeting
a specific node; confirm it's retrievable and editable, and that manually escalating a ticket
from its detail view (User Story 2) creates a visible escalation event.
Acceptance Scenarios:
- Given the escalation policy screen, When an admin creates a rule with a trigger type and target node, Then it appears in the rule list with both clearly shown.
- Given a ticket's detail view, When an agent manually escalates it to a specific node with a reason, Then the ticket's assignment updates and the escalation appears in that ticket's own history.
- Given a manual escalation targeting a node that doesn't exist (a stale reference), When it's attempted, Then the UI surfaces the rejection clearly rather than showing a false success.
User Story 6 - Agents and admins see SLA and escalation status at a glance (Priority: P2)
A dedicated view shows every ticket's SLA status (running/paused/warning/breached) and a separate view shows recent escalation events — both filterable, both reflecting live backend state rather than a snapshot that goes stale.
Why this priority: Depends on User Stories 4-5 existing (something to actually monitor). This is what makes SLA/escalation a managed, visible commitment rather than something only ever inspected ticket-by-ticket.
Independent Test: With a mix of running, paused, and breached SLA runs across several tickets, confirm the SLA monitor view correctly groups/filters by status and each entry links to its ticket.
Acceptance Scenarios:
- Given tickets with SLA runs in different states, When viewing the SLA monitor, Then each is shown with its correct status and due/breached time, filterable by status.
- Given a recent automatic escalation, When viewing the escalation matrix, Then it appears with the triggering reason, the rule (if automatic) or actor (if manual), and the resulting target node.
User Story 7 - An admin manages the product catalog and knowledge base governance (Priority: P3)
An admin views and manages products/categories (as already integrated via supporthub-api) and reviews/publishes knowledge base entries (known issues, FAQs, resolution procedures) from configuration screens.
Why this priority: Lower priority than the operational stories above — a product/knowledge catalog changes far less often day-to-day than tickets, SLAs, or escalations, and the backend for both already has a stable read/write surface this can be built against whenever capacity allows.
Independent Test: View the product list with their integration status; open a knowledge entry, change its status (draft/published/unpublished), and confirm the change is reflected immediately.
Acceptance Scenarios:
- Given the products admin screen, When an admin views the list, Then each product's integration status (active/suspended) is visible.
- Given the knowledge governance screen, When an admin publishes a draft entry,
Then its status updates and it becomes visible whichever way the entry's own
categoryScope/effectiveDaterules mean it should be.
Edge Cases
- What happens if the backend API is unreachable when a screen loads? Every data view MUST show a clear error state distinct from "no data" — never an indefinitely spinning loader or a silently empty list that looks like a legitimate zero-results state.
- What happens if two agents have the same ticket's detail view open and one changes its status? The other agent's view MUST reflect the change on its next data refresh — this feature does not attempt real-time push sync (see Assumptions).
- What happens when an admin's action is rejected by a business rule the backend enforces (e.g. a cycle in the hierarchy, a solution proposed with no root cause on file)? The UI MUST surface the backend's own rejection reason, never mask it behind a generic "something went wrong."
- What happens if an agent's supporthub-api session role doesn't include admin access but they navigate directly to an admin URL? The admin portal MUST NOT render for that identity — this is an enforcement of Principle I/III, not a cosmetic navigation-hiding concern.
- What happens if no supporthub-api session exists at all (no token, an expired token, or a
token supporthub-api's own
/auth/meno longer honors) and a support/admin URL is requested? The user MUST be redirected to a sign-in screen rather than the portal rendering with absent or default data.
Requirements (mandatory)
Functional Requirements
- FR-000: The system MUST provide a sign-in screen for agents/admins that authenticates
against supporthub-api's own login (010-identity-auth), MUST redirect any unauthenticated
request for a
(support)/(admin)URL to it, and MUST sign a user out (clearing the local session and redirecting to sign-in) the moment supporthub-api no longer honors their session. - FR-001: The system MUST show an agent a dashboard of tickets currently assigned to them, with customer/product, priority, status, and SLA time-remaining/overdue visible without opening the ticket.
- FR-002: The system MUST show a ticket's full message history, distinguishing customer- visible messages from internal notes, and MUST let an agent post either.
- FR-003: The system MUST let an agent record an investigation, root cause, solution, implementation, verification, and resolution against a ticket's problem, in that order, surfacing the backend's own precondition rejections rather than allowing an invalid order client-side.
- FR-004: The system MUST let an agent transition a ticket's status (including manual escalation to a specific hierarchy node) and reflect the resulting state without a manual page reload.
- FR-005: The system MUST let an admin create, view, and edit teams, agents, agent skills, and hierarchy nodes (including scope, required skills, and assignment strategy).
- FR-006: The system MUST let an admin create, view, and edit business calendars (working hours, holidays) and SLA policies (time limits, scope, calendar reference).
- FR-007: The system MUST let an admin create, view, and edit escalation policies and rules (trigger type, target node, notification target).
- FR-008: The system MUST provide an SLA status view across tickets, filterable by status, and an escalation history view showing recent automatic and manual escalations.
- FR-009: The system MUST let an admin view the product catalog (with integration status) and manage knowledge base entry publication status.
- FR-010: Every screen that calls a backend endpoint MUST distinguish a loading state, an empty-result state, and an error state — never conflating any two of them.
- FR-011: The admin portal MUST NOT render for an identity whose supporthub-api session role
is not
ADMIN, regardless of what URL is requested directly. - FR-012: No screen in this feature MUST compute or override a business decision the backend already owns (ticket transition validity, SLA due dates, most-specific-policy resolution, escalation rule matching) — every such decision is read from, or requested of, the API, never derived independently in the UI.
Key Entities
- Sign-In / Session: The agent/admin's supporthub-api-issued session (010-identity-auth) — the token, the identity it carries, and the redirect-to-sign-in behavior when it's absent or no longer valid.
- Agent Dashboard: The agent's own view of currently-assigned tickets, summarizing status relevant to deciding what to work on next.
- Ticket Workbench: The full detail view of one ticket — messages, lifecycle status, problem-resolution records, and available actions.
- Support Organization Editor: The admin surface over teams, agents, skills, and hierarchy.
- SLA & Calendar Configuration: The admin surface over business calendars and SLA policies.
- Escalation Configuration: The admin surface over escalation policies, rules, and the manual-escalation action available from a ticket.
- Monitoring Views: The SLA status and escalation history views, read-only aggregations across tickets.
- Catalog & Knowledge Governance: The lower-priority admin surface over products and knowledge base entries.
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: An agent can go from opening the dashboard to posting a message on an assigned ticket in under 15 seconds of active use (excluding backend response time).
- SC-002: 100% of business-rule rejections from the backend (409/400 responses) are shown to the user with the backend's own reason, never a generic failure message.
- SC-003: 100% of screens in this feature correctly distinguish loading, empty, and error states, verified by simulating each condition against a real backend.
- SC-004: An admin can create a complete, usable support organization (one team, one agent with a skill, one hierarchy node) in under 5 minutes without consulting API documentation.
- SC-005: 0% of admin-portal routes render their content for a non-admin identity, verified by attempting direct navigation as a customer- or agent-only identity.
- SC-006: 100% of direct navigations to a
(support)/(admin)URL with no valid session redirect to sign-in, and 0% render the portal with absent or default data instead.
Assumptions
- This feature does not include the
(public)/(customer)portals — those serve a different audience (end customers) and aren't named in Phase 10's own roadmap line ("Agent workspace... admin configuration surfaces"); they remain future scope for a later feature. - No real-time push sync (WebSocket) is required for this feature — every view refetches on
a normal interaction cadence (navigation, an explicit refresh action, or a short polling
interval where a screen's own staleness would otherwise be misleading, e.g. the SLA monitor).
lib/websocketis scaffolded in this project but wiring it up is out of scope here; Edge Cases' "two agents, one ticket" scenario is handled by refetch-on-navigation, not push. - Analytics/reporting dashboards, the compliance audit-log viewer, and platform-wide settings screens are out of scope for this feature — they're lower-value, lower-frequency admin surfaces than the operational and configuration screens above, and can be their own follow-up feature once this one's scaffold (typed API client, portal layout, admin table/ form patterns) exists to build them against quickly.
- AI confidence policy administration (005's
AIConfidencePolicy) is out of scope for this feature — it's a narrower, less frequently touched configuration surface than support org/ SLA/escalation; deferred to a follow-up rather than expanding this already-large feature further. - Role/permission enforcement (FR-011) reads the role on the supporthub-api session
(
ADMIN/AGENT, fromPOST /auth/loginandGET /auth/me) — this feature does not define what roles exist or how they're granted (Principle I, supporthub-api's own 010-identity-auth); it only gates rendering on whatever role value that session already carries. - Account provisioning (who gets an agent/admin account, and with what role) is out of
scope — supporthub-api's 010-identity-auth already provides
POST /admin/usersfor an admin to provision new accounts; this feature's own admin screens may expose it later, but User Story 0 only needs to consume an existing account's login, not manage account creation.