Feature branch PR for Spec 114. This branch contains the merged agent session work (see merge commit on branch). Tests - `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #139
373 lines
10 KiB
YAML
373 lines
10 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: System Console Control Tower (Spec 114)
|
|
version: 0.1.0
|
|
description: |
|
|
Planning contract for System Console Control Tower read models.
|
|
|
|
NOTE: Filament/Livewire pages render server-side. This OpenAPI file documents
|
|
the intended query surfaces as if they were JSON endpoints to keep fields
|
|
and filtering semantics explicit during implementation.
|
|
servers:
|
|
- url: /system
|
|
paths:
|
|
/dashboard:
|
|
get:
|
|
summary: Control Tower KPIs
|
|
parameters:
|
|
- in: query
|
|
name: window
|
|
schema:
|
|
type: string
|
|
enum: [1h, 24h, 7d]
|
|
required: false
|
|
responses:
|
|
'200':
|
|
description: KPI + top offenders
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ControlTowerResponse'
|
|
/directory/workspaces:
|
|
get:
|
|
summary: Workspaces directory
|
|
parameters:
|
|
- in: query
|
|
name: q
|
|
schema: { type: string }
|
|
- in: query
|
|
name: health
|
|
schema:
|
|
type: string
|
|
enum: [ok, warn, critical, unknown]
|
|
responses:
|
|
'200':
|
|
description: Workspaces list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/WorkspaceListResponse'
|
|
/directory/workspaces/{workspaceId}:
|
|
get:
|
|
summary: Workspace detail
|
|
parameters:
|
|
- in: path
|
|
name: workspaceId
|
|
required: true
|
|
schema: { type: integer }
|
|
responses:
|
|
'200':
|
|
description: Workspace detail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/WorkspaceDetailResponse'
|
|
/directory/tenants:
|
|
get:
|
|
summary: Tenants directory
|
|
parameters:
|
|
- in: query
|
|
name: q
|
|
schema: { type: string }
|
|
- in: query
|
|
name: workspace_id
|
|
schema: { type: integer }
|
|
responses:
|
|
'200':
|
|
description: Tenants list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TenantListResponse'
|
|
/directory/tenants/{tenantId}:
|
|
get:
|
|
summary: Tenant detail
|
|
parameters:
|
|
- in: path
|
|
name: tenantId
|
|
required: true
|
|
schema: { type: integer }
|
|
responses:
|
|
'200':
|
|
description: Tenant detail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/TenantDetailResponse'
|
|
/ops/runs:
|
|
get:
|
|
summary: Global operation runs
|
|
parameters:
|
|
- in: query
|
|
name: window
|
|
schema:
|
|
type: string
|
|
enum: [1h, 24h, 7d]
|
|
- in: query
|
|
name: status
|
|
schema:
|
|
type: string
|
|
enum: [queued, running, completed]
|
|
- in: query
|
|
name: outcome
|
|
schema:
|
|
type: string
|
|
- in: query
|
|
name: type
|
|
schema:
|
|
type: string
|
|
- in: query
|
|
name: workspace_id
|
|
schema: { type: integer }
|
|
- in: query
|
|
name: tenant_id
|
|
schema: { type: integer }
|
|
responses:
|
|
'200':
|
|
description: Runs list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RunListResponse'
|
|
/ops/runs/{runId}:
|
|
get:
|
|
summary: Canonical run detail
|
|
parameters:
|
|
- in: path
|
|
name: runId
|
|
required: true
|
|
schema: { type: integer }
|
|
responses:
|
|
'200':
|
|
description: Run detail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RunDetailResponse'
|
|
/ops/failures:
|
|
get:
|
|
summary: Failed runs (prefilter)
|
|
parameters:
|
|
- in: query
|
|
name: window
|
|
schema:
|
|
type: string
|
|
enum: [1h, 24h, 7d]
|
|
responses:
|
|
'200':
|
|
description: Failed runs list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RunListResponse'
|
|
/ops/stuck:
|
|
get:
|
|
summary: Stuck runs (prefilter)
|
|
parameters:
|
|
- in: query
|
|
name: window
|
|
schema:
|
|
type: string
|
|
enum: [1h, 24h, 7d]
|
|
responses:
|
|
'200':
|
|
description: Stuck runs list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/RunListResponse'
|
|
/security/access-logs:
|
|
get:
|
|
summary: Access logs
|
|
parameters:
|
|
- in: query
|
|
name: window
|
|
schema:
|
|
type: string
|
|
enum: [1h, 24h, 7d]
|
|
- in: query
|
|
name: actor_id
|
|
schema: { type: integer }
|
|
- in: query
|
|
name: status
|
|
schema:
|
|
type: string
|
|
enum: [success, failure]
|
|
responses:
|
|
'200':
|
|
description: Access logs list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/AccessLogListResponse'
|
|
components:
|
|
schemas:
|
|
ControlTowerResponse:
|
|
type: object
|
|
required: [window, kpis, top_offenders]
|
|
properties:
|
|
window: { type: string }
|
|
kpis:
|
|
type: object
|
|
additionalProperties: { type: integer }
|
|
top_offenders:
|
|
type: array
|
|
items:
|
|
type: object
|
|
required: [dimension, id, label, failed_count]
|
|
properties:
|
|
dimension: { type: string, enum: [tenant, workspace, run_type] }
|
|
id: { type: integer }
|
|
label: { type: string }
|
|
failed_count: { type: integer }
|
|
WorkspaceListResponse:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
WorkspaceDetailResponse:
|
|
type: object
|
|
required: [workspace]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
tenants:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/TenantSummary'
|
|
TenantListResponse:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/TenantSummary'
|
|
TenantDetailResponse:
|
|
type: object
|
|
required: [tenant]
|
|
properties:
|
|
tenant:
|
|
$ref: '#/components/schemas/TenantSummary'
|
|
provider_connections:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ProviderConnectionSummary'
|
|
permissions:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/TenantPermissionSummary'
|
|
recent_runs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RunSummary'
|
|
RunListResponse:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RunSummary'
|
|
RunDetailResponse:
|
|
type: object
|
|
required: [run]
|
|
properties:
|
|
run:
|
|
allOf:
|
|
- $ref: '#/components/schemas/RunSummary'
|
|
- type: object
|
|
properties:
|
|
summary_counts:
|
|
type: object
|
|
additionalProperties: { type: integer }
|
|
failure_summary:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/RunFailure'
|
|
context:
|
|
type: object
|
|
additionalProperties: true
|
|
AccessLogListResponse:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AccessLogEntry'
|
|
WorkspaceSummary:
|
|
type: object
|
|
required: [id, name, slug]
|
|
properties:
|
|
id: { type: integer }
|
|
name: { type: string }
|
|
slug: { type: string }
|
|
tenant_count: { type: integer }
|
|
health: { type: string, enum: [ok, warn, critical, unknown] }
|
|
last_activity_at: { type: string, format: date-time, nullable: true }
|
|
TenantSummary:
|
|
type: object
|
|
required: [id, external_id, name, workspace_id]
|
|
properties:
|
|
id: { type: integer }
|
|
external_id: { type: string }
|
|
name: { type: string }
|
|
workspace_id: { type: integer }
|
|
status: { type: string }
|
|
environment: { type: string, nullable: true }
|
|
health: { type: string, enum: [ok, warn, critical, unknown] }
|
|
last_activity_at: { type: string, format: date-time, nullable: true }
|
|
ProviderConnectionSummary:
|
|
type: object
|
|
required: [provider, is_default]
|
|
properties:
|
|
provider: { type: string }
|
|
is_default: { type: boolean }
|
|
last_health_check_at: { type: string, format: date-time, nullable: true }
|
|
health: { type: string, nullable: true }
|
|
TenantPermissionSummary:
|
|
type: object
|
|
required: [key, status]
|
|
properties:
|
|
key: { type: string }
|
|
status: { type: string }
|
|
last_checked_at: { type: string, format: date-time, nullable: true }
|
|
RunSummary:
|
|
type: object
|
|
required: [id, workspace_id, type, status, outcome, created_at]
|
|
properties:
|
|
id: { type: integer }
|
|
workspace_id: { type: integer }
|
|
tenant_id: { type: integer, nullable: true }
|
|
type: { type: string }
|
|
status: { type: string }
|
|
outcome: { type: string }
|
|
initiator_name: { type: string }
|
|
created_at: { type: string, format: date-time }
|
|
started_at: { type: string, format: date-time, nullable: true }
|
|
completed_at: { type: string, format: date-time, nullable: true }
|
|
RunFailure:
|
|
type: object
|
|
required: [code, message]
|
|
properties:
|
|
code: { type: string }
|
|
reason_code: { type: string, nullable: true }
|
|
message: { type: string }
|
|
AccessLogEntry:
|
|
type: object
|
|
required: [id, recorded_at, action, status]
|
|
properties:
|
|
id: { type: integer }
|
|
recorded_at: { type: string, format: date-time }
|
|
action: { type: string }
|
|
status: { type: string }
|
|
actor_id: { type: integer, nullable: true }
|
|
actor_email: { type: string, nullable: true }
|
|
actor_name: { type: string, nullable: true }
|
|
ip: { type: string, nullable: true }
|
|
user_agent: { type: string, nullable: true }
|