## 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
5.0 KiB
5.0 KiB
Research: Workspace-first Managed Environment Core Cutover
Date: 2026-05-06
Branch: 279-workspace-managed-environment-core
Decision 1: Use one breaking in-place cutover with no Tenant compatibility layer
- Decision: Replace
Tenantas the active managed-target core directly instead of introducing alias models, dual-read paths, or dual-write migrations. - Rationale: The repo is still pre-production, the constitution explicitly rejects speculative compatibility paths, and the current coupling spans too many seams for an adapter layer to stay honest.
- Alternatives considered:
Tenantwrapper overManagedEnvironment: rejected because it would preserve the wrong core truth and spread mixed nouns.- dual columns (
tenant_idplusmanaged_environment_id): rejected because it would violate the pre-production lean doctrine and make later specs harder, not easier.
Decision 2: Keep the current /admin/t/{environment} path temporarily as the only bounded exception
- Decision: Allow the existing public
/admin/t/{environment}path family to remain temporarily while rebinding it toManagedEnvironment. - Rationale: The current cutover already replaces the core entity, memberships, query helpers, and panel binding. Folding the full workspace-first public route rewrite into the same slice would collapse Spec
280into279and make the first cutover package too broad. - Alternatives considered:
- immediate public route-family rewrite: rejected because it belongs to Spec
280and would widen review scope too far. - second compatibility route family: rejected because the cutover must not carry two public path families at once.
- immediate public route-family rewrite: rejected because it belongs to Spec
Decision 3: Replace current tenant-context helpers in place instead of layering new adapters
- Decision: Retarget or rename the existing tenant-context seams (
WorkspaceContext, Filament panel binding, resource query helpers, global-search helpers, route builders) in place. - Rationale: The current helper seams are the correct ownership points. A new parallel
ManagedEnvironmentContextlayer wrapped around tenant helpers would create drift immediately. - Alternatives considered:
- keep tenant helpers and add environment adapters: rejected because it creates a second context vocabulary.
- local page-by-page context replacement: rejected because the problem is cross-cutting and shared.
Decision 4: Keep ManagedEnvironment provider-neutral and defer provider extraction to Spec 281
- Decision:
ManagedEnvironmentowns neutral managed-target identity only. Provider-specific fields such as Entra tenant IDs, Graph configuration, domains, or consent details stay outside the new root entity. - Rationale: The whole point of the cutover is to stop provider-specific semantics from defining the platform core. The repo already has provider-owned seams that can carry this data until Spec
281normalizes them. - Alternatives considered:
- copy current
Tenantprovider fields toManagedEnvironment: rejected because it would deepen Microsoft coupling. - extract provider profiles in the same slice: rejected because Spec
281already owns that follow-up.
- copy current
Decision 5: Retarget membership semantics without broad RBAC redesign
- Decision: Replace current tenant-membership truth with managed-environment membership truth while preserving current workspace and capability semantics.
- Rationale: The cutover needs environment-scoped access control to keep current pages safe, but a broader RBAC scope redesign is already reserved for Spec
285. - Alternatives considered:
- leave memberships tenant-shaped temporarily: rejected because the active root model would still leak tenant-core assumptions.
- widen capabilities or role families now: rejected because that would collapse Spec
285into the core cutover.
Decision 6: Use unit + feature + browser + guard checks as the narrowest honest proof
- Decision: Plan one managed-environment unit family, one feature family, one browser smoke, and one legacy-core guard family.
- Rationale: The cutover changes both internal identity rules and end-to-end context selection. Feature tests alone are not enough to prove the shell/chooser still works, and browser coverage alone would hide legacy-core drift.
- Alternatives considered:
- feature tests only: rejected because the cutover changes end-to-end context entry.
- heavy-governance or multi-browser rollout: rejected because the slice is core infrastructure, not new multi-surface behavior.
Final Research Outcome
279should remain the breaking core entity cutover only.- The only allowed public-path deviation is temporary
/admin/t/{environment}retention while it bindsManagedEnvironment. - Existing tenant-context seams should be replaced in place, not wrapped.
ManagedEnvironmentmust stay provider-neutral.- Membership semantics move with the core entity, but broader RBAC redesign remains deferred.
- Unit, feature, browser, and guard coverage together are the narrowest honest proof.