## Summary - consolidate internal platform naming from `Tenant` to `Environment` / `ManagedEnvironment` across models, controllers, services, and Filament resources - rename environment-scoped UI surfaces such as dashboards, chooser flows, navigation, and related widgets to match the updated environment-first domain language - align middleware, onboarding/review lifecycle services, jobs, and route/context controllers with the new environment-scoped architecture ## Validation - not rerun as part of this commit/push/PR request ## Notes - branch is 1 commit ahead of `platform-dev` - main commit: `refactor: consolidate internal tenant model naming` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #355
24 KiB
Feature Specification: Internal Tenant Model Naming Consolidation
Feature Branch: 300-internal-tenant-model-naming-consolidation
Created: 2026-05-13
Status: Ready
Input: User-provided Spec 300 draft for a narrow structural rename after Specs 297-299
Spec Candidate Check (mandatory — SPEC-GATE-001)
- Problem: Runtime routes and customer-facing copy are now workspace/environment-first, but active technical owners still use
Tenantnames for the platform-managed environment object. - Today's failure: Developers can still reach for
TenantResource,TenantDashboard,{tenant}route parameters,tenant_*tables, or tenant-named helpers and accidentally stabilize platform-owned tenant-first architecture. - User-visible improvement: Future environment work remains provider-neutral and less likely to leak old Tenant wording back into URLs, navigation, tests, reports, or admin workflows.
- Smallest enterprise-capable version: Classify every remaining
tenantreference, rename only platform-owned Managed Environment references, preserve provider/framework/historical/negative-guard references, and prove canonical routes/RBAC remain equivalent. - Explicit non-goals: No new product feature, navigation redesign, provider abstraction rewrite, OperationRun architecture change, localization sweep, compatibility layer,
/admin/t/...route,/admin/tenants/...route, or TenantPanel restoration. - Permanent complexity imported: No new runtime abstraction or feature framework. The implementation imports rename/migration review cost, guard tests, and two spec-local classification artifacts.
- Why now: Current
platform-devhasfeat: finalize managed environment cutover seal (#354), and Specs 297, 298, and 299 carry completed-task/review signals. This is the right structural cleanup after the cutover seal, not a cutover fix. - Why not local: The drift spans Filament resources/pages/widgets, route parameters, services, migrations, indexes, tables, tests, helpers, audit/metadata keys, and provider payload boundaries.
- Approval class: Cleanup
- Red flags triggered: Broad structural rename blast radius. Defense: no blind search/replace, mandatory inventory, provider/framework allowlist, focused route/RBAC guards, and no compatibility aliases in final state.
- Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexität: 1 | Produktnähe: 1 | Wiederverwendung: 2 | Gesamt: 9/12
- Decision: approve as a bounded cleanup spec
Spec Scope Fields (mandatory)
- Scope: workspace + managed-environment core naming
- Primary Routes:
/admin/workspaces/{workspace}/environments/admin/workspaces/{workspace}/environments/{environment}/admin/workspaces/{workspace}/environments/{environment}/.../admin/workspaces/{workspace}/operations/admin/provider-connections
- Data Ownership: No new persisted truth. Existing Managed Environment-owned and tenant-owned-by-history tables/columns may be renamed only when they refer to the platform Managed Environment object.
- RBAC: Workspace membership remains the authority boundary; Managed Environment membership remains narrowing-only; non-entitled workspace/environment access remains deny-as-not-found; member-without-capability remains forbidden.
For canonical-view specs:
- Default filter behavior when tenant-context is active: Existing workspace/environment filters remain equivalent; any renamed query parameter must preserve current scoping semantics.
- Explicit entitlement checks preventing cross-tenant leakage: Existing policies, Gates,
ManagedEnvironmentAccessScopeResolver, route binding, and test helpers must continue enforcing workspace + environment entitlement.
Cross-Cutting / Shared Pattern Reuse (mandatory)
- Cross-cutting feature?: yes
- Interaction class(es): canonical links, route helpers, global search/resource ownership, navigation registration, audit event names, OperationRun metadata keys, evidence/report/review links, guard tests
- Systems touched:
ManagedEnvironmentLinks, workspace intended URL handling, Filament admin panel discovery/routes, route bindings, resources/pages/widgets, RBAC helpers, audit and OperationRun metadata emitters, test helpers - Existing pattern(s) to extend: Existing workspace/environment route helpers and guard-test patterns from Specs 297-299
- Shared contract / presenter / builder / renderer to reuse:
App\Support\ManagedEnvironmentLinks, existing workspace route owners, existing RBAC/policy helpers, existing Filament v5 action/resource conventions - Why the existing shared path is sufficient or insufficient: Existing helpers already own canonical environment URLs; this spec renames technical owners around those helpers rather than introducing a new link or navigation framework.
- Allowed deviation and why: Provider-specific and Filament framework-required tenant APIs may remain after classification.
- Consistency impact: Routes, route parameters, class names, test helpers, audit metadata, and report/evidence links must remain environment-first unless provider/framework/historical/negative-guard classification applies.
- Review focus: Reviewers must verify no active platform-owned
Tenant*technical owner remains unclassified and no legacy route/helper is revived.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: no
- Shared OperationRun UX contract/layer reused: Existing
OperationRunLinksand OperationRun service truth remain unchanged if touched. - Delegated start/completion UX behaviors: N/A - no run start, completion, notification, dedupe, or link UX semantics are introduced.
- Local surface-owned behavior that remains: Existing operation initiation inputs only.
- Queued DB-notification policy: N/A
- Terminal notification path: N/A
- Exception required?: none
Provider Boundary / Platform Core Check (mandatory)
- Shared provider/platform boundary touched?: yes
- Boundary classification: mixed
- Seams affected: platform Managed Environment identifiers/classes/tables, provider connection target-scope metadata, Graph/Entra tenant IDs, onboarding provider identity fields, audit/OperationRun metadata keys
- Neutral platform terms preserved or introduced:
workspace,environment,managed_environment,managed_environment_id,ManagedEnvironment,ManagedEnvironmentLinks - Provider-specific semantics retained and why:
Microsoft tenant,Entra tenant,Azure tenant,tenantId,entra_tenant_id,microsoft_tenant_id,provider tenant id,target tenantremain where they describe external provider truth or raw API payloads. - Why this does not deepen provider coupling accidentally: The spec moves platform-owned naming away from
Tenantwhile explicitly quarantining provider-owned tenant terms instead of deleting them. - Follow-up path: document-in-feature through
tenant-reference-inventory.mdandallowed-tenant-references.md; escalate only if an ambiguous active platform-owned term cannot be safely classified.
UI / Surface Guardrail Impact (mandatory)
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Filament environment resources/pages technical rename | no expected copy/layout change | Native Filament | navigation/routes/global search | route, page class, resource class | no | Technical owner rename only; visible copy remains from Specs 298-299 |
Route parameter rename from {tenant} to {environment} where platform-owned |
no URL shape change | N/A | canonical route helpers | route binding, URL generation | no | Segment remains /environments/... |
| Provider-specific tenant labels | no | Native Filament / existing copy | provider identity | provider payload/copy | yes, allowed classification | Keep Microsoft/Entra terms |
Decision-First Surface Role (mandatory when operator-facing surfaces are changed)
N/A - no new operator-facing surface and no new decision workflow. Existing surfaces must remain equivalent.
Audience-Aware Disclosure (mandatory when operator-facing surfaces are changed)
N/A - no new detail or status surface. Existing diagnostics/support/raw disclosure tiers must remain unchanged.
UI/UX Surface Classification (mandatory when operator-facing surfaces are changed)
N/A - no new operator-facing list/detail/queue/report surface. Any touched Filament resource/page keeps its current surface class and action hierarchy.
Operator Surface Contract (mandatory when operator-facing surfaces are changed)
N/A - no new operator-facing page. Any renamed page/resource keeps the existing operator question, default-visible content, diagnostics-only content, actions, destructive-action handling, and RBAC.
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no
- New persisted entity/table/artifact?: no new product truth; possible table/column/index/constraint renames only
- New abstraction?: no
- New enum/state/reason family?: no
- New cross-domain UI framework/taxonomy?: no
- Current operator problem: The platform core still looks Tenant-first internally, making future environment/workspace/provider work error-prone and increasing regression risk after the cutover.
- Existing structure is insufficient because: Specs 297-299 intentionally stopped short of structural DB/model/resource consolidation. Leaving active
Tenant*owners in place keeps the old architecture as the easiest path for future work. - Narrowest correct implementation: Rename only platform-owned Managed Environment references and classify everything else; do not generalize provider architecture or rewrite unrelated domains.
- Ownership cost: High review and test cost from a broad rename; mitigated by inventory, phased tasks, focused validation lanes, and no compatibility layer.
- Alternative intentionally rejected: Leave internal names as-is and rely on docs. Rejected because active class/table/helper names shape future code and tests more strongly than comments.
- Release truth: Current-release cleanup after the managed-environment cutover pack
Compatibility posture
This feature assumes a pre-production environment with no live customer data and no compatibility requirement. No legacy aliases, dual-write/read paths, or old route compatibility layers should remain in final state unless a blocking production-data fact is discovered and the spec is stopped.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Feature guard tests, Filament/Livewire page/action tests, focused Unit tests for pure helpers, targeted Browser smoke anchors for visible flows
- Validation lane(s): Feature/Guards, Feature/Workspaces, Feature/ProviderConnections, Feature/RequiredPermissions, Feature/Filament, Feature/Rbac, Browser anchors, Pint dirty,
git diff --check - Why this classification and these lanes are sufficient: The change is structural naming with route/RBAC equivalence requirements; focused guards and impacted feature lanes prove the contract without a broad suite repair loop.
- New or expanded test families: Narrow guard tests for no stale
Tenant*active owner/helper/route regression; no new heavy family by default. - Fixture / helper cost impact: Helpers must be renamed without making workspace/provider/browser setup implicit. Expensive context remains opt-in.
- Heavy-family visibility / justification: Browser smokes are explicit anchors only because canonical route and visible navigation regressions are high-impact.
- Special surface test profile:
route-contract,standard-native-filament,global-context-shell,browser-smokeonly for touched visible anchors - Standard-native relief or required special coverage: Standard Filament/Livewire tests are enough for class/resource rename behavior; browser coverage is limited to existing smoke anchors.
- Reviewer handoff: Verify route contract, old route absence, RBAC isolation, stale helper absence, provider terminology preservation, and no unclassified active platform-owned tenant references.
- Budget / baseline / trend impact: Expected focused-lane runtime increase only; document if broad lane cost shifts.
- Escalation needed: document-in-feature; follow-up-spec only if migration/schema risk or unresolved platform-owned tenant references block cleanup.
- Active feature PR close-out entry: Guardrail / Structural Tenant Naming Consolidation / Smoke Coverage
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail artisan route:list | rg "admin/t|admin/tenants|workspaces/.*/environments|provider-connections|required-permissions|operations"cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guardscd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspacescd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnectionscd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissionscd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filamentcd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbaccd apps/platform && ./vendor/bin/sail bin pint --dirty --format agentgit diff --check
User Scenarios & Testing (mandatory)
User Story 1 - Platform Maintainer Renames Active Managed Environment Owners (Priority: P1)
As a platform maintainer, I need active platform-owned technical names to say ManagedEnvironment/Environment when they refer to the platform managed target, so future code does not rebuild Tenant-first architecture.
Why this priority: This is the core structural cleanup and the strongest dependency-unblocking value.
Independent Test: Run the final tenant-reference scan and verify every remaining tenant reference is classified as provider-specific, framework-required, historical, or regression-guard.
Acceptance Scenarios:
- Given a platform-owned Filament resource/page/service/helper that refers to the Managed Environment object, When Spec 300 is complete, Then the active class/helper/table/column name is environment-first or is documented as a blocker.
- Given a remaining
tenantreference in active code, When the final inventory is reviewed, Then it has an explicit allowed category and reason.
User Story 2 - Operator Routes And Access Stay Equivalent (Priority: P2)
As an operator, I need workspace/environment routes and access rules to behave exactly as before, so the cleanup does not change product behavior.
Why this priority: The structural rename must not weaken route stability, RBAC, or workspace/environment isolation.
Independent Test: Run canonical route, retired route, workspace/environment isolation, and impacted Filament/RBAC tests.
Acceptance Scenarios:
- Given an entitled user opens
/admin/workspaces/{workspace}/environments/{environment}, When the page resolves, Then the same environment detail behavior is available under canonical routes. - Given a user is not entitled to the workspace or environment, When they access renamed routes or actions, Then deny-as-not-found semantics still apply.
- Given retired
/admin/t/...or/admin/tenants/...URLs, When they are requested, Then no product route is resurrected.
User Story 3 - Provider Tenant Terminology Remains Correct (Priority: P3)
As a provider integration maintainer, I need Microsoft/Entra/Graph tenant terminology to remain intact where it represents external provider truth, so the platform cleanup does not corrupt API contracts or admin meaning.
Why this priority: The goal is platform-owned cleanup, not deleting the word tenant everywhere.
Independent Test: Run provider-specific scans and verify allowed references remain in provider-owned fields/copy/payloads.
Acceptance Scenarios:
- Given a provider connection field named
entra_tenant_id, When Spec 300 is complete, Then the field remains if it represents the external Entra tenant ID. - Given a raw Graph payload or target-scope metadata contains
tenantId, When classification is performed, Then the provider-owned key is preserved and documented.
Edge Cases
ManagedEnvironmentalready exists as the active model andmanaged_environmentsalready exists as the active table; implementation must consolidate remaining names rather than assume a greenfieldTenantmodel/table rename.- Migration filenames and index/constraint names can still carry
tenanteven when table/columns already usemanaged_environment; these must be classified and renamed where safe under the pre-production posture. - Filament tenancy APIs such as
Filament::getTenant()are framework-required and must not be renamed. - Historical specs and negative guard regex literals may keep tenant wording only when the file/category makes that reason explicit.
- Provider identity fields such as
entra_tenant_idmay appear beside platformmanaged_environment_id; only the platform-owned key should be renamed.
Requirements (mandatory)
Functional Requirements
- FR-300-001: The implementation MUST refresh
tenant-reference-inventory.mdbefore runtime edits and classify every relevanttenanthit asplatform-managed-environment,provider-specific,framework-required,historical,regression-guard,test-fixture-stale, orblocked/unclear. - FR-300-002: No active
App\Models\Tenantmodel orTenantFactorymay remain. Current repo truth already usesApp\Models\ManagedEnvironmentandManagedEnvironmentFactory; implementation must not add a compatibility alias. - FR-300-003: Platform-owned Filament owners such as
TenantResource,TenantDashboard,TenantRequiredPermissions,TenantDiagnostics,ManageTenantMemberships, andTenantMembershipsRelationManagerMUST be renamed to ManagedEnvironment/Environment equivalents unless a repo-real blocker is documented. - FR-300-004: Platform-owned route parameters under canonical environment routes MUST use
{environment}where feasible, or document the repo-real blocker, while preserving public URL segments as/environments/.... - FR-300-005: Platform-owned services/helpers/support classes such as
TenantMembershipManager,TenantDiagnosticsService,TenantPageCategory,TenantAction*,TenantOperability*,TenantDashboard*, and tenant-owned workspace-isolation helpers MUST be renamed when they refer to the platform Managed Environment object. - FR-300-006: Database table, column, index, constraint, model, factory, and migration names that refer to the platform Managed Environment object MUST be environment-first where safe under LEAN-001. Existing active
managed_environments,managed_environment_id, andmanaged_environment_membershipstruth MUST remain source of truth. - FR-300-007: Tenant-named review, evidence, report, baseline, finding, backup, restore, and OperationRun metadata references MUST be renamed only when they point to the platform Managed Environment object. Provider payload keys remain provider-specific.
- FR-300-008: Provider-specific tenant terminology MUST remain intact where it represents Microsoft/Entra/Azure/Graph/provider target truth, including
tenantId,entra_tenant_id,microsoft_tenant_id, and provider-facing copy such asMicrosoft tenant ID. - FR-300-009: Framework-required Filament tenant APIs MUST be kept and documented, including
Filament::getTenant(),Filament::setTenant(), and tenancy contracts/method names. - FR-300-010: Stale test helpers such as
setTenantPanelContext,panel: 'tenant', and active platform-ownedTenantFactoryreferences MUST be removed except for explicit negative guard literals. - FR-300-011: Existing canonical routes MUST remain active and no
/admin/t/...,/admin/tenants/..., or active route namedfilament.admin.resources.tenants.*may return as a product route. - FR-300-012: RBAC semantics MUST remain unchanged: workspace membership remains role authority, environment membership remains narrowing-only, non-entitlement stays 404, and missing capability stays 403.
- FR-300-013: Audit/event names and OperationRun metadata keys MAY be renamed only when they represent platform Managed Environment truth; no silent dual-writing is allowed unless a separate migration-risk decision changes this spec.
- FR-300-014: Final scans MUST show no unclassified active platform-owned tenant references.
Non-Functional Requirements
- NFR-300-001: The implementation MUST use a phased rename and tests; blind global search/replace is forbidden.
- NFR-300-002: No compatibility layer, alias class, dual-read, dual-write, or legacy route should remain in final state under the repo's pre-production posture.
- NFR-300-003: Filament v5 / Livewire v4.0+ compliance MUST be explicit; no Livewire v3 or Filament v3/v4 APIs may be introduced.
- NFR-300-004: Laravel 12 panel provider registration remains in
apps/platform/bootstrap/providers.php; do not register panel providers inbootstrap/app.php. - NFR-300-005: Globally searchable resources must either retain View/Edit pages or disable global search after renaming.
- NFR-300-006: Destructive actions touched by the rename must keep
->action(...),->requiresConfirmation(), server-side authorization, and audit behavior. - NFR-300-007: Asset strategy is unchanged; if implementation unexpectedly registers Filament assets, deployment notes must include
cd apps/platform && php artisan filament:assets.
Acceptance Criteria
- AC-300-001: No active platform-owned model/resource/page/helper/factory named
Tenant*remains unless explicitly classified as provider-specific, framework-required, historical, or regression-guard. - AC-300-002: Active platform-owned DB naming is environment-first.
managed_environments,managed_environment_id, andmanaged_environment_membershipsremain source-of-truth names; old tenant-named active FKs/tables/constraints are removed or documented as allowed non-platform references. - AC-300-003: Active Filament technical owners for environment management are environment-named and global search behavior remains valid under Filament v5 rules.
- AC-300-004:
/admin/workspaces/{workspace}/environments/...routes remain active;/admin/t/...and/admin/tenants/...remain retired. - AC-300-005: Provider-specific Microsoft/Entra/provider tenant language remains intact and documented.
- AC-300-006: No stale helper names remain except negative guard literals documented in the inventory.
- AC-300-007: Workspace/environment RBAC and isolation tests prove no access widening.
- AC-300-008: OperationRun remains execution truth; only platform-owned metadata names change if needed.
- AC-300-009: Evidence/report/review semantics remain unchanged; only platform-owned references are renamed.
- AC-300-010:
tenant-reference-inventory.mdandallowed-tenant-references.mdclassify all remaining tenant references at close-out.
Out Of Scope
- New product features or navigation redesign
- Customer Review Workspace, Governance Inbox, Localization v1, package execution, guided operations, or broader provider abstraction work
- Microsoft Graph contract refactor or OperationRun architecture change
- Reintroducing
TenantPanelProvider,/admin/t/...,/admin/tenants/..., or old TenantResource product routes - Production online migration/backfill strategy for live customer data
- Permanent aliases, compatibility routes, dual-write, or dual-read behavior
Assumptions
- Specs 297-299 are merged into the current branch or this branch is based on their final state.
- There is no production customer data requiring online backward-compatible migration.
- Local/dev/test data may be migrated or rebuilt.
- Provider-specific tenant concepts and Filament framework-required tenant APIs are allowed when classified.
- The current repo source of truth is
App\Models\ManagedEnvironmentand tablemanaged_environments; the cleanup targets remaining technical debt.
Open Questions
- None blocking for preparation. If implementation discovers production-data migration risk or an ambiguous active platform-owned tenant reference that cannot be classified, stop and report
blocked by migration/schema riskorblocked by unresolved platform-owned tenant references.