# Implementation Plan: Spec 333 - Restore Create UX Final Productization - **Branch**: `333-restore-create-ux-final-productization` - **Date**: 2026-05-26 - **Spec**: `specs/333-restore-create-ux-final-productization/spec.md` - **Input**: Productize Restore Create wizard UX over Spec 332 foundation. No new flow system, presenter, or backend rewrite. ## Summary Finalize the visible Restore Create wizard as a coherent restore safety workflow: - Step 1: source decision, backup quality, full gates, proof. - Step 2: calm scope summary, mapping summary by default, explicit resolver mode, group picker context. - Step 3: product-safe validation, grouped blockers/warnings/safe checks, provider credential blocked state. - Step 4: summary-first preview, needs-attention first, compact unchanged detail, gate-consistent next step. - Step 5: high-friction confirmation, dry-run clarity, proof-safe pre-execution copy. Implementation must consume Spec 332 state truth from `RestoreRunCreatePresenter` and existing Product Process Flow components. It must not add backend behavior, persistence, Graph calls, packages, or new architecture. ## Technical Context **Language/Version**: PHP 8.4.15, Laravel 12.52.0 **Primary Dependencies**: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1 **Storage**: Existing PostgreSQL-backed models only; no migration **Testing**: Pest Feature/Livewire, Unit, and Browser **Validation Lanes**: confidence + browser + formatting **Target Platform**: Laravel Sail local, Dokploy container runtime for staging/production **Project Type**: Laravel monolith with Filament admin panel **Performance Goals**: keep wizard rendering DB/local-state based; no Graph calls during render; long lists collapsed/compact **Constraints**: no new packages, no migrations, no queues/scheduler/storage/env changes, no new Product Process Flow system **Scale/Scope**: one existing environment-bound Restore Create wizard and its focused tests/screenshots ## Repo Truth Summary Existing foundation: - Presenter source of truth: `apps/platform/app/Filament/Resources/RestoreRunResource/Presenters/RestoreRunCreatePresenter.php` - Wizard/page entry: `apps/platform/app/Filament/Resources/RestoreRunResource.php` - Create page wrapper: `apps/platform/app/Filament/Resources/RestoreRunResource/Pages/CreateRestoreRun.php` - Restore Create components: - `apps/platform/resources/views/filament/forms/components/restore-run-safety-decision.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-backup-quality-summary.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-safety-gates.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-proof-aside.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-scope-summary.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-mapping-resolver-summary.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-checks.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-preview.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-confirm-panel.blade.php` - `apps/platform/resources/views/filament/forms/components/restore-run-group-mapping-skipped.blade.php` - `apps/platform/resources/views/filament/forms/components/partials/restore-run-process-flow-panel.blade.php` - `apps/platform/resources/views/filament/forms/components/partials/restore-run-proof-panel.blade.php` - Group picker: - `apps/platform/app/Livewire/EntraGroupCachePickerTable.php` - `apps/platform/resources/views/livewire/entra-group-cache-picker-table.blade.php` - `apps/platform/resources/views/filament/modals/entra-group-cache-picker.blade.php` - Existing related tests: - `apps/platform/tests/Feature/Filament/Spec332ProductProcessFlowSystemTest.php` - `apps/platform/tests/Browser/Spec332RestoreRunWizardProductProcessFlowSmokeTest.php` - `apps/platform/tests/Browser/Spec332RestoreRunWizardProductProcessFlowScreenshotsTest.php` - `apps/platform/tests/Feature/Filament/RestoreRunPreviewProductizationTest.php` - `apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php` - `apps/platform/tests/Feature/RestoreGroupMappingTest.php` - `apps/platform/tests/Unit/Filament/RestoreRunCreatePresenterDeterminismTest.php` ## UI / Surface Guardrail Plan - **Guardrail scope**: changed surfaces - **Affected routes/pages/actions/states/navigation/panel/provider surfaces**: - Restore Create wizard at `/admin/workspaces/{workspace}/environments/{environment}/restore-runs/create` - Step 1 source decision state - Step 2 scope/mapping resolver state - group picker modal - Step 3 validation state - Step 4 preview state - Step 5 confirmation/execution readiness state - **No-impact class, if applicable**: N/A - **Native vs custom classification summary**: mixed Filament wizard/forms/actions plus existing custom Blade components - **Shared-family relevance**: Product Process Flow, proof panels, status messaging, action links, dangerous confirmation - **State layers in scope**: page, wizard step, presenter contract, modal, Livewire table - **Audience modes in scope**: operator-MSP and support-platform; no customer-facing route added - **Decision/diagnostic/raw hierarchy plan**: decision first, proof second, diagnostics/raw third/collapsed - **Raw/support gating plan**: raw IDs secondary, raw payloads/diffs collapsed or behind disclosure - **One-primary-action / duplicate-truth control**: presenter contract owns status/reason/impact/next-action; Blade renders it without computing alternate truth - **Handling modes by drift class or surface**: review-mandatory because this is a dangerous workflow - **Repository-signal treatment**: review-mandatory for restore/gating/proof copy - **Special surface test profiles**: dangerous workflow wizard + browser smoke - **Required tests or manual smoke**: focused Feature/Livewire, Unit presenter determinism, Browser screenshots - **Exception path and spread control**: none planned - **Active feature PR close-out entry**: Smoke Coverage - **UI/Productization coverage decision**: existing route/archetype coverage remains valid; Spec 333 screenshots provide focused coverage - **Coverage artifacts to update**: none unless implementation discovers route/archetype/coverage drift - **No-impact rationale**: N/A - **Navigation / Filament provider-panel handling**: no panel/provider registration change - **Screenshot or page-report need**: screenshots required, page report not required unless drift is discovered ## Shared Pattern & System Fit - **Cross-cutting feature marker**: yes - **Systems touched**: Restore Create wizard, Product Process Flow, Restore Proof, status messaging, group picker, validation/preview/confirmation panels - **Shared abstractions reused**: `RestoreRunCreatePresenter`, existing restore-run Blade components, `BadgeRenderer`, `OperationRunLinks`, restore safety/preview/check integrity resolvers - **New abstraction introduced? why?**: none - **Why the existing abstraction was sufficient or insufficient**: sufficient; Spec 332 intentionally centralized the product-state contract and Product Process Flow - **Bounded deviation / spread control**: display-only tweaks may stay in existing components but cannot calculate independent gate/proof truth ## OperationRun UX Impact - **Touches OperationRun start/completion/link UX?**: presentation only - **Central contract reused**: existing restore execution behavior and `OperationRunLinks` - **Delegated UX behaviors**: existing start/completion/notification behavior remains unchanged - **Surface-owned behavior kept local**: restore inputs, dry-run/preview-only toggle, typed confirmation, pre-execution proof copy - **Queued DB-notification policy**: N/A - **Terminal notification path**: N/A - **Exception path**: none ## Provider Boundary & Portability Fit - **Shared provider/platform boundary touched?**: yes, display-only - **Provider-owned seams**: Entra group cache, Microsoft/provider connection readiness - **Platform-core seams**: environment, restore scope, proof basis, operation proof, post-run evidence - **Neutral platform terms / contracts preserved**: environment, provider connection, restore scope, target mapping, operation proof, post-run evidence - **Retained provider-specific semantics and why**: directory group and object ID wording remains where the existing Entra group mapping boundary requires it - **Bounded extraction or follow-up path**: broader provider readiness productization deferred to follow-up ## Constitution Check *GATE: Must pass before implementation. Re-check after implementation.* - **Inventory-first / snapshots-second**: pass; Restore Create uses existing backup snapshots and restore draft state. - **Read/write separation**: pass; preview/dry-run and explicit confirmation remain required before execution. - **Graph contract path**: pass; no new Graph calls. Existing Graph behavior remains behind existing services/contracts. - **Deterministic capabilities**: pass; existing capability checks remain authoritative. - **RBAC-UX**: pass; no UI-only authorization changes. Existing server-side authorization/capability checks remain required. - **Workspace/tenant isolation**: pass; existing route-bound workspace/environment context remains in force; group picker must use current environment cache only. - **Run observability / OperationRun UX**: pass; no new OperationRun behavior. - **Test governance**: pass; lane classification is explicit and bounded. - **Proportionality / no premature abstraction**: pass; no new presenter, framework, persistence, enum, taxonomy, or backend layer. - **Provider boundary**: pass; provider-specific wording remains only at existing provider-owned group/provider seams. - **Filament-native UI**: pass with existing mixed custom components; implementation must keep Filament semantics and no ad-hoc styling system. - **UI/Productization coverage**: pass; reachable UI changes are classified and screenshots are required. ## Test Governance Check - **Test purpose / classification by changed surface**: - Unit: presenter determinism and no static memoization/leakage. - Feature/Livewire: wizard state, copy, gating, grouped validation, preview summary, confirmation readiness. - Browser: visible multi-step workflow and screenshots. - **Affected validation lanes**: confidence + browser. - **Why this lane mix is the narrowest sufficient proof**: Restore Create is a Livewire wizard with browser-visible behavior and high-risk state gates; pure unit/feature tests alone cannot prove visible layout/screenshot requirements. - **Narrowest proving commands**: - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament/Spec333RestoreCreateUxFinalProductizationTest.php tests/Feature/RestoreGroupMappingTest.php tests/Feature/Filament/RestoreWizardGraphSafetyTest.php tests/Feature/Filament/RestoreRunPreviewProductizationTest.php tests/Unit/Filament/RestoreRunCreatePresenterDeterminismTest.php --compact` - `cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec333RestoreCreateUxFinalProductizationSmokeTest.php --compact` - **Fixture / helper / factory / seed / context cost risks**: use existing Spec 332 browser fixtures/helpers where possible; do not create broad shared defaults. - **Expensive defaults or shared helper growth introduced?**: no planned shared default growth. - **Heavy-family additions, promotions, or visibility changes**: explicit Spec 333 browser smoke only. - **Surface-class relief / special coverage rule**: no standard relief; dangerous workflow requires browser smoke/screenshots. - **Closing validation and reviewer handoff**: run targeted Feature/Unit/Browser tests, Spec 332 overlap tests, Pint dirty, and `git diff --check`; report full suite if not run. - **Budget / baseline / trend follow-up**: none expected unless browser fixture runtime materially grows. - **Review-stop questions**: lane fit, breadth, hidden fixture cost, browser screenshot reliability, no false proof copy. - **Escalation path**: document-in-feature. - **Active feature PR close-out entry**: Smoke Coverage. - **Why no dedicated follow-up spec is needed**: this is bounded final productization of one existing wizard; post-execution proof belongs to a separate follow-up. ## Project Structure ### Documentation (this feature) ```text specs/333-restore-create-ux-final-productization/ ├── spec.md ├── plan.md ├── tasks.md ├── restore-create-state-contract.md ├── checklists/ │ └── requirements.md └── artifacts/ └── screenshots/ └── .gitkeep ``` ### Source Code (expected implementation surfaces) ```text apps/platform/app/Filament/Resources/ ├── RestoreRunResource.php └── RestoreRunResource/ ├── Pages/CreateRestoreRun.php └── Presenters/RestoreRunCreatePresenter.php apps/platform/resources/views/filament/forms/components/ ├── restore-run-safety-decision.blade.php ├── restore-run-backup-quality-summary.blade.php ├── restore-run-safety-gates.blade.php ├── restore-run-proof-aside.blade.php ├── restore-run-scope-summary.blade.php ├── restore-run-mapping-resolver-summary.blade.php ├── restore-run-checks.blade.php ├── restore-run-preview.blade.php ├── restore-run-confirm-panel.blade.php └── restore-run-group-mapping-skipped.blade.php apps/platform/resources/views/livewire/ └── entra-group-cache-picker-table.blade.php apps/platform/resources/views/filament/modals/ └── entra-group-cache-picker.blade.php ``` ### Test Code (expected implementation surfaces) ```text apps/platform/tests/Feature/Filament/Spec333RestoreCreateUxFinalProductizationTest.php apps/platform/tests/Feature/RestoreGroupMappingTest.php apps/platform/tests/Feature/Filament/RestoreWizardGraphSafetyTest.php apps/platform/tests/Feature/Filament/RestoreRunPreviewProductizationTest.php apps/platform/tests/Unit/Filament/RestoreRunCreatePresenterDeterminismTest.php apps/platform/tests/Browser/Spec333RestoreCreateUxFinalProductizationSmokeTest.php ``` ## Domain / Model Implications - No model changes. - No migration. - No new restore backend behavior. - No new OperationRun type. - No provider gateway change. - Existing `RestoreRun`, `BackupSet`, `BackupItem`, `EntraGroup`, `ManagedEnvironment`, provider connection, validation, and preview state remain the data sources. ## UI / Filament Implications - Filament v5 / Livewire v4.1 compliance remains required. - Panel provider registration remains unchanged in `apps/platform/bootstrap/providers.php`; no new panel/provider. - `RestoreRunResource` keeps existing View page; global search behavior is not changed by this spec and must be verified if touched. - Destructive/high-impact behavior is not changed. Real restore execution remains gated by existing dry-run/preview, validation, confirmation, authorization, and audit behavior. - No registered Filament assets are planned, so no new `filament:assets` deployment step is introduced. ## Implementation Phases ### Phase 1 - State Contract / Repo Truth - Re-read Spec 332 artifacts, current presenter/components, and this Spec 333 state contract. - Confirm `RestoreRunCreatePresenter` is the single source of truth. - Confirm no static/process-level memoization. - Update runtime only after state contract alignment is clear. ### Phase 2 - Step 1 Polish - Align Step 1 source states to required copy. - Ensure backup quality summary exposes required counts and caveat. - Keep full gates and proof panel visible. - Remove internal/technical/false-proof copy. ### Phase 3 - Step 2 Scope / Mapping / Group Picker - Keep default Step 2 calm and summary-first. - Hide mapping details by default. - Productize resolver row identity and single collapse action. - Preserve or explicitly state skip behavior. - Make group picker context and empty states current-environment safe. - Keep Next blocked by unresolved mappings. ### Phase 4 - Step 3 Validation - Group blockers, warnings, and safe checks. - Make provider credentials missing a product-safe blocked state. - Fix toast copy when blockers exist. - Keep next state-aware and blocked when validation is blocked. ### Phase 5 - Step 4 Preview - Make preview summary-first. - Show needs attention first. - Collapse or compact unchanged/no-change items. - Hide raw diff/provider payload by default. - Correct next-gate copy for current/blocked/not-generated states. ### Phase 6 - Step 5 Confirmation - Make confirmation high-friction. - Make dry-run/preview-only state clear. - Show pre-execution operation proof and post-run evidence as unavailable. - Ensure execute availability remains controlled by existing gates and capability behavior. ### Phase 7 - Tests / Browser / Screenshots - Add or adjust focused Feature/Unit tests. - Add browser smoke and screenshots. - Run targeted validation commands. - Re-run Spec 332 overlap tests if shared components changed. ## Validation Commands ```bash cd apps/platform ./vendor/bin/sail artisan test \ tests/Feature/Filament/Spec333RestoreCreateUxFinalProductizationTest.php \ tests/Feature/RestoreGroupMappingTest.php \ tests/Feature/Filament/RestoreWizardGraphSafetyTest.php \ tests/Feature/Filament/RestoreRunPreviewProductizationTest.php \ tests/Unit/Filament/RestoreRunCreatePresenterDeterminismTest.php \ --compact ``` ```bash cd apps/platform ./vendor/bin/sail php vendor/bin/pest \ tests/Browser/Spec333RestoreCreateUxFinalProductizationSmokeTest.php \ --compact ``` ```bash cd apps/platform ./vendor/bin/sail artisan test --filter=Spec332 --compact ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec332* --compact ./vendor/bin/sail pint --dirty git diff --check ``` ## Rollout / Deployment Considerations - **Migrations**: none. - **Environment variables**: none. - **Queues/workers**: none. - **Scheduler**: none. - **Storage/volumes**: none. - **Packages/assets**: none. - **Dokploy/Staging/Production**: ordinary app deployment only; validate on Staging because restore is high-risk UI. - **Filament assets**: no new registered assets planned; if implementation unexpectedly registers assets, deployment must include `cd apps/platform && php artisan filament:assets` and this plan must be updated first. ## Risk Controls - Do not implement a new flow system or presenter. - Do not move truth into Blade. - Do not add backend restore behavior. - Do not overclaim recovery, operation proof, post-run evidence, health, or customer safety. - Do not use raw IDs as primary labels. - Do not expose raw provider errors/payloads by default. - Do not broaden tests into unrelated surfaces. - Update spec/plan before implementation if repo truth differs from assumptions.