399 lines
12 KiB
YAML
399 lines
12 KiB
YAML
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' |