TenantAtlas/specs/240-tenant-onboarding-readiness/plan.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

18 KiB

Implementation Plan: 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 Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/spec.md

Note: This template is filled in by the /speckit.plan command. See .specify/scripts/ for helper scripts.

Summary

  • Add one operator-facing, derived readiness summary to the existing managed-tenant onboarding workflow: the route-bound draft at /admin/onboarding/{onboardingDraft} always shows full readiness, while the /admin/onboarding landing surface adds compact readiness only when multiple resumable drafts exist and preserves the existing single-draft redirect behavior.
  • Reuse current onboarding draft lifecycle, provider connection summary, verification diagnostics, the existing 30-day permission freshness rule, and canonical OperationRun links instead of adding new persistence, readiness enums, or provider-generic onboarding frameworks.
  • Keep the workflow DB-only at render time, workspace- and tenant-safe, and centered on one operator decision: what blocks this tenant now and what the next action is.
  • Defer numeric completion scoring and any cross-surface readiness abstraction; later consumers must reuse the same derived onboarding truth instead of broadening this slice.

Technical Context

Language/Version: PHP 8.4 (Laravel 12) Primary Dependencies: Laravel 12 + Filament v5 + Livewire v4 + Pest; existing onboarding services (OnboardingLifecycleService, OnboardingDraftStageResolver), provider connection summary, verification assist, and Ops-UX helpers Storage: PostgreSQL via existing managed_tenant_onboarding_sessions, provider_connections, operation_runs, and stored permission-posture data; no new persistence planned Testing: Pest feature + unit tests (Filament/Livewire feature coverage plus policy/unit coverage) Validation Lanes: fast-feedback Target Platform: Sail-backed Laravel admin panel under /admin Project Type: web Performance Goals: onboarding landing and draft routes remain DB-only at render/hydration, compose readiness in-request from existing records, and avoid outbound HTTP or new queue starts during page render Constraints: preserve workspace isolation, linked-tenant entitlement checks, existing RBAC capability boundaries, provider-boundary neutrality in top-level wording, current destructive confirmation patterns, current OperationRun start UX, and no new tables/enums/frameworks for readiness Scale/Scope: one workspace-scoped onboarding workflow surface, one derived readiness composition, and focused onboarding/policy coverage only

UI / Surface Guardrail Plan

  • Guardrail scope: changed surfaces
  • Native vs custom classification summary: native Filament + shared primitives
  • Shared-family relevance: status messaging, action links, badges, embedded diagnostics, navigation
  • State layers in scope: page + workflow-step + derived summary
  • Handling modes by drift class or surface: review-mandatory
  • Repository-signal treatment: review-mandatory
  • Special surface test profiles: standard-native-filament
  • Required tests or manual smoke: functional-core
  • Exception path and spread control: existing guided-workflow exception for ManagedTenantOnboardingWizard; no new surface exemption
  • Active feature PR close-out entry: Guardrail

Shared Pattern & System Fit

  • Cross-cutting feature marker: yes
  • Systems touched: ManagedTenantOnboardingWizard, onboarding landing/draft picker, OnboardingLifecycleService, OnboardingDraftStageResolver, ProviderConnectionSurfaceSummary, VerificationAssistViewModelBuilder, TenantRequiredPermissionsViewModelBuilder, OperationRunLinks
  • Shared abstractions reused: OnboardingLifecycleService, OnboardingDraftStageResolver, ProviderConnectionSurfaceSummary, VerificationAssistViewModelBuilder, TenantRequiredPermissionsViewModelBuilder, OperationRunLinks, OperationUxPresenter, ProviderOperationStartResultPresenter
  • New abstraction introduced? why?: none; readiness stays a thin derived composition on the existing workflow surface
  • Why the existing abstraction was sufficient or insufficient: existing services already own checkpoint progression, provider connection wording, permission freshness, verification diagnostics, and canonical run links; the missing piece is a single operator-facing composition and action prioritization
  • Bounded deviation / spread control: provider-specific consent and permission names remain inside existing diagnostic detail and provider-owned next steps; top-level readiness copy stays platform-neutral, and any shared builder extension must stay additive and behavior-preserving for non-onboarding consumers while onboarding-specific prioritization remains page-local

OperationRun UX Impact

  • Touches OperationRun start/completion/link UX?: yes
  • Central contract reused: shared OperationRun UX layer via OperationRunLinks, OperationUxPresenter, and the existing onboarding tenantlessOperationRunUrl(...) helper
  • Delegated UX behaviors: queued toast, dedupe-or-blocked messaging, canonical Open operation link labeling, tenant/workspace-safe run URL resolution, and terminal lifecycle notifications remain delegated to shared Ops-UX paths
  • Surface-owned behavior kept local: readiness wording, freshness explanation, and next-action prioritization inside the onboarding workflow
  • Queued DB-notification policy: unchanged explicit opt-in; this slice does not add queued or running DB notifications
  • Terminal notification path: central lifecycle mechanism already used by reused verification/bootstrap actions
  • Exception path: none

