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
86 lines
3.7 KiB
Markdown
86 lines
3.7 KiB
Markdown
# Phase 1 — Data Model (Spec 114: System Console Control Tower)
|
|
|
|
This feature is primarily **read-only UI** over existing platform/ops metadata.
|
|
|
|
## Entities (existing)
|
|
|
|
### Workspace (`workspaces`)
|
|
- Purpose: group tenants; scope boundary for tenant plane.
|
|
- Relevant fields: `id`, `name`, `slug`, timestamps.
|
|
- Relationships:
|
|
- `Workspace::tenants()`
|
|
- `Workspace::memberships()`
|
|
|
|
### Tenant (`tenants`)
|
|
- Purpose: customer tenant inventory + onboarding/health metadata.
|
|
- Relevant fields (high level):
|
|
- `id`, `external_id`, `name`, `workspace_id`, `status`, `environment`
|
|
- RBAC signals: `rbac_last_checked_at`, `rbac_last_setup_at`, `rbac_canary_results`, `rbac_last_warnings`
|
|
- `metadata` (array)
|
|
- Relationships:
|
|
- `Tenant::providerConnections()` → `provider_connections`
|
|
- `Tenant::permissions()` → `tenant_permissions`
|
|
- `Tenant::auditLogs()` → `audit_logs`
|
|
|
|
### ProviderConnection (`provider_connections`)
|
|
- Purpose: connectivity + health-check metadata for external provider.
|
|
- Relevant fields: `provider`, `is_default`, `scopes_granted`, `last_health_check_at`, `metadata`.
|
|
|
|
### TenantPermission (`tenant_permissions`)
|
|
- Purpose: cached/recorded permission checks.
|
|
- Relevant fields: `key` (permission name), `status`, `details`, `last_checked_at`.
|
|
|
|
### OperationRun (`operation_runs`)
|
|
- Purpose: canonical operations observability record (non-negotiable per constitution).
|
|
- Relevant fields:
|
|
- identity/scope: `workspace_id` (NOT NULL), `tenant_id` (nullable), `user_id` (nullable), `initiator_name`
|
|
- lifecycle: `type`, `status` (`queued|running|completed`), `outcome` (`pending|succeeded|failed|canceled|…`)
|
|
- audit UX: `summary_counts` (numeric-only keys), `failure_summary` (sanitized bounded array), `context` (sanitized/limited)
|
|
- timing: `created_at`, `started_at`, `completed_at`
|
|
|
|
### AuditLog (`audit_logs`)
|
|
- Purpose: security/audit trail.
|
|
- Relevant fields: `workspace_id`, `tenant_id` (nullable), `actor_*`, `action`, `status`, `metadata` (sanitized), `recorded_at`.
|
|
- System console relevant actions (already emitted):
|
|
- `platform.auth.login`
|
|
- `platform.break_glass.enter|exit|expired`
|
|
|
|
## Derived/Computed concepts (new, no new table)
|
|
|
|
### Time window
|
|
- Enumerated: `1h`, `24h` (default), `7d`.
|
|
- Used for Control Tower and for failures/stuck scoping.
|
|
|
|
### “Stuck” run classification
|
|
- Definition: a run is “stuck” when:
|
|
- `status=queued` and `created_at <= now() - queued_threshold_minutes` AND `started_at IS NULL`, OR
|
|
- `status=running` and `started_at <= now() - running_threshold_minutes`
|
|
- Thresholds are configurable (v1):
|
|
- `system_console.stuck_thresholds.queued_minutes`
|
|
- `system_console.stuck_thresholds.running_minutes`
|
|
|
|
### Tenant/workspace health badge
|
|
- “Worst wins” aggregation over signals:
|
|
- Tenant status (active/onboarding/archived)
|
|
- Provider connection health/status
|
|
- Permission status
|
|
- Recent failed/stuck runs within the time window
|
|
- Display-only; does not mutate state.
|
|
|
|
## Validation rules
|
|
- Any operator-provided reason/note (break-glass, mark investigated): min length 5, max length 500.
|
|
- Filters: only allow known enum values (time window, run status/outcome).
|
|
|
|
## Storage/indexing plan (Phase 2 tasks will implement)
|
|
- `operation_runs`:
|
|
- Indexes to support windowed queries and grouping:
|
|
- `(workspace_id, created_at)`
|
|
- `(tenant_id, created_at)`
|
|
- optional: `(status, outcome, created_at)` and `(type, created_at)` depending on explain plans
|
|
- `audit_logs`:
|
|
- `(action, recorded_at)` and `(actor_id, recorded_at)` for Access Logs filters
|
|
|
|
## Notes on data minimization
|
|
- Use `RunFailureSanitizer` + `SummaryCountsNormalizer` contracts.
|
|
- Avoid rendering raw `context` by default; when displayed, cap size and redact sensitive keys.
|