Skip to content

Phase 1 + 2: multi-tenant hierarchy, stateless company context, settings engine#202

Open
TLemmAI wants to merge 21 commits intofleetbase:mainfrom
TLemmAI:feat/multi-tenant-hierarchy
Open

Phase 1 + 2: multi-tenant hierarchy, stateless company context, settings engine#202
TLemmAI wants to merge 21 commits intofleetbase:mainfrom
TLemmAI:feat/multi-tenant-hierarchy

Conversation

@TLemmAI
Copy link
Copy Markdown

@TLemmAI TLemmAI commented Apr 15, 2026

Summary

Foundation layer for fleetbase's TMS productization. Phase 1 introduces parent-organization → client-organization hierarchy with stateless per-request company context. Phase 2 adds a settings surface with parent-to-client inheritance.

Phase 1 — Multi-tenant hierarchy

  • companies schema: parent_company_uuid, company_type, is_client, client_code, client_settings
  • company_users pivot: access_level enum + is_default boolean
  • Company/User/CompanyUser model helpers: parentCompany(), clientCompanies(), isClient(), isOrganization(), getAccessibleCompanyUuids(), defaultCompany(), accessibleCompanyUuids(), canAccessCompany()
  • Seed migration: backfills existing companies as organizations, marks one company_users row per user as is_default using deterministic tie-breaker
  • CompanyContextResolver middleware — stateless per-request, reads X-Company-Context header with $user->defaultCompany() fallback, client-role hard guardrail
  • CompanyContextSelfResolver middleware — role-agnostic variant (no client hard-block) for self-service routes like settings
  • ScopedToCompanyContext trait — fail-closed local scope (empty result when no context bound)
  • ClientCompanyController — org-scoped CRUD for client companies
  • CompanyContextControllercurrent and switch endpoints (validation-only, no state mutation)

Phase 2 — Settings engine

  • CompanySettingsResolver helper — dot-notation, typed defaults, parent→client inheritance on top of existing Setting model (no new company_settings table)
  • CompanySettingsControllerGET/PUT/PATCH /v1/company-settings/current
  • CompanySettingsUpdateRequest — validates flat dot-notation key map payload

Test infrastructure

  • Orchestra Testbench bootstrap added under tests/TestCase.php + tests/Pest.php
  • Hoisted responsecache noop + mysql → sqlite connection alias into TestCase

Merged from upstream/main

origin/main drifted by 3 commits (schedule_items company_uuid, hos_*, v1.6.39). Auto-merged cleanly — disjoint from multi-tenant / settings surface.

Test plan

Current feature branch: 116 Pest tests passed (279 assertions) covering every surface above.

  • After merge: full Pest suite still 116 passing
  • Smoke API/SDK 14/14

Dependencies

This is the foundation PR — fleetops, ledger, ember-core, ember-ui, and the fleetbase parent all depend on it.

local and others added 21 commits April 6, 2026 13:15
- DocumentQueueItem model with safe-failure status flow
- DocumentIngestionService: heuristic classification first, AI fallback,
  PDF extraction optional, conditional CarrierInvoice creation only at
  confidence >= 0.85
- Manual upload as primary path; works without Anthropic key, without
  spatie/pdf-to-text, without queue workers, without IMAP
- All FleetOps/Ledger references guarded with class_exists()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant