99 lines
4.2 KiB
Markdown
99 lines
4.2 KiB
Markdown
# 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.
|