TenantAtlas/specs/300-internal-tenant-model-naming-consolidation/plan.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

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-smoke for 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: /admin and /system planes 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, not bootstrap/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/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
  • 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-filament unless 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\ManagedEnvironment exists.
    • ManagedEnvironmentFactory exists.
    • managed_environments exists.
    • No active App\Models\Tenant model was found through application info or app/Models scan.
  • Current route truth:
    • /admin/workspaces/{workspace}/environments/... routes exist.
    • /admin/t and /admin/tenants had 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 as TenantDashboard, TenantDiagnostics, and TenantRequiredPermissions.
  • 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

  1. Confirm branch and dirty state.
  2. Refresh the inventory scans in tenant-reference-inventory.md.
  3. Stop if unrelated uncommitted changes exist.
  4. Stop if production-data migration requirements are discovered.
  5. Confirm no app implementation begins until spec/plan/tasks/checklist are accepted.

Phase 1: Baseline Inventory And Guard Tests

  1. Run required route/source/provider/schema scans.
  2. Expand tenant-reference-inventory.md from preparation summary into file-level classification.
  3. Expand allowed-tenant-references.md with all provider/framework/historical/regression-guard references.
  4. 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

  1. Verify managed_environments remains the source-of-truth table.
  2. Rename platform-owned tenant-named tables/columns/indexes/constraints where safe.
  3. Rename migration filenames/classes where they are historical names for active platform Managed Environment truth and pre-production safety allows it.
  4. Keep provider-owned entra_tenant_id / microsoft_tenant_id payload fields.
  5. Validate with migrate:fresh --seed or document why targeted migration validation is the narrower proof.

Phase 3: Model, Factory, Service, And Helper Rename

  1. Keep ManagedEnvironment model and ManagedEnvironmentFactory as canonical.
  2. Rename platform-owned model classes such as TenantPermission, TenantSetting, TenantRoleMapping, TenantOnboardingSession, and review/triage classes when classification says they represent Managed Environment-owned truth.
  3. Rename platform-owned service/support classes and variables.
  4. Remove stale compatibility aliases.
  5. Run focused Unit/Feature tests for renamed helpers and services.

Phase 4: Filament Resource/Page/Widget Rename

  1. Rename TenantResource and nested Pages/RelationManagers to environment-first names.
  2. Rename TenantDashboard, TenantDiagnostics, and TenantRequiredPermissions to environment-first page names.
  3. Update route owner classes and route names without changing canonical URL segments.
  4. Review global search: renamed resources must have View/Edit pages or disable global search.
  5. Preserve destructive action confirmation, server authorization, and audit behavior.

Phase 5: Tests, Fixtures, Browser Anchors

  1. Rename stale test helpers and fixtures.
  2. Keep negative guard literals only where explicitly documented.
  3. Update Browser smoke selectors only where visible copy/test IDs depend on renamed technical owners.
  4. Run focused validation lanes and Browser anchors.

Phase 6: Final Classification And Validation

  1. Rerun final scans.
  2. Ensure no unclassified active platform-owned tenant references remain.
  3. Complete final tenant-reference-inventory.md and allowed-tenant-references.md.
  4. Run Pint dirty and git diff --check.
  5. 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 complete
  • merge-ready with documented provider/framework tenant references
  • blocked by unresolved platform-owned tenant references
  • blocked by migration/schema risk
  • incomplete; canonical route or RBAC regression found