Implements workspace-scoped managed tenant onboarding wizard (Filament v5 / Livewire v4) with strict RBAC (404/403 semantics), resumable sessions, provider connection selection/creation, verification OperationRun, and optional bootstrap. Removes legacy onboarding entrypoints and adds Pest coverage + spec artifacts (073). ## Summary <!-- Kurz: Was ändert sich und warum? --> ## Spec-Driven Development (SDD) - [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/` - [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md` - [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation) - [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert ## Implementation - [ ] Implementierung entspricht der Spec - [ ] Edge cases / Fehlerfälle berücksichtigt - [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes ## Tests - [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit) - [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`) ## Migration / Config / Ops (falls relevant) - [ ] Migration(en) enthalten und getestet - [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration) - [ ] Neue Env Vars dokumentiert (`.env.example` / Doku) - [ ] Queue/cron/storage Auswirkungen geprüft ## UI (Filament/Livewire) (falls relevant) - [ ] UI-Flows geprüft - [ ] Screenshots/Notizen hinzugefügt ## Notes <!-- Links, Screenshots, Follow-ups, offene Punkte --> Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.fritz.box> Reviewed-on: #88
164 lines
8.8 KiB
Markdown
164 lines
8.8 KiB
Markdown
# Implementation Plan: Unified Managed Tenant Onboarding Wizard (073)
|
|
|
|
**Branch**: `073-unified-managed-tenant-onboarding-wizard` | **Date**: 2026-02-03 | **Spec**: specs/073-unified-managed-tenant-onboarding-wizard/spec.md
|
|
**Input**: Feature specification from `specs/073-unified-managed-tenant-onboarding-wizard/spec.md`
|
|
|
|
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/scripts/` for helper scripts.
|
|
|
|
## Summary
|
|
|
|
Deliver a single, resumable onboarding wizard for Managed Tenants that: (1) identifies/upserts a managed tenant within the current workspace, (2) attaches or configures a Provider Connection, (3) runs verification asynchronously as an `OperationRun` with sanitized outcomes, and (4) optionally kicks off bootstrap operations.
|
|
|
|
Implementation approach: reuse existing primitives (`App\Models\Tenant`, Provider Connections, `provider.connection.check` operation type, workspace + tenant isolation middleware, canonical capability registries) and replace legacy tenant registration/redirect entry points with a single workspace-scoped wizard route.
|
|
|
|
## Technical Context
|
|
|
|
<!--
|
|
ACTION REQUIRED: Replace the content in this section with the technical details
|
|
for the project. The structure here is presented in advisory capacity to guide
|
|
the iteration process.
|
|
-->
|
|
|
|
**Language/Version**: PHP 8.4.x (Composer constraint: `^8.2`)
|
|
**Primary Dependencies**: Laravel 12, Filament 5, Livewire 4+, Pest 4, Sail 1.x
|
|
**Storage**: PostgreSQL (Sail) + SQLite in tests where applicable
|
|
**Testing**: Pest (via `vendor/bin/sail artisan test`)
|
|
**Target Platform**: Web app (Sail for local dev; container-based deploy on Linux)
|
|
**Project Type**: Web application (Laravel monolith)
|
|
**Performance Goals**: Onboarding UI renders DB-only; all Graph calls occur in queued work tracked by `OperationRun`; avoid N+1 via eager loading for any list/detail.
|
|
**Constraints**: Tenant isolation (404 vs 403 semantics); no secret material ever returned to the UI/logs; idempotent run-start and onboarding session resume; destructive-like actions require confirmation.
|
|
**Scale/Scope**: Workspace-scoped onboarding; expected low volume but high correctness/safety requirements.
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
|
|
GATE RESULT: PASS (no planned constitution violations).
|
|
|
|
- Inventory-first: onboarding writes only tenant metadata + configuration pointers; no inventory/snapshot side effects.
|
|
- Read/write separation: onboarding creates/updates records and starts operations; all mutating actions are authorized, audited, and tested.
|
|
- Graph contract path: verification uses existing `GraphClientInterface` methods (e.g., `getOrganization()`), and runs only in queued jobs.
|
|
- Deterministic capabilities: use `App\Support\Auth\Capabilities` + `WorkspaceRoleCapabilityMap`; add a dedicated onboarding capability granted to Owner+Manager.
|
|
- RBAC-UX semantics: workspace membership enforced via `ensure-workspace-member`; tenant membership enforced via `EnsureFilamentTenantSelected` / `DenyNonMemberTenantAccess` with deny-as-not-found (404). Missing capability returns 403.
|
|
- Destructive confirmation: any archive/delete/credential-rotation actions involved in onboarding must be `->action(...)->requiresConfirmation()`.
|
|
- Run observability: verification + optional bootstrap actions start via `OperationRun` and enqueue only; monitoring pages remain DB-only.
|
|
- Data minimization: onboarding session stores only non-secret fields; run failures store reason codes + sanitized messages.
|
|
- BADGE-001: introduce/extend Managed Tenant status badges via `BadgeCatalog` domain mapping (no per-page mapping).
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/073-unified-managed-tenant-onboarding-wizard/
|
|
├── plan.md # This file (/speckit.plan command output)
|
|
├── research.md # Phase 0 output (/speckit.plan command)
|
|
├── data-model.md # Phase 1 output (/speckit.plan command)
|
|
├── quickstart.md # Phase 1 output (/speckit.plan command)
|
|
├── contracts/ # Phase 1 output (/speckit.plan command)
|
|
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
|
|
```
|
|
|
|
### Source Code (repository root)
|
|
<!--
|
|
ACTION REQUIRED: Replace the placeholder tree below with the concrete layout
|
|
for this feature. Delete unused options and expand the chosen structure with
|
|
real paths (e.g., apps/admin, packages/something). The delivered plan must
|
|
not include Option labels.
|
|
-->
|
|
|
|
```text
|
|
app/
|
|
├── Filament/
|
|
│ ├── Pages/
|
|
│ │ └── Workspaces/
|
|
│ │ ├── ManagedTenantsLanding.php
|
|
│ │ └── (new) ManagedTenantOnboardingWizard.php
|
|
│ └── Pages/Tenancy/
|
|
│ └── RegisterTenant.php # legacy entry point to remove/disable
|
|
├── Http/Controllers/
|
|
│ └── TenantOnboardingController.php # legacy admin-consent helper; evaluate usage
|
|
├── Jobs/
|
|
│ └── ProviderConnectionHealthCheckJob.php # verification via OperationRun
|
|
├── Models/
|
|
│ ├── Tenant.php
|
|
│ ├── ProviderConnection.php
|
|
│ └── (new) TenantOnboardingSession.php
|
|
└── Services/
|
|
├── Auth/
|
|
│ ├── WorkspaceCapabilityResolver.php
|
|
│ └── WorkspaceRoleCapabilityMap.php
|
|
├── Providers/
|
|
│ ├── ProviderOperationRegistry.php
|
|
│ └── ProviderGateway.php
|
|
└── Graph/
|
|
└── GraphClientInterface.php
|
|
|
|
database/migrations/
|
|
├── (new) *_add_workspace_scoped_unique_tenant_id.php
|
|
└── (new) *_create_tenant_onboarding_sessions_table.php
|
|
|
|
routes/web.php
|
|
|
|
tests/Feature/
|
|
└── (new) ManagedTenantOnboardingWizardTest.php
|
|
```
|
|
|
|
**Structure Decision**: Laravel web application (monolith). Onboarding wizard is a Filament page mounted on a workspace-scoped route under `/admin/w/{workspace}/...` (no tenant context required to start).
|
|
|
|
## Complexity Tracking
|
|
|
|
> **Fill ONLY if Constitution Check has violations that must be justified**
|
|
|
|
| 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] |
|
|
|
|
No constitution violations are anticipated for this feature.
|
|
|
|
## Phase 0 — Outline & Research (complete)
|
|
|
|
Outputs:
|
|
|
|
- `research.md`: decisions + rationale + alternatives (no unresolved clarifications).
|
|
|
|
Key research conclusions:
|
|
|
|
- Reuse `App\Models\Tenant` as “Managed Tenant” (no new base concept), but introduce `pending` status for the onboarding lifecycle.
|
|
- Replace legacy onboarding/registration routes (`/admin/register-tenant`, redirects under `/admin/managed-tenants/*`) with a single workspace-scoped onboarding wizard.
|
|
- Use existing provider verification operation type (`provider.connection.check`) executed via `ProviderConnectionHealthCheckJob` with `OperationRun` tracking.
|
|
|
|
## Phase 1 — Design & Contracts (complete)
|
|
|
|
Outputs:
|
|
|
|
- `data-model.md`: entities, fields, relationships, validation, state transitions.
|
|
- `contracts/*`: documented HTTP routes + action contracts (OpenAPI-style where applicable).
|
|
- `quickstart.md`: dev notes, env vars, how to run tests.
|
|
|
|
Design highlights:
|
|
|
|
- Data model
|
|
- Tenants: change status lifecycle to include `pending`, ensure `workspace_id` is NOT NULL + FK, and enforce global uniqueness of `tenant_id` (Entra tenant ID) bound to exactly one workspace.
|
|
- Onboarding sessions: new table/model for resumable state (strictly non-secret) keyed by `(workspace_id, tenant_id)`.
|
|
- Authorization
|
|
- Introduce a workspace capability for onboarding (e.g., `workspace_managed_tenant.onboard`) and map it to Owner+Manager via `WorkspaceRoleCapabilityMap`.
|
|
- Enforce server-side authorization for every mutation and operation-start; 404 for non-members and cross-workspace access; 403 for members missing capability.
|
|
- Runs
|
|
- Verification is a queued `OperationRun` using `provider.connection.check`.
|
|
- Optional bootstrap actions become separate `OperationRun` types (only if they exist in the ProviderOperationRegistry).
|
|
|
|
## Phase 2 — Implementation Plan (to be executed by /speckit.tasks)
|
|
|
|
This plan intentionally stops before creating `tasks.md`.
|
|
|
|
Proposed sequencing for tasks:
|
|
|
|
1) Introduce `TenantOnboardingSession` model + migration, and add workspace-scoped uniqueness for tenants.
|
|
2) Implement `ManagedTenantOnboardingWizard` page mounted at `/admin/w/{workspace}/managed-tenants/onboarding`.
|
|
3) Wire verification start to existing `ProviderConnectionHealthCheckJob` / `provider.connection.check` operation.
|
|
4) Remove/disable legacy entry points (`RegisterTenant`, redirect routes) and ensure “not found” behavior.
|
|
5) Add Pest feature tests for: 404 vs 403 semantics, idempotency, resumability, and sanitized run outcomes.
|