Files
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

2.6 KiB
Raw Permalink Blame History

13 — Support ticket ratings / CSAT

Owner: agent 13
Depends on: agent 12 schema (030_support_desk.sqlsupport_csat_ratings)
Status: implemented (API + tests)

Goal

Customers rate resolved or closed tickets once (score 15 + optional comment). Platform admins see aggregate CSAT (no PII).

Schema (agent 12)

Table support_csat_ratings:

Column Notes
ticket_id UNIQUE — one rating per ticket
company_id, user_id owner + tenant
score SMALLINT 15
comment optional, max 2000 runes (truncated)
created_at UTC

Ticket columns csat_token_hash / csat_invite_sent_at exist for optional public token flow (not wired in this agent).

Rules

  1. Only created_by_user_id may rate (others → 404).
  2. Status must be resolved or closed else 400 (ticket not eligible for rating).
  3. Duplicate insert → 409 (already rated).
  4. Logs: ticket_id + score only — never comment, email, or names.

APIs

Method Path Auth Response
POST /api/support/tickets/{id}/csat session + company 201 SupportCsat
GET /api/support/tickets/{id} customer additive csat / csat_eligible
GET /api/admin/support/tickets/{id} support desk includes csat when present
GET /api/admin/support/csat?from=&to= platform admin aggregate

Customer submit body

{ "score": 4, "comment": "optional" }

Admin aggregate

{
  "total": 12,
  "average": 4.25,
  "distribution": { "1": 0, "2": 1, "3": 2, "4": 4, "5": 5 },
  "from": null,
  "to": null
}

from / to are optional RFC3339 bounds on created_at (to exclusive).

Code map

Piece Path
Service apps/api/internal/support/ratings.go
Types CSATInput, CSATRating, CSATAggregate in types.go
Handlers apps/api/internal/httpapi/support_csat_handlers.go
Routes customer POST csat; admin GET /api/admin/support/csat
Unit tests ratings_test.go, support_csat_auth_test.go
Integration ratings_integration_test.go (needs DATABASE_URL + goose)

Verification

cd apps/api
go test ./internal/support/ -count=1 -run 'CSAT|NormalizeCSAT|ClientErrorCSAT'
go test ./internal/httpapi/ -count=1 -run 'SupportCSAT|SupportTicketCRUDAuth'

With DB migrated:

go test ./internal/support/ -count=1 -run TestSubmitCSATOwnershipAndOnce

Out of scope (this agent)

  • Public token CSAT (POST /api/public/support/csat)
  • User/staff UI panels (agents 1415)
  • Email CSAT invite stubs