# Research: Managed Tenant Onboarding Wizard UI (v2) (069) This document resolves Phase 0 unknowns and captures the design decisions used by [plan.md](./plan.md). ## Decision 1 — Scope mapping ("Workspace" vs current app tenant) **Decision:** For v2, interpret **Workspace scope** and **Managed Tenant** from the spec as the existing Filament tenant model: `App\Models\Tenant`. **Rationale:** - The current app’s authorization plane, routing, and multi-tenancy are already built around `Tenant`. - Provider connections are already tenant-scoped (`provider_connections.tenant_id`). - Introducing a new Workspace/ManagedTenant hierarchy would expand the change surface (routing, policies, membership model, UI) beyond what is needed to ship the wizard + task board. **Alternatives considered:** - Add a new `workspaces` model/table with `managed_tenants` underneath it. - Rejected for Phase 1: would require reworking tenancy, membership, policies, and navigation. ## Decision 2 — Evidence as the status source-of-truth **Decision:** Step/task badges are derived from stored evidence rows; any "status" fields elsewhere are treated as derived cache. **Rationale:** - Matches FR-006 and prevents UI from being dependent on ephemeral job output. - Enables stable audit/troubleshooting and deterministic rendering (Monitoring pages remain DB-only). **Alternatives considered:** - Cache the current status directly on `Tenant`. - Rejected: easy to drift from reality and makes history/audit harder. ## Decision 3 — Task catalog representation **Decision:** Implement onboarding tasks as a small, explicit catalog (PHP enum or config-backed list) that defines: - `task_type` (stable key) - prerequisites - which OperationRun type/job implements the task - which evidence type(s) it writes **Rationale:** - Keeps task definitions centralized and testable. - Supports the task board UX (show prerequisites, last status, rerun). **Alternatives considered:** - Store task definitions in the database. - Rejected for Phase 1: adds complexity/migrations and makes review harder. ## Decision 4 — Concurrency + idempotency for task starts **Decision:** Enforce "one active run per (managed_tenant_id, task_type)" by: - Using `OperationRunService::ensureRunWithIdentity(...)` with an identity payload that includes at least `{ tenant_id, task_type }`. - Maintaining/using an active-run unique constraint for the computed identity hash. **Rationale:** - Aligns with the constitution (DB-level active run dedupe) and existing provider start-gate patterns. - Prevents double-click duplicates and conflicting task runs. **Alternatives considered:** - Application-only mutexes/locks. - Rejected: insufficient without DB-level protection. ## Decision 5 — Collaboration locking model **Decision:** Add session-level locking fields to onboarding sessions: - `locked_by_user_id` - `locked_until` **Rationale:** - Simple, explainable behavior. - Supports takeover/handoff and prevents silent overwrites. **Alternatives considered:** - Per-step/per-task fine-grained locks. - Rejected for Phase 1: higher complexity with limited user value. ## Decision 6 — Legacy (v1) onboarding migration path **Decision:** Provide a migration bridge that can: - Create a Provider Connection for a tenant if the legacy `Tenant` credential fields exist. - Move credentials into `provider_credentials` (encrypted) and stop rendering the legacy credential fields in the onboarding UI. **Rationale:** - Satisfies FR-021 without requiring a full backfill of historical run output. - Aligns with the repo’s existing secure credential patterns (`ProviderCredential` + `CredentialManager`). **Alternatives considered:** - Keep using `Tenant.app_client_secret` for v2. - Rejected: conflicts with ProviderConnection-first direction and increases leak risk. ## Decision 7 — Filament implementation shape **Decision:** Implement wizard + task board as Filament Pages/Actions. **Rationale:** - Matches current admin UI architecture. - Allows capability-gated actions with consistent RBAC UX patterns. **Alternatives considered:** - Standalone Blade controllers for v2 onboarding. - Rejected: splits patterns and complicates authorization/testing conventions.