TenantAtlas/specs/138-managed-tenant-onboarding-draft-identity/data-model.md
ahmido 98e2b5acd9 feat: managed tenant onboarding draft identity and resume semantics (#167)
## Summary
- add canonical managed-tenant onboarding draft routing with explicit draft identity and landing vs concrete draft behavior
- implement draft lifecycle, authorization, attribution, picker UX, resume-stage resolution, and auditable cancel or completion semantics
- add focused feature, unit, and browser coverage plus Spec 138 artifacts for the onboarding draft resume flow

## Validation
- `vendor/bin/sail artisan test --compact tests/Feature/ManagedTenantOnboardingWizardTest.php tests/Feature/Audit/OnboardingDraftAuditTest.php tests/Feature/Onboarding/OnboardingDraftAccessTest.php tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php tests/Feature/Onboarding/OnboardingDraftLifecycleTest.php tests/Feature/Onboarding/OnboardingDraftMultiTabTest.php tests/Feature/Onboarding/OnboardingDraftPickerTest.php tests/Feature/Onboarding/OnboardingDraftRoutingTest.php tests/Feature/Onboarding/OnboardingRbacSemanticsTest.php tests/Feature/Onboarding/OnboardingVerificationClustersTest.php tests/Feature/Onboarding/OnboardingVerificationTest.php tests/Feature/Onboarding/OnboardingVerificationV1_5UxTest.php tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php tests/Unit/Onboarding tests/Unit/VerificationReportSanitizerEvidenceKindsTest.php tests/Browser/OnboardingDraftRefreshTest.php tests/Browser/OnboardingDraftVerificationResumeTest.php`
- passed: 69 tests, 251 assertions

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #167
2026-03-13 23:45:23 +00:00

113 lines
3.7 KiB
Markdown

# Data Model: Managed Tenant Onboarding Draft Identity & Resume Semantics
## Primary Entity: Onboarding Draft
### Backing Model
- Existing model: `App\Models\TenantOnboardingSession`
- Existing table: `managed_tenant_onboarding_sessions`
- UI language: `Onboarding draft`
## Ownership & Authorization Model
- The onboarding draft is a workspace-scoped workflow-coordination record, not a generic tenant-owned domain record.
- `workspace_id` is mandatory for every draft.
- `tenant_id` remains nullable under the constitution-approved onboarding exception because drafts can exist before tenant identification.
- Once `tenant_id` is attached, authorization must enforce both workspace entitlement and tenant entitlement for draft access.
- Before `tenant_id` is attached, workspace entitlement is sufficient.
## Entity Fields
### Existing or Required Core Fields
| Field | Type | Purpose |
|---|---|---|
| `id` | bigint | Stable draft identity used in canonical route binding |
| `workspace_id` | bigint | Workspace isolation boundary |
| `tenant_id` | bigint nullable | Managed tenant database record when identified |
| `entra_tenant_id` | string nullable | External tenant identity used before or during tenant materialization |
| `started_by_user_id` | bigint nullable | Attribution for who created the draft |
| `updated_by_user_id` | bigint nullable | Attribution for who last confirmed a change |
| `current_step` | string nullable | Diagnostic and audit marker only |
| `state` | json nullable | Confirmed non-secret draft state |
| `completed_at` | timestamp nullable | Marks the draft as completed |
| `cancelled_at` | timestamp nullable | Marks the draft as cancelled |
| `created_at` | timestamp | Created timestamp |
| `updated_at` | timestamp | Last persisted update timestamp |
### Recommended State Payload Keys
Confirmed draft state should continue to allow only non-secret, confirmed keys such as:
- `entra_tenant_id`
- `tenant_id`
- `tenant_name`
- `environment`
- `primary_domain`
- `notes`
- `provider_connection_id`
- `selected_provider_connection_id`
- `verification_operation_run_id`
- `verification_run_id`
- `bootstrap_operation_types`
- `bootstrap_operation_runs`
- `bootstrap_run_ids`
## Lifecycle Semantics
### Resumable
A draft is resumable when all of the following are true:
- It belongs to the current workspace.
- It is authorized for the current actor.
- It is not completed.
- It is not cancelled.
### Non-Resumable
A draft is non-resumable when any of the following are true:
- It is completed.
- It is cancelled.
- It is outside the current workspace.
- It is inaccessible due to authorization.
## Derived Projections
### Draft Stage
Derived from confirmed state, not only from `current_step`:
1. No identified tenant data: `identify`
2. Tenant identified but no provider connection selected: `connect-provider`
3. Provider connection selected but verification cannot proceed or is incomplete: `verify-access`
4. Verification complete but bootstrap pending: `bootstrap`
5. Bootstrap confirmed and ready for final review or activation: `review`
6. Completed: `completed`
7. Cancelled: `cancelled`
### Draft Summary Metadata
Used by the landing picker and header banner:
- Tenant display name
- External tenant identifier
- Environment
- Current stage label
- Started by display name
- Last updated by display name
- Last updated at
- Draft age
- Verification stale or blocked hint
## Sensitive Data Rule
The following values must never be stored in the draft payload for UI rehydration:
- Client secrets
- Raw credential material
- Temporary authorization tokens
- Any secret provider credential value
The draft may store references to related provider connections or verification runs, but not secrets.