# 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 `Tenant` names 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 `tenant` reference, 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-dev` has `feat: 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 `OperationRunLinks` and 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 tenant` remain 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 `Tenant` while explicitly quarantining provider-owned tenant terms instead of deleting them. - **Follow-up path**: document-in-feature through `tenant-reference-inventory.md` and `allowed-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-smoke` only 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/Guards` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Workspaces` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac` - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `git 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**: 1. **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. 2. **Given** a remaining `tenant` reference 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**: 1. **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. 2. **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. 3. **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**: 1. **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. 2. **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 - `ManagedEnvironment` already exists as the active model and `managed_environments` already exists as the active table; implementation must consolidate remaining names rather than assume a greenfield `Tenant` model/table rename. - Migration filenames and index/constraint names can still carry `tenant` even when table/columns already use `managed_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_id` may appear beside platform `managed_environment_id`; only the platform-owned key should be renamed. ## Requirements *(mandatory)* ### Functional Requirements - **FR-300-001**: The implementation MUST refresh `tenant-reference-inventory.md` before runtime edits and classify every relevant `tenant` hit as `platform-managed-environment`, `provider-specific`, `framework-required`, `historical`, `regression-guard`, `test-fixture-stale`, or `blocked/unclear`. - **FR-300-002**: No active `App\Models\Tenant` model or `TenantFactory` may remain. Current repo truth already uses `App\Models\ManagedEnvironment` and `ManagedEnvironmentFactory`; implementation must not add a compatibility alias. - **FR-300-003**: Platform-owned Filament owners such as `TenantResource`, `TenantDashboard`, `TenantRequiredPermissions`, `TenantDiagnostics`, `ManageTenantMemberships`, and `TenantMembershipsRelationManager` MUST 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`, and `managed_environment_memberships` truth 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 as `Microsoft 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-owned `TenantFactory` references 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 named `filament.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 in `bootstrap/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`, and `managed_environment_memberships` remain 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.md` and `allowed-tenant-references.md` classify 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\ManagedEnvironment` and table `managed_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 risk` or `blocked by unresolved platform-owned tenant references`.