TenantAtlas/specs/069-managed-tenant-onboarding-wizard/plan.md
2026-02-01 12:20:09 +01:00

128 lines
5.0 KiB
Markdown

# Implementation Plan: Managed Tenant Onboarding Wizard v1
**Branch**: `069-managed-tenant-onboarding-wizard` | **Date**: 2026-01-31 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from [specs/069-managed-tenant-onboarding-wizard/spec.md](spec.md)
## Summary
Implement a tenant-plane onboarding wizard under `/admin` that:
- renders DB-only (no outbound HTTP during render/mount)
- persists resumable onboarding sessions (non-secret payload)
- triggers verification via enqueue-only `OperationRun` records
- enforces RBAC-UX semantics (non-member 404; member missing capability 403 + disabled UI)
- redirects/removes legacy onboarding entry points (notably `/admin/new`)
## Technical Context
**Language/Version**: PHP 8.4.x
**Primary Dependencies**: Laravel 12, Filament v5, Livewire v4
**Storage**: PostgreSQL (Sail)
**Testing**: Pest v4
**Target Platform**: Web app (tenant-plane `/admin`, platform-plane `/system`)
**Project Type**: Laravel monolith
**Performance Goals**:
- Wizard step render: DB-only
- Operation starts: authorize + create/reuse `OperationRun` + enqueue only
**Constraints**:
- No outbound HTTP during render/mount (DB-only render).
- Verification/health checks must be enqueue-only and observable via `OperationRun`.
- Capability checks must use the canonical registry `App\\Support\\Auth\\Capabilities` (no raw strings).
- Credential secrets must be encrypted at rest and must never be displayed back to the user.
**Scale/Scope**: Admin workflow; correctness + auditability prioritized.
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Inventory-first: Wizard renders from stored state only (tenant fields + last run summaries), not live Graph.
- Graph contract path: Any Graph verification work (when implemented) must go through the existing Graph abstraction and contract registry.
- RBAC-UX: tenant-plane `/admin` only; non-member access is 404; member missing capability is 403; UI disabled state is not authorization.
- Run observability: all verification actions create/reuse an `OperationRun` and enqueue work; no synchronous external calls.
- Data minimization: onboarding session payload excludes secrets; failures are stable codes + sanitized messages.
Status: PASS.
## Project Structure
### Documentation (this feature)
```text
specs/069-managed-tenant-onboarding-wizard/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
└── contracts/
└── onboarding-wizard.md
```
### Source Code (repository root)
```text
app/
├── Filament/ # Filament resources/pages
├── Models/ # Eloquent models
├── Providers/Filament/ # Panel providers
├── Services/ # OperationRun + provider gates + auth resolvers
└── Support/ # RBAC helpers, middleware, capability registry
bootstrap/
└── providers.php # Laravel 11+ provider registration
config/
└── graph_contracts.php
database/
└── migrations/
routes/
└── web.php
tests/
├── Feature/
└── Unit/
```
**Structure Decision**: Laravel monolith; Filament v5 discovery conventions for pages/resources.
## Phase 0 — Outline & Research
Output: [research.md](research.md)
All NEEDS CLARIFICATION items: none remaining.
## Phase 1 — Design & Contracts
Outputs:
- [data-model.md](data-model.md)
- [contracts/onboarding-wizard.md](contracts/onboarding-wizard.md)
- [quickstart.md](quickstart.md)
Agent context update required after these artifacts:
- Run `.specify/scripts/bash/update-agent-context.sh copilot`
Constitution re-check (post-design): PASS.
## Phase 2 — Task Planning (produced by `/speckit.tasks`)
Planned task groups:
1. Data layer: `tenant_onboarding_sessions` migration + model.
2. Wizard UI: tenant-plane Filament page with 5 steps (DB-only render).
3. RBAC mapping (canonical registry):
- Start/resume onboarding (spec: `managed_tenants.create`) → `Capabilities::TENANT_MANAGE`
- Manage onboarding fields/credentials (spec: `managed_tenants.manage`) → `Capabilities::TENANT_MANAGE`
- View tenant + wizard (spec: `managed_tenants.view`) → `Capabilities::TENANT_VIEW`
- Enqueue provider connection checks / verification runs (spec: `operations.run`) → `Capabilities::PROVIDER_RUN`
- Enqueue inventory sync (optional) → `Capabilities::TENANT_INVENTORY_SYNC_RUN`
4. Operations: enqueue-only verification action(s) backed by `OperationRunService`.
5. Legacy routes: redirect `/admin/new` to the existing “Choose tenant” entry point (`/admin/choose-tenant`).
6. Tests (Pest): resume/dedupe, RBAC 404/403 behavior, and run creation/dedupe.
## Complexity Tracking
N/A — no constitution violations require justification.
| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| [e.g., 4th project] | [current need] | [why 3 projects insufficient] |
| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] |