Provider Boundary & Portability Fit

  • Shared provider/platform boundary touched?: yes
  • Provider-owned seams: consent diagnostics, missing-permission detail, provider-specific remediation next steps, target-scope identity detail
  • Platform-core seams: readiness summary, checkpoint progress, next-action labels, freshness messaging, workflow routing
  • Neutral platform terms / contracts preserved: provider connection, readiness, diagnostics, next action, freshness, onboarding step
  • Retained provider-specific semantics and why: Microsoft permission names and consent language stay inside existing verification assist and provider summary detail because the operator needs exact remediation instructions for the supported provider
  • Bounded extraction or follow-up path: none; if a second provider appears later, revisit only the provider-owned detail seam rather than the workflow shell

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

  • Persisted truth / proportionality: PASS — readiness remains derived from existing onboarding, provider connection, operation-run, and permission-posture truth; no new table, enum, or state family is planned.
  • Read/write separation / destructive actions: PASS — this slice changes operator understanding on an existing wizard; existing cancel/delete/complete actions retain current confirmation, audit, and authorization rules.
  • Graph contract path / DB-only render: PASS — render and Livewire hydration stay DB-only, reusing stored provider connection, verification, and permission-posture data with no new Graph calls.
  • RBAC / isolation: PASS — existing workspace membership, linked-tenant entitlement, and Capabilities::* gates remain authoritative; non-members and wrong-scope actors stay 404, capability-denied members stay 403.
  • Ops-UX / OperationRun link semantics: PASS — existing verification/bootstrap starts and run links continue to use shared OperationRun UX and canonical tenantless route helpers; no new run-start path is introduced.
  • Provider boundary / shared pattern reuse: PASS — provider-neutral readiness remains top-level, Microsoft-specific details stay contextual, and existing shared builders/helpers are reused before any local deviation.
  • Test governance: PASS — proof stays in fast-feedback feature/unit coverage using existing onboarding fixtures; no new browser or heavy-governance family is required.
  • Global search / panel registration: N/A — this slice changes a Filament page, not a global-searchable resource or panel provider.

Test Governance Check

  • Test purpose / classification by changed surface: Feature (wizard + landing/picker rendering and behavior) plus targeted Unit/Policy coverage for isolation semantics and existing freshness helper behavior where directly reused
  • Affected validation lanes: fast-feedback
  • Why this lane mix is the narrowest sufficient proof: the workflow is server-driven Filament/Livewire UI backed by existing models and policies, so feature tests can prove readiness composition, next-action precedence, and deny semantics without browser automation
  • Narrowest proving command(s): cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php; cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingDraftPickerTest.php tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php; cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php tests/Unit/TenantRequiredPermissionsFreshnessTest.php
  • Fixture / helper / factory / seed / context cost risks: reuse existing onboarding draft, workspace membership, tenant membership, provider connection, and operation-run fixtures; avoid adding browser fixtures or new provider mocks
  • Expensive defaults or shared helper growth introduced?: no; any new test helpers should stay onboarding-local
  • Heavy-family additions, promotions, or visibility changes: none
  • Surface-class relief / special coverage rule: standard-native-filament guided-workflow exception already exists; add feature assertions to cover the readiness summary on both landing and draft routes
  • Closing validation and reviewer handoff: rerun the targeted onboarding wizard, draft-picker/authorization, and policy/freshness tests after implementation; reviewers should verify one primary next action, correct 404 vs 403 semantics, and no render-time outbound HTTP
  • Budget / baseline / trend follow-up: none expected beyond ordinary feature-local upkeep
  • Review-stop questions: Does the slice stay in fast-feedback? Did any new fixture force browser/heavy coverage? Did the implementation introduce a second readiness taxonomy or persisted truth?
  • Escalation path: document-in-feature if a shared helper needs a tiny extension; reject-or-split if implementation tries to add new persistence/frameworks or browser-lane proof
  • Active feature PR close-out entry: Guardrail
  • Why no dedicated follow-up spec is needed: the planned proof extends already-existing onboarding suites and does not add a new recurring test cost center

Implementation Close-Out — 2026-04-25

  • Guardrail result: keep. The implementation stayed inside the existing guided onboarding page, reused current lifecycle/stage, provider summary, verification assist, permission freshness, and OperationRun link paths, and did not add persistence, enums, a readiness taxonomy, or a cross-surface framework.
  • Fast-feedback proof: cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Feature/Onboarding/OnboardingDraftPickerTest.php tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php tests/Unit/Policies/TenantOnboardingSessionPolicyTest.php tests/Unit/TenantRequiredPermissionsFreshnessTest.php passed with 55 tests and 212 assertions.
  • Provider-boundary / lane-cost decision: keep. Provider-specific permission and consent detail remains secondary and provider-owned; top-level readiness wording stays platform-neutral. No browser, heavy-governance, new fixture family, or follow-up spec is required.
  • Explicit defers retained: numeric completion score and cross-surface readiness reuse remain deferred; future consumers should reuse this derived onboarding truth rather than broaden this slice.

