- Canonical /admin/onboarding entry point; legacy routes 404\n- Tenantless run viewer at /admin/operations/{run} with membership-based 404\n- RBAC UX (disabled controls + tooltips) and server-side 403\n- DB-only rendering/refresh; contract registry enforced\n- Adds migrations + tests + spec artifacts
81 lines
3.0 KiB
Markdown
81 lines
3.0 KiB
Markdown
# Onboarding Wizard — Action Contracts (073)
|
||
|
||
These are conceptual contracts for the wizard’s server-side actions (Filament / Livewire).
|
||
They define inputs/outputs and authorization semantics.
|
||
|
||
## Identify tenant
|
||
|
||
- **Purpose:** Upsert or resume onboarding and ensure the managed tenant identity (Entra Tenant ID) is globally unique and bound to a single workspace.
|
||
- **Inputs:**
|
||
- `entra_tenant_id` (string)
|
||
- `environment` (string)
|
||
- `name` (string)
|
||
- `primary_domain` (string|null)
|
||
- `notes` (string|null)
|
||
- **Outputs:**
|
||
- `managed_tenant_id` (internal DB id)
|
||
- `onboarding_session_id`
|
||
- `current_step`
|
||
- **Errors:**
|
||
- 404: workspace not found, actor not a workspace member, or Entra Tenant ID exists in a different workspace (deny-as-not-found)
|
||
- 403: actor is a workspace member but lacks onboarding capability
|
||
|
||
## Select or create Provider Connection
|
||
|
||
- **Purpose:** Select an existing provider connection in the workspace or create a new one (secrets captured safely).
|
||
- **Inputs:**
|
||
- `provider_connection_id` (int|null)
|
||
- (optional) connection creation fields (non-secret identifiers only)
|
||
- **Outputs:**
|
||
- `provider_connection_id`
|
||
- `is_default` (bool)
|
||
- **Errors:**
|
||
- 404: connection/tenant not in workspace scope
|
||
- 403: member missing capability
|
||
|
||
## Start verification
|
||
|
||
- **Purpose:** Start provider connection verification asynchronously.
|
||
- **Mechanism:** Create/reuse `OperationRun` of type `provider.connection.check`, enqueue `ProviderConnectionHealthCheckJob`.
|
||
- **Inputs:** none (uses selected connection)
|
||
- **Outputs:**
|
||
- `operation_run_id`
|
||
- `status` (queued/running/succeeded/failed)
|
||
- **Errors:**
|
||
- 404: tenant/connection not in workspace scope
|
||
- 403: member missing capability
|
||
|
||
**View run link contract:**
|
||
- The UI must expose a tenantless “View run” URL: `/admin/operations/{run}`.
|
||
- Access is granted only if the actor is a member of the run’s workspace; otherwise 404 (deny-as-not-found).
|
||
|
||
## Optional bootstrap actions
|
||
|
||
- **Purpose:** Start selected post-verify operations as separate runs.
|
||
- **Inputs:** list of operation types (must exist in registry)
|
||
- **Outputs:** list of `operation_run_id`
|
||
- **Errors:**
|
||
- 403/404 semantics as above
|
||
|
||
## Activate (Complete)
|
||
|
||
- **Purpose:** Activate the managed tenant, making it available in the tenant switcher.
|
||
- **Preconditions:** Provider connection exists; verification is not Blocked unless overridden by an owner.
|
||
- **Inputs:**
|
||
- `override_blocked` (bool, optional)
|
||
- `override_reason` (string, required if override)
|
||
- **Outputs:**
|
||
- `managed_tenant_id`
|
||
- `status` (active)
|
||
- **Errors:**
|
||
- 404: managed tenant not in workspace scope / actor not a member
|
||
- 403: actor is a member but not an owner (owner-only activation); or missing capability
|
||
|
||
**Audit requirement:**
|
||
- Any override must record an audit event including the human-entered reason.
|
||
|
||
## Security & data minimization
|
||
|
||
- Stored secrets must never be returned.
|
||
- Failures are stored as stable reason codes + sanitized messages.
|