## Summary - harden nested Filament and Livewire tenant-context handling across the backup schedule operation runs relation manager, managed-environment triage arrival continuity, the backup set policy picker table, and the Operate Hub shell - add architecture, feature, and browser coverage for nested Filament tenant-context continuity and restore-run resource behavior - add the Spec 334 artifacts (`spec.md`, `plan.md`, `tasks.md`, and the requirements checklist) ## Testing - Not run as part of this commit/push/PR workflow Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #395
93 lines
7.1 KiB
Markdown
93 lines
7.1 KiB
Markdown
# Tasks: Spec 334 - Nested Filament / Livewire Context Contract Hardening
|
|
|
|
- Input: `specs/334-nested-filament-context-contract-hardening/spec.md`, `specs/334-nested-filament-context-contract-hardening/plan.md`
|
|
- Prerequisites: `spec.md`, `plan.md`
|
|
|
|
**Tests**: Required. This is runtime-hardening for nested operator surfaces with authorization/scope impact.
|
|
|
|
## Test Governance Checklist
|
|
|
|
- [x] Lane assignment is explicit and is the narrowest sufficient proof for the changed behavior.
|
|
- [x] New tests stay in the smallest honest family (Feature/Livewire + one architecture guard; browser smoke only for the two user-visible regressions).
|
|
- [x] New helpers/factories/seeds/context defaults stay cheap by default.
|
|
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
|
|
- [x] Any deviation resolves as `document-in-feature`, `follow-up-spec`, or `reject-or-split`.
|
|
|
|
## Phase 1: Preparation And Repo Truth
|
|
|
|
**Purpose**: Confirm repo truth and capture the current failure paths before touching runtime code.
|
|
|
|
- [x] T001 Re-read `spec.md`, `plan.md`, and this `tasks.md`.
|
|
- [x] T002 Confirm working tree intent and record baseline commit (`git status`, `git log -1`).
|
|
- [x] T003 Verify confirmed scope file paths exist and inspect current context usage:
|
|
- `apps/platform/app/Livewire/BackupSetPolicyPickerTable.php`
|
|
- `apps/platform/app/Filament/Resources/RestoreRunResource.php`
|
|
- `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php`
|
|
- `apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php`
|
|
- `apps/platform/app/Filament/Widgets/ManagedEnvironment/ManagedEnvironmentTriageArrivalContinuity.php`
|
|
- `apps/platform/app/Support/OperateHub/OperateHubShell.php`
|
|
- `apps/platform/app/Support/Workspaces/WorkspaceContext.php`
|
|
- [x] T004 Capture the current Add Policies modal failure path (tenantless modal → checkbox column hidden) and record the exact call chain and where tenant/context is read.
|
|
- Captured via regression: `apps/platform/tests/Feature/Filament/BackupSetPolicyPickerTableTest.php` and browser smoke `apps/platform/tests/Browser/Spec334NestedFilamentContextContractSmokeTest.php`.
|
|
- [x] T005 Capture the current Restore Run Create wizard failure path (Livewire update request without route params → tenant resolver throws) and record the exact call chain and closure(s) involved.
|
|
- Captured via regression: `apps/platform/tests/Feature/Filament/RestoreRunResourceLivewireTenantContextTest.php` (real Livewire update payload) + browser smoke `apps/platform/tests/Browser/Spec334NestedFilamentContextContractSmokeTest.php`.
|
|
- [x] T006 Decide whether any shared helper is justified (≥2 confirmed consumers). If not, keep fixes local to each surface + the existing shared seam.
|
|
- No new helper introduced (ABSTR-001). Shared seam hardening applied in `apps/platform/app/Support/OperateHub/OperateHubShell.php`.
|
|
|
|
## Phase 2: Guardrails And Regression Tests (before refactor)
|
|
|
|
**Purpose**: Lock “fail-closed and scoped” behavior and block unsafe tenant switching patterns before implementation refactors.
|
|
|
|
- [x] T007 Add an architecture guard test: `apps/platform/tests/Architecture/FilamentTenantContextContractTest.php`.
|
|
- Detect and fail on unsafe `Filament::setTenant($model->...)` patterns in nested surfaces without explicit allowlist.
|
|
- Keep an explicit allowlist limited to infrastructure-only context selection locations.
|
|
- [x] T008 Add a regression test covering Add Policies picker behavior when ambient tenant is null (authorized user still sees row selection and can select).
|
|
- [x] T009 Add a regression test covering Restore Run Create wizard Livewire update lifecycle (no crash when route params are missing; options are scoped).
|
|
- [x] T010 Add a regression test for BackupSchedule operation runs relation manager scope (owner record scopes query; ambient tenant missing/wrong does not broaden).
|
|
- [x] T011 Add a regression test for the triage widget context (record context preferred; ambient tenant is fallback; missing context fails closed).
|
|
|
|
## Phase 3: Implement Nested Context Contract (confirmed surfaces only)
|
|
|
|
**Purpose**: Apply the contract to the confirmed high-risk surfaces without a broad tenancy rewrite.
|
|
|
|
- [x] T012 Harden `apps/platform/app/Livewire/BackupSetPolicyPickerTable.php`:
|
|
- Resolve context from validated BackupSet ownership (workspace + managed environment).
|
|
- Scope table query by resolved environment.
|
|
- Re-resolve and re-authorize at mutation time (bulk action).
|
|
- Never silently override mismatched ambient tenant.
|
|
- [x] T013 Harden `apps/platform/app/Filament/Resources/RestoreRunResource.php`:
|
|
- Ensure option closures used during Livewire updates can resolve validated environment context without route params.
|
|
- Livewire update context recovery is implemented in the shared seam: `apps/platform/app/Support/OperateHub/OperateHubShell.php` (validated referer path candidate for `/livewire-*/update` requests).
|
|
- Referer is treated as a candidate only; access is still validated via workspace + membership + operability checks.
|
|
- [x] T014 Harden `apps/platform/app/Filament/Concerns/ResolvesPanelTenantContext.php` only if the seam is shared and the fix is not restore-specific.
|
|
- No change required (the shared seam hardening in `OperateHubShell` unblocks the failing lifecycle).
|
|
- [x] T015 Harden `apps/platform/app/Filament/Resources/BackupScheduleResource/RelationManagers/BackupScheduleOperationRunsRelationManager.php`:
|
|
- Prefer owner schedule record as primary context (`$this->getOwnerRecord()`).
|
|
- Remove dependencies on ambient tenant where owner context exists.
|
|
- [x] T016 Harden `apps/platform/app/Filament/Widgets/ManagedEnvironment/ManagedEnvironmentTriageArrivalContinuity.php`:
|
|
- Prefer widget record context.
|
|
- Use one resolver consistently for visibility and mutation checks.
|
|
- Fail closed when context is missing.
|
|
|
|
## Phase 4: Browser Smoke (required because the original bugs were user-visible)
|
|
|
|
- [x] T017 Backup Set Add Policies smoke:
|
|
- Open Backup Set detail → Add Policies.
|
|
- Verify policies are visible and row selection checkbox column is visible.
|
|
- Select one or more rows; verify “Add selected” path works.
|
|
- [x] T018 Restore Run Create wizard smoke:
|
|
- Open Restore Runs → Create.
|
|
- Trigger Livewire interactions (wizard next/previous, selections).
|
|
- Verify no “no tenant context selected” crash.
|
|
|
|
## Phase 5: Validation
|
|
|
|
- [x] T019 Run narrow tests first (confidence lane):
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Architecture --filter='FilamentTenantContextContract' --compact`
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament --filter='BackupSetPolicyPicker|RestoreRun|BackupScheduleOperationRuns|Triage' --compact`
|
|
- [ ] T020 Run broader related suites only if needed (keep lane cost honest):
|
|
- `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Filament --compact`
|
|
- [x] T021 Run `cd apps/platform && ./vendor/bin/sail pint --dirty` and `git diff --check`.
|
|
- [x] T022 Report full-suite status honestly if not run.
|
|
- Full suite not executed; this spec was validated via targeted Feature/Architecture tests + a dedicated browser smoke file.
|