Files
descrybe/docs/admin-roles-support/README.md
T
greeneclipse 8580c996c3 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.
2026-08-09 22:47:43 +02:00

6.7 KiB
Raw Blame History

Admin roles, legacy plans & support desk

End-to-end work from the 20-agent admin-roles-support swarm: legacy (A1) limited nav, platform staff roles, admin panel polish, support assign/claim + CSAT ratings.

Runtime rule (tenant features):

effective(feature) = plan_allows(feature)
  AND global_section_enabled(section(feature))
  AND global_feature_enabled(feature)

Staff access is orthogonal to plan features: users.staff_role + is_platform_admin gate /admin and the support desk.


Doc map (agents 119)

Doc Owner What it covers
01-ux-research.md 1 Admin / permissions / support UX patterns
02-current-inventory.md / 02-extension-points.json 2 Pre-change inventory
03-roles-matrix.md / .json 3 Legacy allow-list + role→feature matrix
04-contract.md / .json 4 Unified plan + staff contract
05-legacy-seed.md 5 Legacy profile seed / A1 detection
06-staff-roles.md 6 admin / developer / support_staff backend
07-admin-shell.md 7 Admin layout / nav chrome
08-permissions-ui.md 8 Billing → Permissions panel
09-admin-billing-ui.md 9 Plans list / assign polish
10-admin-orgs-ui.md 10 Users/companies + staff role grant
11-support-design.md / 11-support-api-contract.json 11 Support desk design
12-support-backend.md 12 Tickets / claim / assign API
13-support-ratings.md 13 CSAT 15 ratings
14-support-staff-ui.md 14 Staff inbox + assign UI
15-user-support-ui.md 15 Customer support + rate UI
16-legacy-nav.md 16 A1 image-nav gating
17-security.md 17 AuthZ / IDOR / CSRF pass
18-performance.md 18 Indexes / list bounds
19-defaults-alignment.md 19 Ladder + Legacy + staff defaults

Related: ../plan-permissions/README.md (feature keys + admin Permissions API).


Schema (goose)

Version File Purpose
026 apps/api/sql/schema/026_plan_features.sql plans.features + global gates
027 027_capabilities_support_perf.sql Capabilities + support queue indexes
028 028_plan_is_legacy.sql plans.is_legacy + name backfill
029 029_staff_roles.sql users.staff_role
030 030_support_desk.sql CSAT table, claim queue cols, notification kinds

Apply (Windows):

.\scripts\migrate.ps1
# or from apps/api with DATABASE_URL set:
go run github.com/pressly/goose/v3/cmd/goose@v3.24.3 -dir sql/schema postgres $env:DATABASE_URL up

Strip UTF-8 BOM from new SQL if goose errors on \ufeff-- +goose Up.


Code map

Concern Paths
Legacy detect/seed apps/api/internal/billing/legacy_plan*.go
Staff roles apps/api/internal/auth/staff*.go, httpapi/middleware.go, admin_staff_handlers.go
Support desk apps/api/internal/support/{desk,ratings,agents,tickets}.go, httpapi/support_*.go
Admin shell AdminNav.svelte, admin-nav-ui.svelte.ts, root +layout.svelte
Permissions UI PlanPermissionsPanel.svelte, admin-plan-permissions.ts
Orgs / staff grant routes/admin/users/+page.svelte, admin-orgs.ts
Legacy nav Nav.svelte, plan-capabilities.ts, PlanRouteGuard.svelte
Staff inbox routes/admin/support/**
User rate SupportTicketRating.svelte, routes/support/**

Manual verify checklist

A1 / Legacy nav

  • goose30; seed-demo (or EnsureDefaultPlans) so Local Demo Co is on plan Legacy (is_legacy=true)
  • Restart API after migrate/seed
  • Login as demo → Local Demo Co → sidebar shows only: Dashboard, Products, Feeds, Export Feeds, Categories, Attributes, Standard Fields, Usage & Billing, Settings
  • No Background Tasks / Processing, Stores, Campaigns, Brand, SEO (no empty More unless Platform admin)
  • GET /api/billing/capabilities: processing.monitor / stores.hub / marketing.* → false; nav parents → true
  • Deep link /processing → upgrade panel

Admin panel polish

  • /admin shell: sidebar groups Monitor / Manage, dark content, mobile drawer
  • /admin/billing → Permissions: profiles (incl. Legacy one-click), section toggles
  • /admin/users: companies + assign plan + staff role dialog

Support assign + rate

  • Customer: create ticket → staff reply → resolve → rate 15 (SupportTicketRating)
  • Staff: /admin/support?scope=unassigned → Claim → Mine; Unassign returns to queue
  • Full admin: ticket detail → Assign to staff → Apply
  • API: support routes under RequireSupportDesk; billing mutations still RequirePlatformAdmin

Staff role access

  • Grant support_staff from Users → that user sees Support (+ Overview redirects to Support), not Billing/Settings
  • GET /api/admin/billing (or plans) → 403 for support_staff
  • admin / developer / legacy is_platform_admin + NULL role → full console
  • Cannot PATCH own staff_role

Verify commands

.\scripts\migrate.ps1
cd apps\api
go test ./internal/billing/ ./internal/auth/ ./internal/support/ -count=1
go test ./internal/httpapi/ -count=1 -run "Staff|Support|PlanFeature|PlanGate|AdminAuth|RequirePlatform|CSAT|Csat"
cd ..\web
npm run check

Optional demo alignment:

cd apps\api
go run ./cmd/seed-demo -postgres $env:DATABASE_URL

Integration notes (agent 20)

  • Merged duplicate 028_* legacy SQL into 028_plan_is_legacy.sql; renumbered staff → 029, support desk → 030.
  • /admin Overview: support_staff redirected to /admin/support (nav still shows Overview).
  • seed-demo / EnsureLegacyDefaults assigns Legacy to Local Demo Co / A1 cohort (not Enterprise all-ON).

Remaining blockers / non-goals

  1. Not every tenant mutation is AssertFeature'd (same as plan-permissions agent 10) — UI + critical writes first.
  2. Live browser QA of admin polish + CSAT requires a running npm run dev session and staff test user.
  3. OpenAPI public fragment may still omit some support/staff paths (session docs in plan-permissions / support contract JSON).