Project Structure

Documentation (this feature)

specs/240-tenant-onboarding-readiness/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── checklists/
│   └── requirements.md
├── contracts/
│   └── onboarding-readiness.openapi.yaml
└── tasks.md

Source Code (repository root)

apps/platform/
├── app/
│   ├── Filament/Pages/Workspaces/ManagedTenantOnboardingWizard.php
│   ├── Models/TenantOnboardingSession.php
│   ├── Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
│   ├── Services/Onboarding/
│   │   ├── OnboardingDraftStageResolver.php
│   │   └── OnboardingLifecycleService.php
│   ├── Support/OperationRunLinks.php
│   ├── Support/Providers/TargetScope/ProviderConnectionSurfaceSummary.php
│   └── Support/Verification/VerificationAssistViewModelBuilder.php
└── tests/
    ├── Feature/ManagedTenantOnboardingWizardTest.php
    ├── Feature/Onboarding/OnboardingDraftAuthorizationTest.php
    ├── Feature/Onboarding/OnboardingDraftPickerTest.php
    ├── Unit/Policies/TenantOnboardingSessionPolicyTest.php
    └── Unit/TenantRequiredPermissionsFreshnessTest.php

Structure Decision: Single Laravel web application. This feature remains confined to the existing onboarding wizard/landing workflow, existing onboarding + provider support services, and focused onboarding/policy tests.

Complexity Tracking

No constitution violations are required for this feature. The plan explicitly avoids new persistence, abstractions, readiness enums, or cross-surface frameworks.

Proportionality Review

N/A — the plan intentionally keeps readiness derived and local to the existing onboarding workflow. No new persisted entity, abstraction layer, enum/status family, or taxonomy is proposed.

Phase 0 — Research (output: research.md)

See: /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/research.md

Goals:

  • Confirm the narrowest existing sources of truth for onboarding readiness, draft landing metadata, provider summary, permission freshness, and canonical operation links.
  • Resolve the freshness question by reusing the existing 30-day permission freshness rule plus current connection-change and selected-connection-mismatch signals rather than introducing a new onboarding-specific threshold or persisted freshness model.
  • Confirm that landing-route behavior remains the same surface (single-draft redirect or multi-draft picker) so readiness context is added without creating a second onboarding register.

Phase 1 — Design & Contracts (outputs: data-model.md, contracts/, quickstart.md)

See:

  • /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/data-model.md
  • /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/contracts/onboarding-readiness.openapi.yaml
  • /Users/ahmeddarrazi/Documents/projects/wt-plattform/specs/240-tenant-onboarding-readiness/quickstart.md

Design focus:

  • Add one derived readiness composition on ManagedTenantOnboardingWizard and the existing draft picker using current draft lifecycle, provider connection summary, verification assist, the existing 30-day permission freshness rule, and explicit "check has not run yet" guidance where no evidence exists.
  • Keep landing-route behavior intact: a single resumable draft still redirects to the route-bound draft; a multi-draft landing view gains compact readiness snippets next to existing metadata.
  • Define next-action precedence from existing truth only: identify tenant → connect provider → grant consent/fix permissions → run or rerun verification → review bootstrap → complete onboarding.
  • Keep permission and consent detail secondary and provider-owned; keep Open operation and consent links canonical and shared.
  • Keep onboarding-specific readiness wording and action prioritization local to the onboarding workflow; if a shared provider or verification builder needs extension, keep the change additive and regression-safe for existing non-onboarding consumers.
  • Defer numeric completion score and any support-diagnostic or trial/demo-specific projection to later specs that reuse the same derived onboarding truth.
  • Do not add new tables, readiness enums, global resources, or provider-generic onboarding abstractions.

Phase 1 — Agent Context Update

After Phase 1 artifacts are generated, update Copilot context from the plan:

  • /Users/ahmeddarrazi/Documents/projects/wt-plattform/.specify/scripts/bash/update-agent-context.sh copilot

Phase 2 — Implementation Outline (tasks created in /speckit.tasks)

  • Extend onboarding landing and draft rendering to surface a derived readiness summary, freshness, and one primary next action from existing services/helpers.
  • Reuse OnboardingLifecycleService snapshot truth, OnboardingDraftStageResolver, ProviderConnectionSurfaceSummary, VerificationAssistViewModelBuilder, and TenantRequiredPermissionsViewModelBuilder to map existing records into operator-facing copy.
  • Add compact readiness metadata to the multi-draft picker and route-bound resume context without creating a new onboarding index resource.
  • Preserve existing consent, verification, bootstrap, operation-link, and destructive header actions; only change prioritization, grouping emphasis, and explanatory copy.
  • Expand targeted feature and policy tests for readiness states, freshness/mismatch handling, landing summary behavior, and 404 vs 403 regressions.

Constitution Check (Post-Design)

Re-check result: PASS. Design artifacts keep readiness derived, DB-only at render time, workspace/tenant safe, Ops-UX compliant, and constrained to existing onboarding + provider foundations.