From 001438008b76c1342a4fd1815d3d53ce8e961c6b Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Thu, 16 Apr 2026 02:00:33 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20fix=20PSA=20ticket=20management=20spec?= =?UTF-8?q?=20=E2=80=94=20prefill=20state,=20TicketQueue=20naming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace false claim about linkedTicket state with explicit fetch step on modal open - Remove MyQueueWidget references; TicketQueue is the existing component being updated Co-Authored-By: Claude Sonnet 4.6 --- .../2026-04-16-psa-ticket-management-design.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/superpowers/specs/2026-04-16-psa-ticket-management-design.md b/docs/superpowers/specs/2026-04-16-psa-ticket-management-design.md index 16b9b4ef..0a195984 100644 --- a/docs/superpowers/specs/2026-04-16-psa-ticket-management-design.md +++ b/docs/superpowers/specs/2026-04-16-psa-ticket-management-design.md @@ -201,7 +201,7 @@ Frontend uses `missing_fields` to highlight required fields still needing engine - `router.tsx` — add `/tickets` route (lazy, via `lazyWithRetry`) - `AppLayout.tsx` — add "Tickets" nav item in sidebar under RESOLVE section - `AssistantChatPage.tsx` — handle `create_spin_off_ticket` action type in TaskLane + add "New Ticket" button to session header -- `QuickStartPage.tsx` — add `MyQueueWidget` component in collapsible Dashboard section +- `QuickStartPage.tsx` — no structural change needed; `TicketQueue` already renders at line 64. The existing component is updated in place (see Section 4). ### Shared Types (`types/tickets.ts`) @@ -352,7 +352,14 @@ export interface PSATicketInfo { These fields are already returned by the CW API in `get_ticket()` — update `_map_ticket()` in `ConnectWiseProvider` and the `PSATicketInfo` Pydantic schema to pass them through. -`AssistantChatPage` already stores the linked ticket as `linkedTicket: PSATicketInfo | null` in local state (populated when a ticket is linked via `TicketLinkIndicator`). Once `PSATicketInfo` includes the IDs, the modal receives: +**`AssistantChatPage` state change required:** The current page only tracks `activePsaTicketId: string | null` (line 76) — it does not hold a `PSATicketInfo` object. Add a new state field: +```typescript +const [linkedTicket, setLinkedTicket] = useState(null) +``` + +When the modal is opened (either via AI suggestion or the "New Ticket" button), if `activePsaTicketId` is set and `linkedTicket` is null, fire `integrationsApi.getTicket(activePsaTicketId)` to fetch the full ticket (which now includes `company_id` and `board_id`) and store it in `linkedTicket`. The modal opens immediately — `initialValues` is populated once the fetch resolves and the form fields update. If the fetch is still in flight when the modal opens, `company_id` and `board_id` start empty and fill in when ready. + +Once `linkedTicket` is populated, the modal receives: ```typescript initialValues: { company_id: linkedTicket.company_id, @@ -360,7 +367,7 @@ initialValues: { } ``` -When no linked ticket exists: `initialValues` is omitted. `company_id` and `board_id` render empty, requiring manual selection. No silent defaults, no errors. +When no linked ticket exists (`activePsaTicketId === null`): `initialValues` is omitted. `company_id` and `board_id` render empty, requiring manual selection. No silent defaults, no errors. ### TaskLane Action Lifecycle @@ -461,7 +468,7 @@ Backend `search_tickets()` adds `orderBy=priority desc,dateEntered desc` to the - `frontend/src/router.tsx` — `/tickets` route - `frontend/src/components/layout/AppLayout.tsx` — Tickets nav item - `frontend/src/pages/AssistantChatPage.tsx` — handle `create_spin_off_ticket` command in action renderer + add "New Ticket" button to session header -- `frontend/src/pages/QuickStartPage.tsx` — MyQueueWidget +- `frontend/src/components/dashboard/TicketQueue.tsx` — update existing component (see Section 4 — not a new file) - `frontend/src/api/integrations.ts` — update `searchTickets()` and `searchTicketsQueue()` return types to `TicketListResponse` - `frontend/src/types/integrations.ts` — add `company_id: number | null` and `board_id: number | null` to `PSATicketInfo` - `frontend/src/components/dashboard/TicketQueue.tsx` — update existing component: read `.items`, add mapping-state detection, member-mapping check, and 5-item cap