## Summary - add a shared tenant lifecycle presentation contract and referenced-tenant adapter for canonical lifecycle labels and helper copy - align tenant, chooser, onboarding, archived-banner, and tenantless operation viewer surfaces with the shared lifecycle vocabulary - add Spec 146 design artifacts, audit notes, and regression coverage for lifecycle presentation across Filament and onboarding surfaces ## Validation - `vendor/bin/sail bin pint --dirty --format agent` - `vendor/bin/sail artisan test --compact tests/Feature/Badges/TenantStatusBadgeTest.php tests/Unit/Badges/TenantBadgesTest.php tests/Unit/Tenants/TenantLifecycleTest.php tests/Unit/Support/Tenants/TenantLifecyclePresentationTest.php tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php tests/Feature/Filament/ReferencedTenantLifecyclePresentationTest.php tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php tests/Feature/Filament/TenantViewHeaderUiEnforcementTest.php tests/Feature/Onboarding/TenantLifecyclePresentationCopyTest.php tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php` ## Notes - Livewire v4.0+ compliance preserved; this change is presentation-only on existing Filament v5 surfaces. - Panel provider registration remains unchanged in `bootstrap/providers.php`. - No global-search behavior changed; no resource was newly made globally searchable or disabled. - No destructive actions were added or changed. - No asset registration strategy changed; existing deploy flow for `php artisan filament:assets` remains unchanged. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #175
153 lines
10 KiB
Markdown
153 lines
10 KiB
Markdown
# Implementation Plan: Central Tenant Status Presentation
|
|
|
|
**Branch**: `146-central-tenant-status-presentation` | **Date**: 2026-03-16 | **Spec**: [specs/146-central-tenant-status-presentation/spec.md](./spec.md)
|
|
**Input**: Feature specification from `/specs/146-central-tenant-status-presentation/spec.md`
|
|
|
|
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.
|
|
|
|
## Summary
|
|
|
|
Standardize tenant lifecycle rendering behind one authoritative presentation contract that extends the existing `TenantLifecycle` + `BadgeCatalog` architecture with explicit lifecycle semantics, helper copy, and invalid-data handling. Roll the shared contract through tenant list/detail summary surfaces, archived-tenant banner copy, choose-tenant and onboarding-linked surfaces, and the tenantless operations viewer plus its enterprise-detail summary payload so `draft`, `onboarding`, `active`, and `archived` always render intentionally, never as Unknown, and never get conflated with provider, verification, RBAC, or run status domains.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4.15
|
|
**Primary Dependencies**: Laravel 12, Filament 5, Livewire 4, Tailwind CSS 4
|
|
**Storage**: PostgreSQL (existing tenant and operation records only; no schema changes planned)
|
|
**Testing**: Pest 4 feature and unit tests, including Filament and Livewire coverage
|
|
**Target Platform**: Laravel Sail web application on Filament admin and workspace-canonical UI surfaces
|
|
**Project Type**: Web application monolith
|
|
**Performance Goals**: No render-time external calls, no material query-count regression on list/detail/viewer surfaces, and no extra polling or background work introduced
|
|
**Constraints**: Preserve Spec 143 lifecycle semantics and Spec 145 action semantics; do not change authorization, lifecycle transitions, selector inclusion rules, or tenant/workspace ownership; centralize badge semantics under BADGE-001; invalid fallback must be reserved for truly non-canonical data only
|
|
**Scale/Scope**: Workspace-owned tenant lifecycle presentation across tenant management, choose-tenant, onboarding-linked tenant references, and the tenantless operations viewer plus its `OperationRunResource` enterprise-detail summary payload, plus regression coverage for the primary surfaces
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
- Inventory-first: PASS. This is presentation-only work over existing tenant and canonical records. No snapshot/backfill/write behavior changes.
|
|
- Read/write separation: PASS. No new writes, previews, confirmations, queues, or audits are introduced.
|
|
- Graph contract path: PASS. No Microsoft Graph calls are added or changed.
|
|
- Deterministic capabilities: PASS. No capability derivation changes.
|
|
- RBAC-UX: PASS. Authorization planes, 404/403 semantics, membership checks, and capability enforcement remain unchanged. Canonical viewers continue to rely on existing record-level authorization before any tenant lifecycle is shown.
|
|
- Workspace isolation: PASS. No workspace-scoping changes.
|
|
- RBAC-UX destructive confirmation: PASS. No new destructive actions.
|
|
- RBAC-UX global search: PASS. This plan may touch global lifecycle presentation only if an already-authorized tenant result is rendered; it does not widen search behavior.
|
|
- Tenant isolation: PASS. No cross-tenant access changes.
|
|
- Run observability: PASS. No `OperationRun` creation, mutation, or monitoring behavior changes.
|
|
- Ops-UX 3-surface feedback: PASS. Not applicable because no `OperationRun` workflow changes are introduced.
|
|
- Ops-UX lifecycle/service ownership: PASS. No `OperationRun` transition changes.
|
|
- Ops-UX summary counts/guards/system runs: PASS. Not applicable.
|
|
- Automation/data minimization: PASS. No new jobs, locks, or logging paths.
|
|
- Badge semantics (BADGE-001): PASS WITH REQUIRED CENTRALIZATION. The implementation must extend the existing `BadgeCatalog` / `BadgeRenderer` path instead of adding local lifecycle maps.
|
|
- UI naming (UI-NAMING-001): PASS. Operator vocabulary remains `Draft`, `Onboarding`, `Active`, and `Archived`.
|
|
- Filament UI Action Surface Contract: PASS. Presentation-only changes on existing surfaces; no action-surface exemption needed.
|
|
- Filament UI UX-001 (Layout & IA): PASS. Existing layouts remain intact; lifecycle rendering changes must fit current table, infolist, and viewer structures.
|
|
|
|
**Post-Design Re-check**: PASS. Phase 1 design keeps lifecycle presentation read-only, tenant-safe, badge-centralized, and action-surface neutral.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/146-central-tenant-status-presentation/
|
|
├── plan.md
|
|
├── research.md
|
|
├── data-model.md
|
|
├── quickstart.md
|
|
├── contracts/
|
|
│ └── tenant-lifecycle-presentation.openapi.yaml
|
|
└── tasks.md
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
|
|
```text
|
|
app/
|
|
├── Filament/
|
|
│ ├── Pages/
|
|
│ │ ├── Operations/
|
|
│ │ └── Workspaces/
|
|
│ ├── Resources/
|
|
│ │ └── TenantResource.php
|
|
│ └── System/Pages/Directory/
|
|
├── Models/
|
|
│ └── Tenant.php
|
|
├── Services/
|
|
│ ├── Onboarding/
|
|
│ └── Tenants/
|
|
├── Support/
|
|
│ ├── Badges/
|
|
│ └── Tenants/
|
|
resources/
|
|
└── views/
|
|
└── filament/
|
|
├── pages/
|
|
└── widgets/
|
|
tests/
|
|
├── Feature/
|
|
│ ├── Filament/
|
|
│ ├── Onboarding/
|
|
│ └── Rbac/
|
|
└── Unit/
|
|
```
|
|
|
|
**Structure Decision**: Use the existing Laravel monolith structure and extend the current support-layer centralization points first: `app/Support/Tenants` for lifecycle semantics, `app/Support/Badges` for badge-level rendering, `app/Filament/Resources/TenantResource.php` and related pages for tenant surfaces, `app/Filament/Pages/Operations` for canonical viewer alignment, and focused Pest coverage in `tests/Feature` and `tests/Unit`.
|
|
|
|
## Phase 0 Research Summary
|
|
|
|
- Confirmed the canonical lifecycle already exists in `App\Support\Tenants\TenantLifecycle` with the exact four required values and labels.
|
|
- Confirmed badge semantics are already centralized through `BadgeCatalog`, `BadgeRenderer`, and `TenantStatusBadge`, but today that path only standardizes badge label/color/icon, not helper copy or richer cross-surface presentation density.
|
|
- Confirmed tenant list/detail and system directory tenant tables already use `BadgeDomain::TenantStatus`, while choose-tenant currently communicates lifecycle indirectly in prose, archived tenant context is surfaced through a dedicated banner view, and operation viewers derive lifecycle context through `TenantOperabilityService` plus `OperationRunResource` enterprise-detail payload data rather than a dedicated lifecycle presentation contract.
|
|
- Confirmed Filament v5 supports badge presentation through shared text/badge semantics, which aligns with continuing to feed UI badges from one renderer rather than introducing per-surface mappings.
|
|
|
|
## Phase 1 Design
|
|
|
|
### Implementation Approach
|
|
|
|
1. Introduce a dedicated tenant lifecycle presentation contract that sits on top of `TenantLifecycle` and returns:
|
|
- canonical lifecycle value
|
|
- canonical label
|
|
- badge tone/icon data
|
|
- concise helper text
|
|
- detailed helper text
|
|
- explicit invalid-data marker for non-canonical values only
|
|
2. Keep `BadgeCatalog` / `BadgeRenderer` as the badge primitive for BADGE-001 compliance, but stop treating badge spec alone as the full lifecycle presentation contract.
|
|
3. Route all in-scope lifecycle rendering through the same presentation source, with per-surface density adapters for:
|
|
- table badge only
|
|
- infolist badge plus helper text
|
|
- tenant summary and archived-banner helper copy
|
|
- selector/supporting prose
|
|
- canonical viewer referenced-tenant banner or note
|
|
4. Audit existing lifecycle render points and tenant-adjacent statuses before rollout so lifecycle remains clearly separate from provider app status, RBAC, verification, and run state and no valid-state local mapping survives outside the shared contract.
|
|
5. Add regression tests that cover all four canonical lifecycle states plus invalid-data fallback behavior, including archived-banner and canonical-view summary surfaces.
|
|
|
|
### Planned Workstreams
|
|
|
|
- **Workstream A: Central contract**
|
|
Create a single presentation object or presenter in the tenant/support layer that derives from `TenantLifecycle` and is reusable outside tables.
|
|
- **Workstream B: Tenant management surfaces**
|
|
Update tenant list/detail summary areas, archived-tenant banner content, and any onboarding-linked tenant cards/sections to use the richer contract while preserving current Filament layouts and actions.
|
|
- **Workstream C: Selector and operations viewer surfaces**
|
|
Update choose-tenant and tenantless operation viewer context copy, including referenced-tenant banners and the `OperationRunResource` enterprise-detail summary payload consumed by that viewer, to use canonical lifecycle wording when lifecycle is shown or described.
|
|
- **Workstream D: Regression hardening**
|
|
Add focused unit tests for exhaustive lifecycle mapping and feature tests for tenant index/detail summary areas, archived banner content, onboarding-linked surfaces, and operation viewers.
|
|
|
|
## Testing Strategy
|
|
|
|
- Add a focused unit test for the central lifecycle presentation contract covering `draft`, `onboarding`, `active`, `archived`, and explicit invalid fallback for non-canonical values.
|
|
- Add a focused audit pass over the existing tenant lifecycle render points before rollout so every valid-state surface is routed through the shared contract.
|
|
- Update or add tenant Filament feature tests to assert lifecycle labels on:
|
|
- tenant index table
|
|
- tenant detail identity and summary sections
|
|
- archived tenant banner copy
|
|
- choose-tenant empty or contextual copy where lifecycle is described
|
|
- Update or add canonical viewer tests to assert onboarding and archived referenced tenants render intentional lifecycle context in both the tenantless viewer banner and the `OperationRunResource`-backed summary payload rendering.
|
|
- Add at least one mixed-status assertion showing lifecycle remains distinct from provider or RBAC status on tenant detail.
|
|
- Run the minimum focused Pest suite through Sail for the touched feature and unit tests.
|
|
|
|
## Complexity Tracking
|
|
|
|
No constitution violations or exceptional complexity are planned at this stage.
|