110 lines
3.7 KiB
Markdown
110 lines
3.7 KiB
Markdown
# Route Contracts: Operations Tenantless Canonical Migration
|
|
|
|
**Feature**: 078-operations-tenantless-canonical
|
|
**Date**: 2026-02-06
|
|
|
|
---
|
|
|
|
## Canonical Routes (Retained — No Changes)
|
|
|
|
### GET /admin/operations
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Route name** | `admin.operations.index` |
|
|
| **Handler** | `App\Filament\Pages\Monitoring\Operations` |
|
|
| **Middleware** | `web`, `panel:admin`, `ensure-correct-guard:web`, `DenyNonMemberTenantAccess`, Filament middleware, `ensure-workspace-selected`, `ensure-filament-tenant-selected` |
|
|
| **Auth** | Requires authentication + workspace membership |
|
|
| **Scope** | Workspace-level (shows all runs in workspace) |
|
|
| **Response** | 200 HTML (Livewire page) |
|
|
|
|
### GET /admin/operations/{run}
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Route name** | `admin.operations.view` |
|
|
| **Handler** | `App\Filament\Pages\Operations\TenantlessOperationRunViewer` |
|
|
| **Middleware** | `web`, `panel:admin`, `ensure-correct-guard:web`, `DenyNonMemberTenantAccess`, Filament middleware |
|
|
| **Auth** | Requires authentication + workspace membership for `$run->workspace_id` |
|
|
| **Model binding** | `{run}` resolves to `OperationRun` by ID |
|
|
| **Non-member** | 404 (deny-as-not-found) |
|
|
| **Not found** | 404 (Laravel model binding) |
|
|
| **Response** | 200 HTML (Livewire page with infolist) |
|
|
|
|
---
|
|
|
|
## Decommissioned Routes (Resource-Generated Routes Removed After Migration)
|
|
|
|
### GET /admin/t/{tenant}/operations/r/{record}
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Route name** | `filament.admin.resources.operations.view` |
|
|
| **Status** | ❌ **REMOVED** — route no longer registered |
|
|
| **After migration** | Natural 404 |
|
|
| **Previously** | `ViewOperationRun` (Filament ViewRecord page) |
|
|
|
|
### GET /admin/t/{tenant}/operations
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Route name** | `filament.admin.resources.operations.index` |
|
|
| **Status** | ❌ **REMOVED** — route no longer registered |
|
|
| **After migration** | Replaced by explicit convenience route `admin.operations.legacy-index` that redirects 302 → `/admin/operations` |
|
|
| **Previously** | `ListOperationRuns` (Filament ListRecords page) |
|
|
|
|
---
|
|
|
|
## Link Generation Contracts
|
|
|
|
### OperationRunLinks::view($run, $tenant)
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Returns** | `route('admin.operations.view', ['run' => $run])` |
|
|
| **Delegates to** | `OperationRunLinks::tenantlessView($run)` |
|
|
| **Tenant parameter** | Ignored (no-op) |
|
|
| **Change** | None — already canonical |
|
|
|
|
### OperationRunLinks::tenantlessView($run)
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Returns** | `route('admin.operations.view', ['run' => $run])` |
|
|
| **Change** | None |
|
|
|
|
### OperationRunLinks::index()
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Returns** | `route('admin.operations.index')` |
|
|
| **Change** | None |
|
|
|
|
### OperationRunLinks::related($run, $tenant)
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Returns** | Array of up to 11 contextual link arrays |
|
|
| **Change** | None — consumed by `TenantlessOperationRunViewer` header actions |
|
|
|
|
---
|
|
|
|
## Test Route Assertions
|
|
|
|
### Positive (must work)
|
|
|
|
| Test | Route | Expected |
|
|
|------|-------|----------|
|
|
| T-078-001 | `GET /admin/operations/{run}` | 200 (member) |
|
|
| T-078-001 | `GET /admin/operations/{run}` | 200 (run with `tenant_id = null`) |
|
|
| T-078-009 | `GET /admin/t/{tenant}/operations` | 302 redirect to `/admin/operations` |
|
|
|
|
### Negative (must 404)
|
|
|
|
| Test | Route | Expected |
|
|
|------|-------|----------|
|
|
| T-078-001 | `GET /admin/operations/{run}` | 404 (non-member) |
|
|
| T-078-002 | `GET /admin/t/{tenant}/operations/r/{record}` | 404 (any user) |
|
|
| T-078-004 | Route name `filament.admin.resources.operations.view` | Not registered |
|
|
| T-078-004 | Route name `filament.admin.resources.operations.index` | Not registered |
|