TenantAtlas/specs/240-tenant-onboarding-readiness/research.md
ahmido ab6eccaf40
Some checks failed
Main Confidence / confidence (push) Failing after 48s
feat: add onboarding readiness workflow (#277)
## Summary
- add derived onboarding readiness to the managed tenant onboarding workflow and multi-draft picker
- keep provider-specific permission diagnostics secondary while preserving canonical `Open operation` and existing onboarding action semantics
- add spec-kit artifacts for `240-tenant-onboarding-readiness` and align roadmap/spec-candidate planning notes
- unify the required-permissions empty state copy to English

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- browser smoke exercised the onboarding picker, route-bound mismatch readiness state, canonical `Open operation` path, and local fixture cleanup

## Notes
- branch includes the generated spec artifacts under `specs/240-tenant-onboarding-readiness/`
- temporary browser smoke tenants/drafts/runs were cleaned from the local environment after validation

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #277
2026-04-25 21:17:31 +00:00

6.7 KiB
Raw Blame History

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 specs “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.

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.

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.