TenantAtlas/specs/300-internal-tenant-model-naming-consolidation/spec.md
ahmido 292d555eac refactor: consolidate internal tenant model naming (#355)
## 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
2026-05-14 11:13:28 +00:00

255 lines
24 KiB
Markdown

# 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`.