--- description: "Task list for External Support Desk / PSA Handoff" --- # Tasks: External Support Desk / PSA Handoff **Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/` **Prerequisites**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/spec.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/plan.md` (required), `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/research.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/data-model.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/quickstart.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/contracts/external-support-desk-handoff.logical.openapi.yaml`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/checklists/requirements.md` **Support truth**: Spec 246 and the existing repo code remain authoritative, except for one bounded Spec 256 finalization exception: after internal request creation, the same `SupportRequest` row may receive exactly one synchronous write limited to the external handoff fields. Extend `apps/platform/app/Models/SupportRequest.php` and the current support-request submission path only; do not add a second support-ticket entity, support queue, support register, or support-request resource. **Tests (TEST-GOV-001)**: REQUIRED (Pest) for all runtime behavior changes in this slice. Keep proof in focused unit plus feature lanes only, then run the narrow manual smoke path from `quickstart.md`. **Operations**: This slice must stay synchronous inside the existing support-request path. Do not create, queue, resume, or complete an `OperationRun`. **RBAC**: Workspace membership and tenant entitlement remain `404` boundaries; in-scope members missing `Capabilities::SUPPORT_REQUESTS_CREATE` remain `403`; latest-handoff visibility must follow the same boundary. **Provider boundary**: One configured external desk target only. No helpdesk registry, no target-management UI, and no multi-provider framework in this slice. **Organization**: Tasks are grouped by user story so create, link, and explicit-failure behavior can be implemented and validated independently once the shared foundation exists. ## Phase 1: Setup (Shared Preparation) **Purpose**: Lock the bounded repo-grounded scope before runtime work begins. - [x] T001 Review `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/spec.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/plan.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/research.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/data-model.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/quickstart.md`, `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/contracts/external-support-desk-handoff.logical.openapi.yaml`, and `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/checklists/requirements.md` and confirm the slice stays one-way, single-target, and SupportRequest-backed. - [x] T002 [P] Verify the exact reuse seams from Spec 246 in `apps/platform/app/Models/SupportRequest.php`, `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php`, `apps/platform/app/Support/SupportRequests/SupportRequestContextBuilder.php`, `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, `apps/platform/app/Services/Audit/WorkspaceAuditLogger.php`, `apps/platform/app/Support/Audit/AuditActionId.php`, and the new app-config seam `apps/platform/config/support_desk.php` before adding any new handoff behavior. --- ## Phase 2: Foundational (Blocking Prerequisites) **Purpose**: Add the bounded persistence, target-resolution, audit, and shared summary seams that every story depends on. **Critical**: No user story work should begin until this phase is complete. - [x] T003 Extend the existing support-request truth with `external_handoff_mode`, `external_ticket_reference`, `external_ticket_url`, and `external_handoff_failure_summary` in `apps/platform/database/migrations/*_add_external_handoff_fields_to_support_requests_table.php`, `apps/platform/app/Models/SupportRequest.php`, and `apps/platform/database/factories/SupportRequestFactory.php` without creating a second support-ticket model or table. - [x] T004 [P] Add the one concrete provider-owned handoff seam and the single-target app-config contract in `apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php` and `apps/platform/config/support_desk.php`, enforce the five-second outbound timeout there, and avoid introducing a support settings UI, provider registry, or generic helpdesk framework. - [x] T005 [P] Preserve the existing `support_request.created` audit path and add stable audit action IDs plus bounded audit payload helpers for external ticket created, external ticket linked, and external handoff failed in `apps/platform/app/Support/Audit/AuditActionId.php` and `apps/platform/app/Services/Audit/WorkspaceAuditLogger.php`. - [x] T006 Add one shared latest-handoff summary read path for tenant and run primary contexts in `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php` so both existing support actions reuse the same scoped query, naming, and no-cross-scope-shortcut rules. **Checkpoint**: Foundation ready. The existing support-request path can now persist neutral external-linkage truth, resolve one target, and read the latest scoped handoff summary. --- ## Phase 3: User Story 1 - Create A New External Ticket From The Existing Support Flow (Priority: P1) 🎯 MVP **Goal**: An entitled operator can submit the existing support action and create one external desk ticket from the current tenant or run context without leaving the product. **Independent Test**: Submit `Request support` from the tenant dashboard and the operation-run viewer with `create_external_ticket`, fake one configured target, and verify the same `SupportRequest` row keeps the internal `SR-...` reference while storing the returned external reference and URL. ### Tests for User Story 1 - [x] T007 [P] [US1] Add unit coverage for `create_external_ticket` branching, single-target availability fallback, the five-second timeout path, and created-ticket reference or URL normalization in `apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php`. - [x] T008 [P] [US1] Add feature coverage for tenant and run `create_external_ticket` success paths in `apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php` and `apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php`. ### Implementation for User Story 1 - [x] T009 [US1] Extend `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php` so internal support-request creation commits first, `create_external_ticket` runs synchronously afterward, and the one allowed Spec 256 finalization write records the external reference or URL back onto the same `SupportRequest` row. - [x] T010 [US1] Extend the tenant dashboard support action in `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php` with handoff-mode choice, target-availability guidance, `TenantPilot only` versus `TenantPilot + external support desk` mutation-scope copy, latest-handoff summary copy, and success feedback that shows both internal and external references when a ticket is created. - [x] T011 [US1] Extend the run-context support action in `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php` with the same create flow, scoped latest-handoff summary, `TenantPilot only` versus `TenantPilot + external support desk` mutation-scope copy, and success feedback without adding a new run-support surface. - [x] T012 [US1] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php` and fix any create-path regressions before moving to the link flow. **Checkpoint**: User Story 1 is independently functional when both existing support actions can create one external ticket and immediately show the persisted linkage on the same support-request truth. --- ## Phase 4: User Story 2 - Link An Already-Existing External Ticket During Support Submission (Priority: P1) **Goal**: An entitled operator can record an external ticket that already exists without creating a duplicate external case. **Independent Test**: Submit the existing tenant and run `Request support` actions with `link_existing_ticket`, provide a valid reference and optional URL, and verify the `SupportRequest` stores that linkage without issuing an external create call. ### Tests for User Story 2 - [x] T013 [P] [US2] Add unit coverage for `link_existing_ticket` reference normalization, optional URL normalization, and invalid-link rejection in `apps/platform/tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php`. - [x] T014 [P] [US2] Add feature coverage for tenant and run `link_existing_ticket` submissions, including the no-create-call guarantee and linked-flow success feedback that shows both references, in `apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php` and `apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php`. ### Implementation for User Story 2 - [x] T015 [US2] Implement `link_existing_ticket` branching, conditional validation, and persisted external reference or URL behavior in `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php` and `apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php`. - [x] T016 [US2] Add conditional external reference and URL inputs plus linked-flow success feedback that shows the internal and external references on the tenant dashboard action in `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php`. - [x] T017 [US2] Add the same link controls plus linked-flow success feedback to the run-context action in `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php`. - [x] T018 [US2] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php` and fix any link-path regressions before moving to failure hardening. **Checkpoint**: User Story 2 is independently functional when both existing support actions can link an already-created external ticket without producing a duplicate external create call. --- ## Phase 5: User Story 3 - Keep Failures Explicit, Scoped, And Auditable (Priority: P2) **Goal**: External handoff failure remains visible and auditable while the internal support request stays durable and the same tenant or run contexts stay the only visibility surfaces. **Independent Test**: Force `create_external_ticket` to fail after internal request creation, then verify the internal `SupportRequest` remains persisted, the current support context shows the latest failure summary for that same support reference, and audit plus authorization behavior stays correct. ### Tests for User Story 3 - [x] T019 [P] [US3] Add unit coverage for latest-handoff summary derivation, latest-per-context selection, and persisted failure-summary semantics in `apps/platform/tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php`. - [x] T020 [P] [US3] Add feature coverage for tenant and run failed-create partial-success behavior, including timeout-normalized failure feedback, in `apps/platform/tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php` and `apps/platform/tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php`. - [x] T021 [P] [US3] Add feature coverage for `404` versus `403` boundaries and context-scoped latest-summary visibility in `apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php`. - [x] T022 [P] [US3] Add feature coverage for preserved `support_request.created` auditing plus created, linked, and failed external-handoff audit events in `apps/platform/tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php`. ### Implementation for User Story 3 - [x] T023 [US3] Persist bounded `external_handoff_failure_summary` semantics, the one allowed Spec 256 finalization-write contract, and latest-summary scoping rules in `apps/platform/app/Models/SupportRequest.php` and `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php` without adding support history pages, external-reference lookup routes, or a second support product surface. - [x] T024 [US3] Implement explicit partial-success or warning feedback plus revisit-time failure-summary rendering in `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php`. - [x] T025 [US3] Enforce the shared authorization and audit boundary for create, link, failure, and latest-summary visibility in `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php`, `apps/platform/app/Support/Audit/AuditActionId.php`, and `apps/platform/app/Services/Audit/WorkspaceAuditLogger.php` without introducing queues, retries, or `OperationRun` orchestration. - [x] T026 [US3] Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php` and fix any failure, audit, or authorization regressions before final polish. **Checkpoint**: User Story 3 is independently functional when explicit failure truth, scoped visibility, and audit coverage all hold without losing the internal support request. --- ## Phase 6: Polish & Cross-Cutting Concerns **Purpose**: Close the slice without widening scope, and leave a clean validation and guardrail trail for review. - [x] T027 Confirm `Request support`, `Support reference`, `External ticket`, handoff-mode labels, mutation-scope wording, and latest-summary copy stay aligned across `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, `apps/platform/app/Support/SupportRequests/ExternalSupportDeskHandoffService.php`, `apps/platform/lang/en/localization.php`, and `apps/platform/lang/de/localization.php` without leaking provider-specific product names into primary operator copy. - [x] T028 Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` on the touched platform files before final validation. - [x] T029 Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/SupportRequests/ExternalSupportDeskHandoffServiceTest.php tests/Unit/Support/SupportRequests/SupportRequestLatestHandoffSummaryTest.php` as the focused unit close-out suite from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/quickstart.md`. - [x] T030 Run `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/SupportRequests/TenantSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/OperationRunSupportRequestExternalHandoffTest.php tests/Feature/SupportRequests/SupportRequestExternalHandoffAuthorizationTest.php tests/Feature/SupportRequests/SupportRequestExternalHandoffAuditTest.php` as the focused feature close-out suite from `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/quickstart.md`. - [x] T031 Execute the manual smoke path in `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/quickstart.md` for tenant and run create, link, and failure handling, including the no-new-support-surface and no-`OperationRun` checks. Completed through a temporary Pest Browser smoke harness covering tenant create, run link, run failure, latest failure summary, no console errors, and no persistent browser-test surface. - [x] T032 Record the final implementation close-out in `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/256-external-support-desk-handoff/plan.md`, including the guardrail outcome and any explicit `document-in-feature` or named `follow-up-spec` decision for target configuration, retry pressure, or multi-provider pressure instead of hiding that scope in code review. --- ## Dependencies & Execution Order ### Phase Dependencies - Phase 1 starts immediately. - Phase 2 depends on Phase 1 and blocks all story work. - Phase 3 depends on Phase 2 and delivers the MVP create flow. - Phase 4 depends on Phase 2 and is safest after Phase 3 because it extends the same submission service and the same two action forms. - Phase 5 depends on Phases 3 and 4 because failure, visibility, and audit proof must cover both create and link behavior on both existing surfaces. - Phase 6 depends on every prior phase. ### User Story Dependencies - US1 is the MVP and first shippable increment. - US2 is independently testable but should follow US1 because both stories extend the same `SupportRequestSubmissionService` and support-action forms. - US3 depends on US1 and US2 because explicit failure, audit, and scoped-visibility rules must cover every handoff mode. ### Within Each User Story - Write the listed Pest coverage first and ensure it fails before implementation. - Land shared submission-service changes before surface wiring whenever both are required. - Re-run the story-specific validation task before moving to the next story. --- ## Parallel Opportunities ### Phase 1 - T001 and T002 can run in parallel. ### Phase 2 - T004 and T005 can run in parallel after T003 establishes the persisted handoff fields. ### User Story 1 - T007 and T008 can run in parallel before implementation work starts. ### User Story 2 - T013 and T014 can run in parallel before implementation work starts. ### User Story 3 - T019, T020, T021, and T022 can run in parallel before the failure hardening pass. --- ## Implementation Strategy ### MVP First 1. Complete Phase 1. 2. Complete Phase 2. 3. Complete Phase 3. 4. Stop and review the create-only external handoff slice before adding link and failure hardening. ### Incremental Delivery 1. Ship US1 so the product can create one external ticket from the two existing support-aware surfaces. 2. Add US2 so operators can link an already-opened external ticket without duplicate create behavior. 3. Add US3 so failure honesty, scoped visibility, and audit proof hold across every handoff mode. ### Team Strategy 1. Finish Phase 2 together before splitting story work. 2. Parallelize test authoring inside each story. 3. Sequence merges carefully around `apps/platform/app/Support/SupportRequests/SupportRequestSubmissionService.php`, `apps/platform/app/Filament/Pages/TenantDashboard.php`, `apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`, and `apps/platform/lang/en/localization.php` plus `apps/platform/lang/de/localization.php`, because every story touches those same shared seams.