# Research: Self-Service Tenant Onboarding & Connection Readiness **Branch**: `240-tenant-onboarding-readiness` **Date**: 2026-04-25 **Spec**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/spec.md` **Plan**: `/Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/plan.md` ## Decisions ### D-001 — Keep readiness derived inside the existing onboarding workflow **Decision**: Compose onboarding readiness inside the existing `ManagedTenantOnboardingWizard` and related landing/draft-picker rendering, using current onboarding, provider connection, verification, and permission-posture truth. Do not add an onboarding-readiness table, persisted projection, or new readiness enum. **Rationale**: The repo already stores the durable workflow truth in `TenantOnboardingSession`, `ProviderConnection`, `OperationRun`, and existing permission-posture data. `OnboardingLifecycleService` already computes checkpoint and action-required state, while `ProviderConnectionSurfaceSummary` and verification-assist builders already expose the provider and permissions detail needed for an operator-facing summary. **Alternatives considered**: - Add a dedicated onboarding-readiness model or table: rejected because the summary is derived and has no independent lifecycle. - Introduce a reusable cross-provider onboarding framework: rejected because the current release has one provider and already has sufficient provider-owned seams. ### D-002 — Reuse the current landing route behavior instead of creating a new onboarding register **Decision**: Keep `/admin/onboarding` as the workspace-scoped entry point that either redirects to the single resumable draft or renders the existing multi-draft picker. Add compact readiness snippets to that same picker rather than introducing a second onboarding dashboard or register. **Rationale**: `ManagedTenantOnboardingWizard::resolveLandingState()` already treats the landing route and the route-bound draft as one workflow surface. `OnboardingDraftPickerTest` proves that the picker already carries stage, attribution, and resume/view actions. Adding readiness context there keeps the operator in the same workflow instead of splitting decision-making across multiple pages. **Alternatives considered**: - New onboarding-list resource or canonical register: rejected because it would duplicate draft-selection semantics and enlarge scope. - Landing-only summary without draft-picker enrichment: rejected because operators with multiple drafts still need draft-level readiness to choose the correct draft. ### D-003 — Reuse existing freshness signals; do not invent a new onboarding freshness policy **Decision**: Treat readiness freshness as a composition of existing signals only: - `OnboardingLifecycleService` connection-change and selected-connection mismatch signals (`connection_recently_updated`, `verification_result_stale`), and - `TenantRequiredPermissionsViewModelBuilder::deriveFreshness()` for stored permission posture freshness (current repo rule: stale when absent or older than 30 days). Do not introduce a second onboarding-specific freshness threshold, new config key, or persisted freshness state in this slice. **Rationale**: The spec’s “freshness” requirement can be satisfied by existing repo truth without creating new semantics. The onboarding workflow already downgrades mismatched or changed verification evidence to action-required, while permission posture already carries a timestamp-based freshness rule used by verification-assist detail. **Alternatives considered**: - Add a new configurable verification-run age threshold for onboarding: rejected because there is no existing shared onboarding policy for it, and this slice should not create one. - Persist freshness state on the onboarding draft: rejected because freshness is a derived presentation concern from existing evidence timestamps and mismatch flags. ### D-004 — Keep permission and consent diagnostics provider-owned and secondary **Decision**: Use `ProviderConnectionSurfaceSummary`, `VerificationAssistViewModelBuilder`, and `TenantRequiredPermissionsViewModelBuilder` to expose provider-specific consent and permission detail as secondary diagnostics beneath a platform-neutral readiness summary. **Rationale**: The top-level operator question is provider-neutral: “Is this tenant ready, and what should I do next?” The exact remediation details still need Microsoft-specific wording today, and those seams already exist in the repo. **Alternatives considered**: - Flatten Microsoft-specific permission names into a new platform-core readiness taxonomy: rejected because it would deepen provider coupling in shared UI semantics. - Hide detailed permission context from onboarding entirely: rejected because the operator still needs precise remediation guidance without opening raw operation data first. ### D-005 — Preserve shared OperationRun link and start semantics **Decision**: Any readiness CTA that opens evidence or reuses verification/bootstrap actions must stay on the current shared OperationRun and Ops-UX paths: `OperationRunLinks`, existing onboarding `tenantlessOperationRunUrl(...)`, `OperationUxPresenter`, and `ProviderOperationStartResultPresenter`. **Rationale**: The workflow already starts verification as queued work and already links to canonical operation detail. This feature only changes explanation and action prioritization, not run creation semantics. **Alternatives considered**: - Create onboarding-specific run links or custom queued messaging: rejected because it would violate the shared OperationRun UX contract. - Add a new readiness “refresh” operation type: rejected because the current verification and bootstrap actions already exist. ### D-006 — Prove the slice with fast-feedback onboarding and policy coverage only **Decision**: Keep validation in fast-feedback by extending existing onboarding feature tests and policy/unit coverage. The primary proof set is `ManagedTenantOnboardingWizardTest`, `OnboardingDraftPickerTest`, `OnboardingDraftAuthorizationTest`, `TenantOnboardingSessionPolicyTest`, and `TenantRequiredPermissionsFreshnessTest`. **Rationale**: The workflow is server-driven Filament/Livewire UI with existing fixtures. Feature tests can prove landing behavior, draft rendering, readiness wording, next-action precedence, and 404 vs 403 semantics without adding new browser or heavy-governance families. **Alternatives considered**: - New browser smoke coverage as the primary proof: rejected because the feature is DB-driven and already covered by focused feature tests. - Unit-only coverage for a new summary builder: rejected because the main risk is integrated workflow rendering and authorization semantics, not pure transformation logic.