TenantAtlas/specs/114-system-console-control-tower/contracts/system-console-control-tower.openapi.yaml
ahmido 0cf612826f feat(114): system console control tower (merged) (#139)
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
2026-02-28 00:15:31 +00:00

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 }