## 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
19 KiB
Implementation Plan: Internal Tenant Model Naming Consolidation
Branch: 300-internal-tenant-model-naming-consolidation | Date: 2026-05-13 | Spec: specs/300-internal-tenant-model-naming-consolidation/spec.md
Input: Feature specification from /specs/300-internal-tenant-model-naming-consolidation/spec.md
Summary
Spec 300 is a structural cleanup after the managed-environment cutover pack. Current repo truth already has App\Models\ManagedEnvironment, ManagedEnvironmentFactory, managed_environments, managed_environment_id, and canonical workspace/environment routes, but active technical owners still use Tenant-first names across Filament resources/pages/widgets, route parameters, services, tests, migration filenames, table names, index/constraint names, and provider-adjacent payloads.
The implementation approach is inventory-first: classify every remaining tenant reference, rename only platform-owned Managed Environment references, preserve provider-specific and framework-required terms, run focused route/RBAC/Filament/browser validation, and leave no compatibility alias or legacy route in final state.
Technical Context
Language/Version: PHP 8.4.15, Laravel 12.52.0
Primary Dependencies: Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Laravel Sail 1.52.0
Storage: PostgreSQL; current source-of-truth table is managed_environments
Testing: Pest via cd apps/platform && ./vendor/bin/sail artisan test --compact; Browser tests under apps/platform/tests/Browser for smoke anchors
Validation Lanes: Feature/Guards, Workspaces, ProviderConnections, RequiredPermissions, Filament, Rbac, targeted Browser smoke, Pint dirty, git diff --check
Target Platform: Laravel SaaS admin app deployed via Dokploy containers; local validation via Sail
Project Type: Monorepo with Laravel platform app under apps/platform
Performance Goals: No broad suite repair loop by default; keep scans and tests focused around structural rename blast radius
Constraints: No runtime behavior change, no production compatibility layer, no route resurrection, no RBAC widening, no provider payload corruption
Scale/Scope: Structural rename across platform-owned environment concepts only
UI / Surface Guardrail Plan
- Guardrail scope: workflow/route/resource guardrail change, no intended visible UI redesign
- Native vs custom classification summary: native Filament/resource/page behavior preserved
- Shared-family relevance: canonical links, navigation/route registration, global search, audit metadata, OperationRun metadata, guard tests
- State layers in scope: route binding, page/resource class names, table/column/index/constraint names, helper names, test helper names, audit/metadata keys
- Audience modes in scope: operator-MSP and support-platform only as existing surfaces; no new customer-facing mode
- Decision/diagnostic/raw hierarchy plan: unchanged
- Raw/support gating plan: unchanged
- One-primary-action / duplicate-truth control: unchanged; any touched actions keep existing hierarchy
- Handling modes by drift class or surface: review-mandatory for active
Tenant*technical owners; allowed classification for provider/framework/historical/regression-guard - Repository-signal treatment: review-mandatory for final scans, route proof, helper retirement, DB naming, provider allowlist, and browser anchors
- Special surface test profiles:
route-contract,standard-native-filament,global-context-shell,browser-smokefor selected anchors - Required tests or manual smoke: focused Pest guard/feature lanes plus selected Browser smokes
- Exception path and spread control: provider-specific and framework-required tenant terms are documented in
allowed-tenant-references.md; no unclassified exception - Active feature PR close-out entry: Guardrail / Structural Tenant Naming Consolidation / Smoke Coverage
Shared Pattern & System Fit
- Cross-cutting feature marker: yes
- Systems touched:
ManagedEnvironmentLinks, workspace intended URL handling, Filament resource/page discovery and routes, route model binding, global search, RBAC helper/policies, OperationRun metadata, audit logs, evidence/report/review references, tests - Shared abstractions reused: Existing route helpers, existing RBAC/policy helpers, existing OperationRun link/service truth, existing Filament v5 resources/pages/actions
- New abstraction introduced? why?: none
- Why the existing abstraction was sufficient or insufficient: Existing environment-first helpers and models are sufficient; the issue is remaining names around them.
- Bounded deviation / spread control: Provider-specific and Filament framework terms remain only with explicit classification.
OperationRun UX Impact
- Touches OperationRun start/completion/link UX?: no
- Central contract reused: Existing
OperationRunLinks,OperationRunService, and OperationRun monitoring semantics remain unchanged if touched - Delegated UX behaviors: N/A
- Surface-owned behavior kept local: N/A
- Queued DB-notification policy: N/A
- Terminal notification path: N/A
- Exception path: none
Provider Boundary & Portability Fit
- Shared provider/platform boundary touched?: yes
- Provider-owned seams: Microsoft/Entra tenant identifiers, Graph
tenantId,entra_tenant_id,microsoft_tenant_id, target-scope provider metadata, raw provider payloads - Platform-core seams: Managed Environment model/table/resource/page/service/helper naming, route parameters, platform metadata keys, evidence/report/review references
- Neutral platform terms / contracts preserved:
ManagedEnvironment,managed_environment_id,environment,workspace,ManagedEnvironmentLinks - Retained provider-specific semantics and why: Microsoft/Entra terms stay because they represent external directory identity, not platform object ownership.
- Bounded extraction or follow-up path: document-in-feature. Stop only if ambiguous active platform-owned references cannot be classified safely.
Constitution Check
GATE: Must pass before implementation. Re-check after structural rename phases.
- Inventory-first: no inventory domain change; source scans/classification precede edits.
- Read/write separation: no new user-triggered write behavior; touched destructive actions must keep confirmation, authorization, audit, and tests.
- Graph contract path: no Graph endpoint changes; provider-specific Graph tenant identifiers remain provider-owned.
- Deterministic capabilities: no capability derivation change.
- RBAC-UX:
/adminand/systemplanes remain separated; workspace/environment non-entitlement stays 404; member-without-capability stays 403. - Workspace isolation: workspace remains primary session context; Managed Environment remains secondary context.
- Tenant isolation: current tenant-owned-by-history semantics are preserved behaviorally while platform-owned naming moves to environment-first.
- Run observability: no new queued/remote work; OperationRun metadata naming may change only where platform-owned.
- Test governance: focused structural rename lanes are explicit; no broad test family growth by default.
- Proportionality: broad rename is justified as post-cutover cleanup; no new runtime abstraction.
- No premature abstraction: no registries/resolvers/frameworks added.
- Persisted truth: no new table/entity/product truth; only names may change.
- Behavioral state: no new states or reason families.
- Shared pattern first: existing link/RBAC/Filament/OperationRun patterns are reused.
- Provider boundary: platform-owned Tenant-first terms are removed; provider-owned tenant terms are kept and documented.
- LEAN-001: pre-production posture means no compatibility aliases, dual paths, or historical fixtures unless a spec-blocking migration risk is discovered.
- Filament v5: Livewire v4.0+ is required; this repo has Livewire 4.1.4.
- Laravel 12 panel providers: remain registered in
apps/platform/bootstrap/providers.php, notbootstrap/app.php. - Global search: any renamed globally searchable resource must keep View/Edit pages or disable global search.
- Filament actions: any touched destructive actions must remain
Action::make(...)->action(...)with->requiresConfirmation()and authorization. - Asset strategy: unchanged; if assets are unexpectedly registered, deployment must run
cd apps/platform && php artisan filament:assets.
Test Governance Check
- Test purpose / classification by changed surface: Feature guards for route/helper/naming contracts; Filament/Livewire feature tests for resources/pages/actions; Unit tests for pure helper services; Browser smoke for selected visible anchors.
- Affected validation lanes: Feature/Guards, Workspaces, ProviderConnections, RequiredPermissions, Filament, Rbac, targeted Browser.
- Why this lane mix is the narrowest sufficient proof: It proves route/RBAC equivalence and stale-name absence without treating the rename as a full-suite stabilization spec.
- Narrowest proving command(s):
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/Rbac
- Fixture / helper / factory / seed / context cost risks: Rename helpers without widening default workspace/provider/browser setup.
- Expensive defaults or shared helper growth introduced?: no
- Heavy-family additions, promotions, or visibility changes: none planned; Browser anchors stay explicit.
- Surface-class relief / special coverage rule:
standard-native-filamentunless a visible context-shell/browser anchor changes. - Closing validation and reviewer handoff: final scans, focused lanes, Browser anchors, Pint dirty,
git diff --check, and close-out inventory. - Budget / baseline / trend follow-up: none expected; document any unexpected lane runtime growth.
- Review-stop questions: Did any active platform-owned
Tenant*owner remain? Did route parameters still use{tenant}for platform environment routes? Did provider terms remain correct? Did global search remain valid? Did RBAC widen? - Escalation path: document-in-feature; follow-up-spec only for unresolved migration/schema risk or ambiguous platform-owned references.
- Active feature PR close-out entry: Guardrail / Structural Tenant Naming Consolidation / Smoke Coverage
- Why no dedicated follow-up spec is needed: The rename is explicitly scoped as the post-297-299 cleanup; unresolved blockers must stop this spec rather than silently deferring core cleanup.
Project Structure
Documentation (this feature)
specs/300-internal-tenant-model-naming-consolidation/
├── allowed-tenant-references.md
├── checklists/
│ └── requirements.md
├── plan.md
├── spec.md
├── tasks.md
└── tenant-reference-inventory.md
Source Code (repository root)
apps/platform/
├── app/
│ ├── Console/Commands/
│ ├── Filament/
│ │ ├── Concerns/
│ │ ├── Pages/
│ │ ├── Resources/
│ │ ├── System/
│ │ └── Widgets/
│ ├── Http/Controllers/
│ ├── Jobs/
│ ├── Models/
│ ├── Policies/
│ ├── Services/
│ └── Support/
├── config/
├── database/
│ ├── factories/
│ └── migrations/
├── resources/
├── routes/
└── tests/
├── Browser/
├── Feature/
└── Unit/
Structure Decision: Use the existing Laravel/Filament layout. Do not introduce new base folders. Rename files/classes in-place to established destination names.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| Broad structural rename | Active technical names keep old Tenant-first architecture alive after route/copy cutover | Comments/docs alone do not stop future code from using active Tenant* classes/helpers/routes |
| Migration/index/constraint rename review | DB source truth is already managed_environment, but tenant-named migration files/indexes/constraints remain |
Leaving schema names mixed makes future migrations and guard tests ambiguous |
Proportionality Review
- Current operator problem: Future platform/environment work can regress visible behavior and provider boundaries because active code still presents Tenant as the platform managed target.
- Existing structure is insufficient because: Specs 297-299 cleaned route/copy/final seal surfaces, not internal class/table/helper ownership.
- Narrowest correct implementation: Classify first, rename platform-owned names only, preserve provider/framework/historical/guard terms, and prove equivalence.
- Ownership cost created: High review and testing cost, plus migration/schema risk; contained by phased tasks and final inventory.
- Alternative intentionally rejected: Leave active internal names as legacy debt. Rejected because the project is pre-production and LEAN-001 favors canonical replacement over legacy preservation.
- Release truth: Current-release structural cleanup
Repository Truth From Preparation
- Current branch before prep:
platform-dev, clean. - Current branch after
create-new-feature:300-internal-tenant-model-naming-consolidation. - Latest starting commit:
b98bafcf feat: finalize managed environment cutover seal (#354). - Related specs:
specs/297-managed-environment-canonical-route-cutover/has completed task/checklist signals and route-cutover artifacts.specs/298-managed-environment-terminology-copy-cleanup/has completed checklist signals and terminology audit artifacts.specs/299-managed-environment-cutover-final-seal/has completed checklist signals and final cutover audit artifacts.
- Current model/table truth:
App\Models\ManagedEnvironmentexists.ManagedEnvironmentFactoryexists.managed_environmentsexists.- No active
App\Models\Tenantmodel was found through application info orapp/Modelsscan.
- Current route truth:
/admin/workspaces/{workspace}/environments/...routes exist./admin/tand/admin/tenantshad no matching routes via Boost route lookup.- Sail route scan shows canonical environment routes still use
{tenant}as a route parameter and active classes such asTenantDashboard,TenantDiagnostics, andTenantRequiredPermissions.
- Current scan volume:
- Broad tenant scan: 2323 line hits.
- Provider-allowed scan: 1661 line hits.
- Migration/schema scan: 851 line hits.
- Legacy route/helper/resource scan: 242 line hits.
Phase 0: Preparation And Safety
- Confirm branch and dirty state.
- Refresh the inventory scans in
tenant-reference-inventory.md. - Stop if unrelated uncommitted changes exist.
- Stop if production-data migration requirements are discovered.
- Confirm no app implementation begins until spec/plan/tasks/checklist are accepted.
Phase 1: Baseline Inventory And Guard Tests
- Run required route/source/provider/schema scans.
- Expand
tenant-reference-inventory.mdfrom preparation summary into file-level classification. - Expand
allowed-tenant-references.mdwith all provider/framework/historical/regression-guard references. - Add/update guard tests for route resurrection, active
Tenant*platform owners, stale helper names, and provider terminology preservation.
Phase 2: DB And Schema Naming Cleanup
- Verify
managed_environmentsremains the source-of-truth table. - Rename platform-owned tenant-named tables/columns/indexes/constraints where safe.
- Rename migration filenames/classes where they are historical names for active platform Managed Environment truth and pre-production safety allows it.
- Keep provider-owned
entra_tenant_id/microsoft_tenant_idpayload fields. - Validate with
migrate:fresh --seedor document why targeted migration validation is the narrower proof.
Phase 3: Model, Factory, Service, And Helper Rename
- Keep
ManagedEnvironmentmodel andManagedEnvironmentFactoryas canonical. - Rename platform-owned model classes such as
TenantPermission,TenantSetting,TenantRoleMapping,TenantOnboardingSession, and review/triage classes when classification says they represent Managed Environment-owned truth. - Rename platform-owned service/support classes and variables.
- Remove stale compatibility aliases.
- Run focused Unit/Feature tests for renamed helpers and services.
Phase 4: Filament Resource/Page/Widget Rename
- Rename
TenantResourceand nested Pages/RelationManagers to environment-first names. - Rename
TenantDashboard,TenantDiagnostics, andTenantRequiredPermissionsto environment-first page names. - Update route owner classes and route names without changing canonical URL segments.
- Review global search: renamed resources must have View/Edit pages or disable global search.
- Preserve destructive action confirmation, server authorization, and audit behavior.
Phase 5: Tests, Fixtures, Browser Anchors
- Rename stale test helpers and fixtures.
- Keep negative guard literals only where explicitly documented.
- Update Browser smoke selectors only where visible copy/test IDs depend on renamed technical owners.
- Run focused validation lanes and Browser anchors.
Phase 6: Final Classification And Validation
- Rerun final scans.
- Ensure no unclassified active platform-owned tenant references remain.
- Complete final
tenant-reference-inventory.mdandallowed-tenant-references.md. - Run Pint dirty and
git diff --check. - Produce final implementation report with rename summary, DB changes, remaining references, route contract, validation, and decision.
Risk Controls
- No blind global search/replace.
- No permanent alias classes.
- No route compatibility layer.
- No dual-write/dual-read unless this spec is stopped and replaced with a production migration spec.
- Provider-specific and framework-required tenant references must be preserved, not renamed for cleanliness.
- Broad scan output must be triaged before code changes.
- Keep implementation commits phased so rollback/review is possible.
Final Decision Criteria
Implementation may report only one of:
merge-ready; internal tenant naming consolidation completemerge-ready with documented provider/framework tenant referencesblocked by unresolved platform-owned tenant referencesblocked by migration/schema riskincomplete; canonical route or RBAC regression found