## Summary - add the implementation-ready spec-prep artifacts for Spec 280: Filament Workspace Tenancy & Environment Routing Cutover - define the bounded scope, rollout constraints, route contract, and validation plan for the workspace-first routing cutover - update the generated Copilot agent context for the active feature branch ## Testing - not run; this branch adds spec-prep artifacts only and does not change application code ## Notes - no application runtime, database, or frontend code changes are included in this PR - target base branch requested: `platform-dev` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #336
422 lines
13 KiB
YAML
422 lines
13 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: TenantPilot Admin - Workspace Tenancy & Environment Routing Cutover (Conceptual)
|
|
version: 0.1.0
|
|
description: |
|
|
Conceptual GET-route contract for Spec 280.
|
|
|
|
This package removes the temporary `/admin/t/{environment}` public shell,
|
|
makes `Workspace` the only Filament tenant for operator admin routing, and
|
|
moves managed-environment work under workspace-first routes rooted at
|
|
`/admin/workspaces/{workspace}`.
|
|
servers:
|
|
- url: /admin
|
|
paths:
|
|
/:
|
|
get:
|
|
summary: Resolve the operator admin entrypoint
|
|
description: |
|
|
Direct `/admin` requests resolve to workspace selection or the active
|
|
workspace dashboard. `/admin` is not a second canonical managed-
|
|
environment dashboard route after this cutover.
|
|
responses:
|
|
'302':
|
|
description: Redirect to workspace selection or the active workspace dashboard
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
x-logical-outcomes:
|
|
- route: /admin/choose-workspace
|
|
when: no valid workspace context exists
|
|
- route: /admin/workspaces/{workspace}
|
|
when: a valid workspace context exists
|
|
/workspaces/{workspace}:
|
|
get:
|
|
summary: Open the canonical workspace dashboard
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
responses:
|
|
'200':
|
|
description: Workspace dashboard rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/WorkspaceDashboardView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
/workspaces/{workspace}/environments:
|
|
get:
|
|
summary: Open the canonical workspace-scoped environment chooser
|
|
description: |
|
|
Reuses the existing workspace-bound environment-selection surface and
|
|
replaces any need for a second public chooser route.
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
responses:
|
|
'200':
|
|
description: Environment chooser rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/EnvironmentChooserView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
/workspaces/{workspace}/environments/{environment}:
|
|
get:
|
|
summary: Open the canonical managed-environment dashboard
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
- $ref: '#/components/parameters/ManagedEnvironmentIdentifier'
|
|
responses:
|
|
'200':
|
|
description: Managed-environment dashboard rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/ManagedEnvironmentDashboardView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
managed_environment_membership: required
|
|
/workspaces/{workspace}/environments/{environment}/required-permissions:
|
|
get:
|
|
summary: Open required permissions under workspace-first environment routing
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
- $ref: '#/components/parameters/ManagedEnvironmentIdentifier'
|
|
responses:
|
|
'200':
|
|
description: Required permissions page rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/ManagedEnvironmentPageView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
managed_environment_membership: required
|
|
/workspaces/{workspace}/operations:
|
|
get:
|
|
summary: Open the canonical workspace operations hub
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
- $ref: '#/components/parameters/ManagedEnvironmentFilter'
|
|
- $ref: '#/components/parameters/TenantScope'
|
|
- $ref: '#/components/parameters/ActiveTab'
|
|
- $ref: '#/components/parameters/ProblemClass'
|
|
responses:
|
|
'200':
|
|
description: Workspace operations hub rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/WorkspaceOperationsView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
managed_environment_membership: conditional-when-filtered
|
|
/workspaces/{workspace}/operations/{run}:
|
|
get:
|
|
summary: Open the canonical operation run detail viewer
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
- $ref: '#/components/parameters/OperationRunIdentifier'
|
|
responses:
|
|
'200':
|
|
description: Operation run detail rendered
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
x-logical-view-model:
|
|
$ref: '#/components/schemas/OperationRunDetailView'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-capability-rules:
|
|
workspace_membership: required
|
|
run_visibility: tenant-safe-within-workspace
|
|
/w/{workspace}/managed-tenants:
|
|
get:
|
|
summary: Legacy workspace-scoped managed-tenants chooser route removed
|
|
description: |
|
|
Spec 280 removes `/admin/w/{workspace}/managed-tenants` and replaces it
|
|
with the canonical workspace-first environment chooser at
|
|
`/admin/workspaces/{workspace}/environments`. No redirect or
|
|
compatibility alias survives.
|
|
parameters:
|
|
- $ref: '#/components/parameters/WorkspaceIdentifier'
|
|
responses:
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-removed-by-spec: 280
|
|
/operations:
|
|
get:
|
|
summary: Legacy workspace operations collection route removed
|
|
description: |
|
|
Spec 280 removes `/admin/operations` in favor of
|
|
`/admin/workspaces/{workspace}/operations`. No redirect or compatibility
|
|
alias survives.
|
|
responses:
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-removed-by-spec: 280
|
|
/operations/{run}:
|
|
get:
|
|
summary: Legacy workspace operations detail route removed
|
|
description: |
|
|
Spec 280 removes `/admin/operations/{run}` in favor of
|
|
`/admin/workspaces/{workspace}/operations/{run}`. No redirect or
|
|
compatibility alias survives.
|
|
parameters:
|
|
- $ref: '#/components/parameters/OperationRunIdentifier'
|
|
responses:
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-removed-by-spec: 280
|
|
/t/{environment}:
|
|
get:
|
|
summary: Legacy environment panel route removed
|
|
description: |
|
|
Spec 280 removes the public `/admin/t/{environment}` route family. No
|
|
redirect or compatibility alias survives.
|
|
parameters:
|
|
- $ref: '#/components/parameters/ManagedEnvironmentIdentifier'
|
|
responses:
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-removed-by-spec: 280
|
|
/tenants/{environment}/required-permissions:
|
|
get:
|
|
summary: Legacy required-permissions route removed
|
|
description: |
|
|
Spec 280 removes `/admin/tenants/{environment}/required-permissions`
|
|
and replaces it with the workspace-first environment route family.
|
|
parameters:
|
|
- $ref: '#/components/parameters/ManagedEnvironmentIdentifier'
|
|
responses:
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
x-removed-by-spec: 280
|
|
components:
|
|
parameters:
|
|
WorkspaceIdentifier:
|
|
name: workspace
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
ManagedEnvironmentIdentifier:
|
|
name: environment
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
OperationRunIdentifier:
|
|
name: run
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: integer
|
|
ManagedEnvironmentFilter:
|
|
name: managed_environment_id
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
description: Optional explicit environment prefilter inside the active workspace.
|
|
TenantScope:
|
|
name: tenant_scope
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
enum: [all]
|
|
ActiveTab:
|
|
name: activeTab
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
ProblemClass:
|
|
name: problemClass
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
responses:
|
|
Forbidden:
|
|
description: Actor is in scope but lacks the required capability on the workspace or managed environment.
|
|
NotFound:
|
|
description: Wrong workspace, wrong managed environment, removed legacy route, or non-member access is hidden as not found.
|
|
schemas:
|
|
WorkspaceSummary:
|
|
type: object
|
|
required: [id, name, slug]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
name:
|
|
type: string
|
|
slug:
|
|
type: string
|
|
ManagedEnvironmentSummary:
|
|
type: object
|
|
required: [id, workspace_id, slug, name, lifecycle_status]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
workspace_id:
|
|
type: integer
|
|
slug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
lifecycle_status:
|
|
type: string
|
|
BreadcrumbSegment:
|
|
type: object
|
|
required: [label, url]
|
|
properties:
|
|
label:
|
|
type: string
|
|
url:
|
|
type: string
|
|
WorkspaceDashboardView:
|
|
type: object
|
|
required: [workspace, overview_payload, environment_chooser_url, operations_url]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
overview_payload:
|
|
type: object
|
|
additionalProperties: true
|
|
environment_chooser_url:
|
|
type: string
|
|
operations_url:
|
|
type: string
|
|
EnvironmentChooserItem:
|
|
type: object
|
|
required: [id, slug, name, lifecycle_status, open_url]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
slug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
lifecycle_status:
|
|
type: string
|
|
posture_hint:
|
|
type: string
|
|
nullable: true
|
|
open_url:
|
|
type: string
|
|
EnvironmentChooserView:
|
|
type: object
|
|
required: [workspace, environments]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
environments:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/EnvironmentChooserItem'
|
|
switch_workspace_url:
|
|
type: string
|
|
nullable: true
|
|
ManagedEnvironmentDashboardView:
|
|
type: object
|
|
required: [workspace, managed_environment, breadcrumbs, operations_url]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
managed_environment:
|
|
$ref: '#/components/schemas/ManagedEnvironmentSummary'
|
|
breadcrumbs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/BreadcrumbSegment'
|
|
dashboard_summary:
|
|
type: object
|
|
additionalProperties: true
|
|
operations_url:
|
|
type: string
|
|
ManagedEnvironmentPageView:
|
|
type: object
|
|
required: [workspace, managed_environment, breadcrumbs, page_label, operations_url]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
managed_environment:
|
|
$ref: '#/components/schemas/ManagedEnvironmentSummary'
|
|
breadcrumbs:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/BreadcrumbSegment'
|
|
page_label:
|
|
type: string
|
|
operations_url:
|
|
type: string
|
|
WorkspaceOperationsView:
|
|
type: object
|
|
required: [workspace]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
managed_environment_id:
|
|
type: integer
|
|
nullable: true
|
|
active_tab:
|
|
type: string
|
|
nullable: true
|
|
problem_class:
|
|
type: string
|
|
nullable: true
|
|
nav_context:
|
|
type: object
|
|
nullable: true
|
|
additionalProperties: true
|
|
OperationRunDetailView:
|
|
type: object
|
|
required: [workspace, run_id]
|
|
properties:
|
|
workspace:
|
|
$ref: '#/components/schemas/WorkspaceSummary'
|
|
managed_environment:
|
|
$ref: '#/components/schemas/ManagedEnvironmentSummary'
|
|
nullable: true
|
|
run_id:
|
|
type: integer
|
|
back_link_url:
|
|
type: string
|
|
nullable: true |