## Summary - replace the legacy Tenant and TenantMembership core models with ManagedEnvironment and ManagedEnvironmentMembership - propagate the managed environment naming and key changes across Filament resources, pages, controllers, jobs, models, and supporting runtime paths - add feature 279 spec artifacts and focused managed-environment test coverage for model behavior, route binding, panel context, authorization, and legacy guardrails ## Validation - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` ## Notes - branch pushed from commit `1123b122` - browser smoke test file was added but not run in this pass Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #335
16 KiB
| description |
|---|
| Task list for Workspace-first Managed Environment Core Cutover |
Tasks: Workspace-first Managed Environment Core Cutover
Input: Design documents from specs/279-workspace-managed-environment-core/
Prerequisites: specs/279-workspace-managed-environment-core/spec.md, specs/279-workspace-managed-environment-core/plan.md, specs/279-workspace-managed-environment-core/checklists/requirements.md, specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.md, specs/279-workspace-managed-environment-core/research.md, specs/279-workspace-managed-environment-core/data-model.md, specs/279-workspace-managed-environment-core/quickstart.md, specs/279-workspace-managed-environment-core/contracts/managed-environment-core-cutover.logical.openapi.yaml
Tests: REQUIRED (Pest). Keep proof bounded to one managed-environment unit family, one managed-environment feature family, one narrow browser smoke, and one legacy-core guard family.
Operations: No new OperationRun family. Existing operation links must resolve the new managed-environment context correctly.
RBAC: Workspace membership remains the first 404 boundary. Managed-environment membership remains the second 404 boundary. In-scope capability denials stay 403.
Shared Pattern Reuse: Reuse WorkspaceContext, existing panel-provider seams, current query helpers, TenantOwnedModelFamilies, and OperationRunLinks. Do not create an adapter layer or second context stack.
Filament / Panel Guardrails: Filament remains v5 on Livewire v4. Provider registration remains unchanged in apps/platform/bootstrap/providers.php. No new panel, no second public route family, and no new asset strategy are allowed.
Organization: Tasks are grouped by user story so core entity cutover, panel/context rebinding, and legacy-core removal remain independently reviewable.
Review Outcome: documentation-required-exception
Workflow Outcome: keep
Test-governance Outcome: keep
Test Governance Checklist
- Lane assignment stays
fast-feedback,confidence, and one narrowbrowserlane. - New or changed tests stay in
apps/platform/tests/Unit/ManagedEnvironment/,apps/platform/tests/Feature/ManagedEnvironment/, and one narrow browser smoke file only. - Fixture replacement stays explicit; no tenant compatibility fixtures remain as defaults.
- Planned validation commands match
spec.md,plan.md, andquickstart.mdexactly. - The
/admin/t/{environment}path retention is tracked as an exception note, not as an uncontrolled compatibility layer. - Any attempt to absorb Spec
280-287work resolves assplitorreject-or-split, not hidden scope.
Phase 1: Setup (Shared Context)
Purpose: Confirm the current tenant-core seams and the bounded cutover inventory before runtime changes begin.
- T001 Review
specs/279-workspace-managed-environment-core/spec.md,plan.md,checklists/requirements.md,research.md,data-model.md, andquickstart.mdtogether so the slice stays on the first reserved cutover only. - T001a Before any implementation-phase task starts, confirm
specs/279-workspace-managed-environment-core/checklists/constitution-scope-001-exception.mdstill governs the cutover or replace it with the actual.specify/memory/constitution.mdamendment reference; if neither exists, stop the implementation loop. - T002 [P] Confirm the current core seam in
apps/platform/app/Models/Tenant.php,Workspace.php, and the current tenant-membership model family. - T003 [P] Confirm the current panel and current-context seam in
apps/platform/app/Providers/Filament/TenantPanelProvider.php,ChooseTenant.php,WorkspaceContext.php, and the tenant-context helper traits. - T004 [P] Use
apps/platform/app/Support/WorkspaceIsolation/TenantOwnedModelFamilies.phpplus a bounded schema grep to enumerate the cutover set that still relies ontenant_idas active managed-target truth. - T004a [P] Record explicit Spec
281and282exclusions so provider-connection extraction and broader governance-artifact retargeting do not drift into the 279 implementation loop.
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Lock the new core entity, membership truth, and proving seams before panel and route rebinding begins.
Critical: No user-story work should begin until this phase is complete.
- T005 [P] Add failing unit coverage in
apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.phpfor workspace relation, route key, selectability, and provider-neutral field rules. - T006 [P] Add failing unit coverage in
apps/platform/tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.phpfor current workspace plus managed-environment resolution. - T007 [P] Add failing feature coverage in
apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.phpandManagedEnvironmentAuthorizationTest.phpfor404versus403semantics. - T008 [P] Add failing feature coverage in
apps/platform/tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.phpfor chooser-to-shell context bootstrapping on the temporary/admin/t/{environment}path. - T009 [P] Add the narrow browser smoke in
apps/platform/tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.phpfor workspace selection, managed-environment selection, and dashboard boot. - T010 Create the new
ManagedEnvironmentmodel, factory, migration(s), and managed-environment membership truth with no compatibility columns. - T011 Replace or rename the current environment-membership seam so current capability semantics apply to managed environments without broad RBAC redesign.
Checkpoint: The new managed-target root and proving seams exist before shared runtime context changes begin.
Phase 3: User Story 1 - Resolve managed environments as the active target inside a workspace (Priority: P1)
Goal: ManagedEnvironment becomes the active managed-target root and current core paths stop depending on Tenant.
Independent Test: Create a workspace plus managed environment, resolve the route key and current context, and confirm no active Tenant model is needed in the core path.
Tests for User Story 1
- T012 [P] [US1] Extend the managed-environment unit and feature tests to cover archived/inactive environments and wrong-workspace resolution.
Implementation for User Story 1
- T013 [US1] Update
Workspaceand related root models so the primary managed-target relationship becomesmanagedEnvironments()rather thantenants(). - T014 [US1] Retarget the core schema and Eloquent relations from
tenant_idtomanaged_environment_idacross the cutover set identified in Phase 1, using destructive pre-production migrations only and keeping the explicit Spec281and282exclusions intact. - T015 [US1] Replace current route-model binding, current-target resolution, and membership-aware target lookup so they resolve
ManagedEnvironmentinstead ofTenant. - T016 [US1] Remove active
App\Models\Tenantcore usage and replace tenant-specific factories, seeders, and policy anchors with managed-environment equivalents.
Checkpoint: The app has one active managed-target root entity and no mixed core noun in the main data path.
Phase 4: User Story 2 - Keep current environment-scoped surfaces operable through the cutover (Priority: P1)
Goal: The current environment-scoped shell continues to work while binding ManagedEnvironment instead of Tenant.
Independent Test: Select a workspace, enter a managed environment through the retargeted chooser, and open the current environment dashboard through the temporary shell.
Tests for User Story 2
- T017 [P] [US2] Extend
ManagedEnvironmentPanelContextTest.phpto cover chooser state, shell context chips, and current-target route builders.
Implementation for User Story 2
- T018 [US2] Update the current tenant chooser page and related context UI so operators choose managed environments inside the active workspace.
- T019 [US2] Update the current tenant-panel shell and shared tenant-context helper seams so the bound model becomes
ManagedEnvironmentwhile the/admin/t/{environment}path remains the only documented temporary exception and the finalWorkspaceFilament-tenancy switch stays deferred to Spec280. - T020 [US2] Retarget tenant-scoped query helpers, global-search scoping, environment-bound widgets, and
OperationRunLinksto the new managed-environment context. - T021 [US2] Keep broader workspace-first public routing, navigation, breadcrumbs, and copy cleanup explicitly out of scope and record any unavoidable temporary copy drift for Spec
280or286.
Checkpoint: Existing environment-scoped operator surfaces still boot and scope correctly on the new core entity.
Phase 5: User Story 3 - Remove active tenant-core drift from schema, policies, and tests (Priority: P2)
Goal: Core-owned code, tests, and guardrails stop reintroducing Tenant as platform-core truth.
Independent Test: Run the legacy-core guard suite and the grep validation to confirm no active Tenant core model or Filament tenant binding remains.
Tests for User Story 3
- T022 [P] [US3] Add failing guard coverage in
apps/platform/tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.phpfor activeApp\Models\Tenantimports,->tenant(Tenant::class)panel binding, and activetenant_idusage inside the T004 core-owned cutover inventory only.
Implementation for User Story 3
- T023 [US3] Update commands, fixtures, factories, policies, and support helpers that still instantiate or search the active managed target through
Tenant. - T024 [US3] Add bounded search-based validation for lingering core
Tenantreferences, document the only approved temporary/admin/t/{environment}path exception, and record the explicit Spec281and282residual allowlist for any remaining non-coretenant_idhits. - T025 [US3] Ensure
ManagedEnvironmentstays provider-neutral and that provider-specific identity remains in provider-owned seams only.
Checkpoint: The cutover leaves no uncontrolled tenant-core drift behind.
Phase 6: Polish & Cross-Cutting Validation
Purpose: Validate the bounded cutover and stop before the broader reserved pack is absorbed.
- T026 [P] Run
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Unit/ManagedEnvironment/ManagedEnvironmentModelTest.php tests/Unit/ManagedEnvironment/ManagedEnvironmentContextResolverTest.php). - T027 [P] Run
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Feature/ManagedEnvironment/ManagedEnvironmentRouteBindingTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentAuthorizationTest.php tests/Feature/ManagedEnvironment/ManagedEnvironmentPanelContextTest.php tests/Feature/ManagedEnvironment/LegacyTenantCoreGuardTest.php). - T028 [P] Run
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail artisan test --compact tests/Browser/Spec279ManagedEnvironmentCoreCutoverSmokeTest.php). - T029 [P] Run
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && (cd "$REPO_ROOT/apps/platform" && ./vendor/bin/sail bin pint --dirty --format agent). - T030 [P] Run
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n --fixed-strings 'App\Models\Tenant' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"andexport PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && REPO_ROOT="$(git rev-parse --show-toplevel)" && rg -n -- '->tenant\(Tenant::class' "$REPO_ROOT/apps/platform/app" "$REPO_ROOT/apps/platform/tests" "$REPO_ROOT/apps/platform/database"and confirm only approved removed-path output remains. - T031 [P] Review touched code to confirm Filament stays on Livewire v4, provider registration remains unchanged in
apps/platform/bootstrap/providers.php, any touched globally searchable resource still has edit/view eligibility or remains out of global search, no new asset registration or deployment-step change is introduced, no second public route family appears, no provider-specific identity lands onManagedEnvironment, and any touched destructive actions still preserve->requiresConfirmation()plus current authorization. - T032 [P] Record the final guardrail and test-governance outcome in the active feature close-out, including the temporary
/admin/t/{environment}exception and the mandatory follow-up ownership for Spec280.
Dependencies & Execution Order
Phase Dependencies
- Phase 1 (Setup): no dependencies; start immediately.
- Phase 2 (Foundational): depends on Phase 1, including T001a with an actual constitution-amendment reference or approved-exception artifact path, and blocks all user-story work.
- Phase 3 (US1): depends on Phase 2 and establishes the new managed-target truth.
- Phase 4 (US2): depends on Phase 2 and should land after US1 so the shell binds the finished core entity.
- Phase 5 (US3): depends on US1 and US2 so guard checks prove the final core path, not an intermediate state.
- Phase 6 (Polish): depends on all desired user stories being complete.
User Story Dependencies
- US1 (P1): independently testable after Phase 2 and is the first required cutover slice.
- US2 (P1): independently testable after Phase 2 but should ship with US1 so the current shell remains operable.
- US3 (P2): independently testable after US1 and US2 and closes the lingering legacy-core drift.
Within Each User Story
- Write the listed Pest coverage first and make it fail for the intended gap.
- Keep implementation inside current core-owned seams and do not widen into broader route/IA/provider/artifact/RBAC follow-up work.
- Re-run the narrowest relevant validation command after each story checkpoint before moving on.
Implementation Strategy
Suggested MVP Scope
- MVP = US1 + US2 together. The cutover is only reviewable if the new core entity exists and the current shell still boots on it.
Incremental Delivery
- Complete Phase 1 and Phase 2.
- Deliver US1 so the managed-target core is replaced.
- Deliver US2 so operators can still enter the environment-scoped shell.
- Deliver US3 to remove lingering legacy drift and lock guardrails.
- Finish with the focused validation and exception close-out in Phase 6.
Team Strategy
- Settle schema, model, and current-context rules first.
- Parallelize failing unit and feature test authoring before runtime edits.
- Serialize merges around panel-provider and context-helper files so the temporary route exception does not drift.
Deferred Follow-Ups / Non-Goals
- workspace-first public route-family rewrite and environment dashboard split
- provider-profile extraction and provider-scope normalization
- governance artifact naming/route retargeting polish
- RBAC scope redesign and new capability families
- copy/localization neutralization
- long-lived cutover quality gates beyond feature-local guard checks
Implementation Close-Out Notes
- Completed implementation keeps Filament v5 on Livewire v4 and leaves provider registration unchanged in
apps/platform/bootstrap/providers.php. - The current
/admin/t/{environment}shell remains the only temporary route exception; it now bindsManagedEnvironmentby slug. ManagedEnvironmentis provider-neutral: Microsoft/Graph identity resolves through provider-owned seams such asprovider_connections.- Legacy-core guard coverage confirms no exact
use App\Models\Tenant;import, no->tenant(Tenant::class)binding, and notenant_idcolumn in the first-slice core tables. - Browser smoke path covered workspace-scoped managed-environment selection through
ChooseTenant::getUrl(panel: 'admin')into/admin/t/spec-279-production. - Validation completed with the planned unit, feature, browser, Pint, syntax, and bounded regression checks; the broad planned
App\Models\Tenantgrep still returns approved longer model names such asTenantReview,TenantPermission, andTenantOnboardingSession.