# Contract: Agent Ticket Queue ## `PATCH /admin/agents/:agentId` (existing route, extended) **Auth**: `fastify.authenticate` (unchanged — this route was already agent-usable, not admin-only, since agents may already update their own roster fields per existing precedent). **Request body** (existing shape plus one new optional field): ```json { "name": "string, optional", "teamId": "string, optional", "active": "boolean, optional", "userId": "string | null, optional" } ``` **Responses**: - `200` — updated `Agent`, including `userId`. - `404` — `agentId` doesn't exist, or (new) the target `userId` doesn't exist as a `User`. - `400` — (new) the target `User`'s role is not `AGENT`. - `409` — (new) the target `userId` is already linked to a different `Agent`. ## `GET /agents/me/tickets` **Auth**: `fastify.authenticate` only — no `requireRole`, since any authenticated `AGENT` (or `ADMIN`, who may also hold an agent profile) may call this for their own session. **Response `200`**: ```json { "success": true, "data": [ { "id": "string", "code": "string", "status": "string", "priority": "string", "severity": "string", "product": { "id": "string", "externalProductId": "string", "name": "string" }, "customer": { "externalUserId": "string", "externalTenantId": "string" }, "assignedAt": "ISO 8601 datetime", "sla": { "status": "string", "firstResponseDueAt": "ISO 8601 datetime | null", "resolutionDueAt": "ISO 8601 datetime | null", "breachedAt": "ISO 8601 datetime | null" } } ], "meta": null } ``` `sla` is `null` when no `SLARun` exists yet for that ticket. **Response `404`**: the session's `User` has no linked `Agent` row (`{ "success": false, "error": { "code": "NOT_FOUND", "message": "No agent profile is linked to this account." } }`). ## `GET /admin/agents/:agentId/tickets` **Auth**: `fastify.authenticate` + `requireRole('ADMIN')`. **Response**: identical shape to `GET /agents/me/tickets`'s `200`, for the `agentId` named in the URL. `404` if `agentId` doesn't exist as an `Agent` row (a plain "agent not found," distinct from the self-route's "no agent linked to this account").