TenantAtlas/specs/129-workspace-admin-home/contracts/workspace-home-routing.openapi.yaml
ahmido 0c709df54e Spec 129: add workspace admin home overview (#157)
## Summary
- make `/admin` the canonical workspace-level home instead of implicitly forcing tenant context
- add a new Filament workspace overview page with bounded workspace-safe widgets, quick actions, and empty states
- align panel routing, middleware, redirect helpers, and tests with the new workspace-home semantics
- add Spec 129 design artifacts, contracts, and focused Pest coverage for landing, navigation, content, operations, and authorization

## Validation
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/AdminHomeRedirectsToChooseTenantWhenWorkspaceSelectedTest.php tests/Feature/Filament/LoginRedirectsToChooseWorkspaceWhenMultipleWorkspacesTest.php tests/Feature/Filament/WorkspaceOverviewLandingTest.php tests/Feature/Filament/WorkspaceOverviewNavigationTest.php tests/Feature/Filament/WorkspaceOverviewContentTest.php tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php tests/Feature/Filament/WorkspaceOverviewOperationsTest.php tests/Feature/Filament/WorkspaceOverviewAuthorizationTest.php tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php tests/Feature/Filament/ChooseTenantRequiresWorkspaceTest.php tests/Feature/Guards/AdminWorkspaceRoutesGuardTest.php`
- `vendor/bin/sail bin pint --dirty --format agent`

## Notes
- Livewire v4.0+ compliance is preserved through Filament v5 usage.
- Panel provider registration remains in `bootstrap/providers.php` for Laravel 12.
- This feature adds a workspace overview page for the admin panel home; it does not introduce destructive actions.
- No new Filament assets were added, so there is no additional `filament:assets` deployment requirement for this branch.
- Manual browser QA for the quickstart scenarios was not completed in this session because the local browser opened at the Microsoft login flow without an authenticated test session.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #157
2026-03-09 21:53:25 +00:00

272 lines
7.2 KiB
YAML

openapi: 3.1.0
info:
title: Workspace Home Routing Contract
version: 1.0.0
description: >-
Behavioral contract for the canonical workspace-level home, adjacent chooser
routes, and the explicit downstream tenant destination introduced or relied on
by Spec 129. These routes are HTML/admin-panel endpoints, but they are modeled
here so landing and redirect semantics stay explicit.
servers:
- url: https://tenantpilot.test
paths:
/admin:
get:
summary: Open the canonical workspace home
operationId: openWorkspaceHome
tags:
- Workspace Home
responses:
'200':
description: Workspace overview page rendered for an authenticated user with a selected workspace and valid membership
content:
text/html:
schema:
$ref: '#/components/schemas/WorkspaceHomePage'
'302':
description: Redirect to the canonical workspace chooser because no workspace is selected
headers:
Location:
schema:
type: string
enum:
- /admin/choose-workspace
'404':
description: Actor is not entitled to the workspace plane or active workspace scope
/admin/choose-workspace:
get:
summary: Open the workspace selection flow
operationId: openChooseWorkspace
tags:
- Workspace Home
responses:
'200':
description: Workspace chooser rendered
content:
text/html:
schema:
$ref: '#/components/schemas/ChooseWorkspacePage'
'404':
description: Actor cannot access the admin workspace plane
/admin/choose-tenant:
get:
summary: Open the explicit tenant drill-down selector
operationId: openChooseTenant
tags:
- Workspace Home
responses:
'200':
description: Tenant chooser rendered for the active workspace
content:
text/html:
schema:
$ref: '#/components/schemas/ChooseTenantPage'
'302':
description: Redirect to workspace chooser when no workspace is selected
headers:
Location:
schema:
type: string
enum:
- /admin/choose-workspace
'404':
description: Actor is not entitled to the workspace or tenant scope
/admin/t/{tenant}:
get:
summary: Open the explicit tenant-context destination after deliberate tenant choice
operationId: openTenantDashboard
tags:
- Workspace Home
parameters:
- name: tenant
in: path
required: true
schema:
type: string
description: Canonical tenant route key selected from the chooser flow
responses:
'200':
description: Tenant-context destination rendered for a tenant the actor is entitled to access within the active workspace
'302':
description: Redirect to workspace chooser when no workspace is selected for the tenant-context request
headers:
Location:
schema:
type: string
enum:
- /admin/choose-workspace
'404':
description: Actor is not entitled to the workspace or selected tenant scope
/admin/switch-workspace:
post:
summary: Switch the active workspace context
operationId: switchWorkspaceContext
tags:
- Workspace Home
responses:
'302':
description: Workspace context changed, then redirected to the appropriate explicit post-selection destination
'403':
description: Actor is authenticated but not allowed to mutate workspace context through this action
'404':
description: Workspace target is outside actor membership scope
components:
schemas:
WorkspaceHomePage:
type: object
required:
- page
- workspace
- tenantRequired
- navigation
properties:
page:
type: string
const: workspace-home
workspace:
$ref: '#/components/schemas/WorkspaceContext'
tenantRequired:
type: boolean
const: false
summaryMetrics:
type: array
items:
$ref: '#/components/schemas/SummaryMetric'
attentionItems:
type: array
items:
$ref: '#/components/schemas/AttentionItem'
recentOperations:
type: array
items:
$ref: '#/components/schemas/RecentOperationItem'
quickActions:
type: array
items:
$ref: '#/components/schemas/QuickAction'
navigation:
type: object
required:
- overviewVisible
- brandLogoTarget
properties:
overviewVisible:
type: boolean
brandLogoTarget:
type: string
const: /admin
ChooseWorkspacePage:
type: object
required:
- page
properties:
page:
type: string
const: choose-workspace
ChooseTenantPage:
type: object
required:
- page
- workspace
properties:
page:
type: string
const: choose-tenant
workspace:
$ref: '#/components/schemas/WorkspaceContext'
WorkspaceContext:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
metadata:
type: object
additionalProperties: true
SummaryMetric:
type: object
required:
- key
- label
- value
properties:
key:
type: string
label:
type: string
value:
type: integer
destinationUrl:
type:
- string
- 'null'
AttentionItem:
type: object
required:
- title
- destinationUrl
properties:
title:
type: string
subtitle:
type:
- string
- 'null'
severity:
type:
- string
- 'null'
destinationUrl:
type: string
RecentOperationItem:
type: object
required:
- operationRunId
- title
- status
- destinationUrl
- createdAt
properties:
operationRunId:
type: integer
title:
type: string
status:
type: string
outcome:
type:
- string
- 'null'
tenantLabel:
type:
- string
- 'null'
destinationUrl:
type: string
createdAt:
type: string
format: date-time
QuickAction:
type: object
required:
- key
- label
- url
- kind
properties:
key:
type: string
label:
type: string
url:
type: string
kind:
type: string
enum:
- context
- navigation
- administration