Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# 15 — User-facing Support Center UI
|
||||
|
||||
**Agent:** 15/20
|
||||
**Date:** 2026-08-05
|
||||
**Scope:** Customer `/support` surfaces — list, create, thread, CSAT rating.
|
||||
**Contract:** [11-support-design.md](./11-support-design.md) §5 / §9.1 (`POST /api/support/tickets/{id}/csat`).
|
||||
|
||||
---
|
||||
|
||||
## Outcome
|
||||
|
||||
Polished, accessible user Support Center that:
|
||||
|
||||
1. Lists the caller’s tickets with status chips + URL `?status=` persistence.
|
||||
2. Creates tickets (subject, category, priority, body) when `support.ticket_create` allows.
|
||||
3. Shows a threaded conversation with quiet polling (visibility-aware).
|
||||
4. Prompts CSAT (1–5 + optional comment) when status is `resolved` or `closed` and no rating yet.
|
||||
5. Respects plan feature keys via existing `PlanRouteGuard` + `FeatureGate` / `planCapabilities.can`.
|
||||
|
||||
---
|
||||
|
||||
## Surfaces
|
||||
|
||||
| Route | Feature key | Notes |
|
||||
|-------|-------------|-------|
|
||||
| `/support` | `support.center` | Status filter chips, clickable rows, count |
|
||||
| `/support/new` | `support.ticket_create` | Priority + char counters; upgrade panel if denied |
|
||||
| `/support/[ticketId]` | `support.ticket_thread` | Thread + CSAT banner/form |
|
||||
|
||||
Legacy plans: if the matrix turns `support.*` off (see `03-roles-matrix`), `PlanRouteGuard` shows the upgrade panel. When keys are absent (pre-cutover), `CORE_ALWAYS_ON` keeps basic support available.
|
||||
|
||||
CSAT is **not** a separate feature key — it rides on `support.ticket_thread` once the ticket is resolved/closed (design §5).
|
||||
|
||||
---
|
||||
|
||||
## Client API
|
||||
|
||||
| Helper | Path |
|
||||
|--------|------|
|
||||
| `listSupportTickets` / `getSupportTicket` / `createSupportTicket` / `replySupportTicket` | `apps/web/src/lib/support/api.ts` |
|
||||
| `submitSupportCsat` → `POST …/csat` `{ score, comment? }` | same |
|
||||
| `canRateTicket` / `canReplyToTicket` | same |
|
||||
| Types `SupportCsat`, `SubmitSupportCsatInput` | `apps/web/src/lib/support/types.ts` |
|
||||
| UI | `SupportTicketRating.svelte` |
|
||||
|
||||
**Graceful backend lag:** if agent 13’s CSAT route is not mounted yet, `isSupportUnavailable` / 404–503 surfaces a clear message without breaking the thread. Duplicate ratings (`409`) show “already rated”.
|
||||
|
||||
**ASSUMPTION:** Response may be a full ticket (with `csat`) or a CSAT object; UI merges `csat` onto the in-memory ticket either way.
|
||||
|
||||
---
|
||||
|
||||
## UX / a11y / perf
|
||||
|
||||
- Status filters: `aria-pressed` chip group (matches admin queue pattern).
|
||||
- Rows: keyboard activatable (`Enter` / `Space`), `role="link"`.
|
||||
- CSAT: `role="radiogroup"` star buttons with explicit `aria-label`s; comment encouraged for scores ≤2.
|
||||
- Thread: `role="log"` + `aria-live="polite"`; capped scroll region; auto-scroll on new messages.
|
||||
- Polling: 20s interval skipped when `document.visibilityState === "hidden"`; refresh on focus.
|
||||
- No extra cards in hero chrome — reuse `PageShell` + existing tokens.
|
||||
|
||||
---
|
||||
|
||||
## Files touched
|
||||
|
||||
- `apps/web/src/lib/support/types.ts`
|
||||
- `apps/web/src/lib/support/api.ts`
|
||||
- `apps/web/src/lib/components/SupportTicketRating.svelte` (new)
|
||||
- `apps/web/src/routes/support/+page.svelte`
|
||||
- `apps/web/src/routes/support/new/+page.svelte`
|
||||
- `apps/web/src/routes/support/[ticketId]/+page.svelte`
|
||||
- `apps/web/src/lib/plan-capabilities.ts` (upgrade titles for create/thread)
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
cd apps/web && npm run check
|
||||
```
|
||||
|
||||
Manual:
|
||||
|
||||
1. `/support` — filter chips update URL; empty + list states.
|
||||
2. `/support/new` — create with priority; gated plan shows upgrade.
|
||||
3. Resolved ticket — CSAT form appears; after submit, “Your rating” card; reply still reopens when allowed.
|
||||
4. Legacy matrix with `support.center=false` — route guard upgrade panel.
|
||||
|
||||
**Depends on:** agent 13 mounting `POST /api/support/tickets/{id}/csat` and optional `csat` on GET. UI is ready ahead of that mount.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope (other agents)
|
||||
|
||||
- Schema / CSAT backend (12–13)
|
||||
- Staff assign / claim UI (14)
|
||||
- Admin CSAT aggregates
|
||||
Reference in New Issue
Block a user