openapi: 3.0.3 info: title: TenantPilot Admin — External Support Desk Handoff (Conceptual) version: 0.1.0 description: | Conceptual contract for the first external support desk handoff slice. NOTE: These flows are implemented as Filament (Livewire) actions on existing pages. This file captures the expected action payload, outcome semantics, and authorization boundaries rather than a public REST API. servers: - url: /admin paths: /t/{tenant}/support-requests/actions/submit: post: summary: Submit a tenant-context support request with optional external handoff description: | Existing tenant dashboard support action, extended with one-way external handoff behavior. Authorization: - Workspace non-member or non-entitled tenant actor: 404 - Entitled tenant member without `support_requests.create`: 403 - Authorized actor: 200 with one support-request submission result Behavior: - Always creates the internal `SR-...` support request first - `internal_only` performs no outbound handoff - `link_existing_ticket` stores the provided external reference and must not call external create - `create_external_ticket` uses one application-configured external target only - `create_external_ticket` applies a maximum 5 second outbound timeout budget - External create failure keeps the internal support request and returns an explicit failed-handoff outcome - No queue, `OperationRun`, retry scheduler, or bidirectional sync is introduced parameters: - name: tenant in: path required: true schema: type: string description: Filament tenancy slug (`tenants.external_id`) requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SupportRequestHandoffSubmission' responses: '200': description: Support request accepted with internal-only, linked, created, or failed-handoff outcome content: application/json: schema: $ref: '#/components/schemas/SupportRequestHandoffResult' '403': description: Forbidden (entitled tenant member lacks support-request capability) '404': description: Not found (wrong workspace, non-member, or missing tenant entitlement) /operations/{run}/support-requests/actions/submit: post: summary: Submit a run-context support request with optional external handoff description: | Existing canonical run detail support action, extended with one-way external handoff behavior. Authorization: - Inaccessible run or run outside entitled tenant scope: 404 - Entitled member without `support_requests.create`: 403 - Authorized actor: 200 with one support-request submission result Behavior: - The run must resolve to an entitled tenant before any support truth is revealed - Uses the same payload contract and outcome semantics as the tenant-context action - Does not create, resume, or update an `OperationRun` parameters: - name: run in: path required: true schema: type: integer description: Internal `operation_runs.id` requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SupportRequestHandoffSubmission' responses: '200': description: Support request accepted with internal-only, linked, created, or failed-handoff outcome content: application/json: schema: $ref: '#/components/schemas/SupportRequestHandoffResult' '403': description: Forbidden (entitled member lacks support-request capability) '404': description: Not found (run inaccessible under workspace or tenant scope) components: schemas: SupportRequestHandoffSubmission: type: object required: - severity - summary - handoff_mode properties: severity: type: string enum: [low, normal, high, blocking] summary: type: string reproduction_notes: type: string nullable: true contact_name: type: string nullable: true contact_email: type: string format: email nullable: true handoff_mode: type: string enum: [internal_only, create_external_ticket, link_existing_ticket] external_ticket_reference: type: string nullable: true description: Required when `handoff_mode = link_existing_ticket` external_ticket_url: type: string format: uri nullable: true target_available: type: boolean nullable: true description: Derived UI hint only; the server remains authoritative SupportRequestHandoffResult: type: object required: - support_request_id - internal_reference - primary_context_type - handoff_mode - handoff_outcome - latest_summary properties: support_request_id: type: integer internal_reference: type: string primary_context_type: type: string enum: [tenant, operation_run] primary_context_id: type: integer nullable: true handoff_mode: type: string enum: [internal_only, create_external_ticket, link_existing_ticket] handoff_outcome: type: string enum: - internal_only - external_ticket_created - external_ticket_linked - external_handoff_failed external_ticket_reference: type: string nullable: true external_ticket_url: type: string format: uri nullable: true failure_summary: type: string nullable: true latest_summary: $ref: '#/components/schemas/LatestSupportRequestHandoffSummary' LatestSupportRequestHandoffSummary: type: object required: - internal_reference - primary_context_type - submitted_at - handoff_mode - has_external_link - has_failure properties: internal_reference: type: string primary_context_type: type: string enum: [tenant, operation_run] primary_context_id: type: integer nullable: true submitted_at: type: string format: date-time handoff_mode: type: string enum: [internal_only, create_external_ticket, link_existing_ticket] external_ticket_reference: type: string nullable: true external_ticket_url: type: string format: uri nullable: true external_handoff_failure_summary: type: string nullable: true has_external_link: type: boolean has_failure: type: boolean