openapi: 3.1.0 info: title: Findings Operator Inbox Surface Contract version: 1.0.0 description: >- Internal reference contract for the canonical My Findings inbox and the workspace overview Assigned to me signal. The application continues to return rendered HTML through Filament and Livewire. The vendor media types below document the structured page models that must be derivable before rendering. This is not a public API commitment. paths: /admin/findings/my-work: get: summary: Canonical personal findings inbox description: >- Returns the rendered admin-plane inbox for the current user's visible assigned open findings. Personal assignment scope is fixed. Tenant prefiltering may be derived from the active admin tenant context. responses: '302': description: Redirects into the existing workspace or tenant chooser flow when membership exists but workspace context is not yet established '200': description: Rendered My Findings inbox page content: text/html: schema: type: string application/vnd.tenantpilot.my-findings-inbox+json: schema: $ref: '#/components/schemas/MyFindingsInboxPage' '404': description: Workspace scope is not visible because membership is missing or out of scope /admin: get: summary: Workspace overview with assigned-to-me signal description: >- Returns the rendered workspace overview. The vendor media type documents the embedded personal findings signal used to decide whether assigned findings work exists before opening the inbox. responses: '302': description: Redirects into the existing workspace or tenant chooser flow when membership exists but workspace context is not yet established '200': description: Rendered workspace overview page content: text/html: schema: type: string application/vnd.tenantpilot.workspace-overview-my-findings+json: schema: $ref: '#/components/schemas/WorkspaceOverviewMyFindingsSignalSurface' '404': description: Workspace scope is not visible because membership is missing or out of scope /admin/t/{tenant}/findings/{finding}: get: summary: Tenant finding detail with inbox continuity support description: >- Returns the rendered tenant finding detail page. The logical contract below documents only the continuity inputs required when the page is opened from the My Findings inbox. parameters: - name: tenant in: path required: true schema: type: integer - name: finding in: path required: true schema: type: integer - name: nav in: query required: false style: deepObject explode: true schema: $ref: '#/components/schemas/CanonicalNavigationContext' responses: '200': description: Rendered tenant finding detail page content: text/html: schema: type: string application/vnd.tenantpilot.finding-detail-continuation+json: schema: $ref: '#/components/schemas/FindingDetailContinuation' '403': description: Viewer is in scope but lacks the existing findings capability for the tenant detail destination '404': description: Tenant or finding is not visible because workspace or tenant entitlement is missing components: schemas: MyFindingsInboxPage: type: object required: - header - appliedScope - availableFilters - summaryCounts - rows - emptyState properties: header: $ref: '#/components/schemas/InboxHeader' appliedScope: $ref: '#/components/schemas/InboxAppliedScope' availableFilters: description: Includes the fixed assignee-scope filter plus tenant, overdue, reopened, and high-severity filters. Tenant filter options are derived only from visible capability-eligible tenants. type: array items: $ref: '#/components/schemas/InboxFilterDefinition' summaryCounts: $ref: '#/components/schemas/MyFindingsSummaryCounts' rows: description: Rows are ordered overdue first, reopened non-overdue second, then remaining findings. Within each bucket, rows with due dates sort by dueAt ascending, rows without due dates sort last, and remaining ties sort by findingId descending. type: array items: $ref: '#/components/schemas/AssignedFindingInboxRow' emptyState: oneOf: - $ref: '#/components/schemas/InboxEmptyState' - type: 'null' InboxHeader: type: object required: - title - description properties: title: type: string enum: - My Findings description: type: string clearTenantFilterAction: oneOf: - $ref: '#/components/schemas/ActionLink' - type: 'null' InboxAppliedScope: type: object required: - workspaceScoped - assigneeScope - tenantPrefilterSource properties: workspaceScoped: type: boolean assigneeScope: type: string enum: - current_user_only tenantPrefilterSource: type: string enum: - active_tenant_context - explicit_filter - none tenantLabel: type: - string - 'null' InboxFilterDefinition: type: object required: - key - label - fixed properties: key: type: string enum: - assignee_scope - tenant - overdue - reopened - high_severity label: type: string fixed: type: boolean options: type: array items: $ref: '#/components/schemas/FilterOption' FilterOption: type: object required: - value - label properties: value: type: string label: type: string MyFindingsSummaryCounts: type: object description: Counts derived from the currently visible inbox queue after the fixed assignee scope and any active tenant, overdue, reopened, or high-severity filters are applied. required: - openAssigned - overdueAssigned properties: openAssigned: type: integer minimum: 0 overdueAssigned: type: integer minimum: 0 AssignedFindingInboxRow: type: object required: - findingId - tenantId - tenantLabel - summary - severity - status - dueState - detailUrl properties: findingId: type: integer tenantId: type: integer tenantLabel: type: string summary: type: string severity: $ref: '#/components/schemas/Badge' status: $ref: '#/components/schemas/Badge' dueAt: type: - string - 'null' format: date-time dueState: $ref: '#/components/schemas/DueState' reopened: type: boolean ownerLabel: type: - string - 'null' detailUrl: type: string navigationContext: oneOf: - $ref: '#/components/schemas/CanonicalNavigationContext' - type: 'null' DueState: type: object required: - label - tone properties: label: type: string tone: type: string enum: - calm - warning - danger InboxEmptyState: type: object required: - title - body - action properties: title: type: string body: type: string reason: type: string enum: - no_visible_assigned_work - active_tenant_prefilter_excludes_rows action: description: For `active_tenant_prefilter_excludes_rows`, clears the tenant prefilter and returns the queue to all visible tenants. For `no_visible_assigned_work`, opens the active tenant's findings list when tenant context exists; otherwise opens `/admin/choose-tenant` so the operator can establish tenant context before entering tenant findings. $ref: '#/components/schemas/ActionLink' WorkspaceOverviewMyFindingsSignalSurface: type: object required: - workspaceId - myFindingsSignal properties: workspaceId: type: integer myFindingsSignal: $ref: '#/components/schemas/MyFindingsSignal' MyFindingsSignal: type: object required: - openAssignedCount - overdueAssignedCount - isCalm - headline - cta properties: openAssignedCount: type: integer minimum: 0 overdueAssignedCount: type: integer minimum: 0 isCalm: type: boolean headline: type: string enum: - Assigned to me description: type: - string - 'null' cta: $ref: '#/components/schemas/OpenMyFindingsActionLink' FindingDetailContinuation: type: object description: Continuity payload for tenant finding detail when it is opened from the My Findings inbox. The backLink is present whenever canonical inbox navigation context is provided and may be null only for direct entry without inbox continuity context. required: - findingId - tenantId properties: findingId: type: integer tenantId: type: integer backLink: description: Present when the detail page is reached from the My Findings inbox with canonical navigation context; null only for direct navigation that did not originate from the inbox. oneOf: - $ref: '#/components/schemas/BackToMyFindingsActionLink' - type: 'null' CanonicalNavigationContext: type: object required: - source_surface - canonical_route_name properties: source_surface: type: string canonical_route_name: type: string tenant_id: type: - integer - 'null' back_label: type: - string - 'null' back_url: type: - string - 'null' ActionLink: type: object required: - label - url properties: label: type: string url: type: string OpenMyFindingsActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Open my findings BackToMyFindingsActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Back to my findings Badge: type: object required: - label properties: label: type: string color: type: - string - 'null'