7.2 KiB
🏢 Garage-Centric Hierarchy Audit Report
Audit Date: 2026-03-29
Issue: #179 - SYSTEM ARCHITECT - CODE & SCHEMA AUDIT
Auditor: Fast Coder (Core Developer)
📋 Executive Summary
This audit verifies the implementation of the "Masterbook 2.0.1 Hierarchy": User → Org (Private/Corp) → Branch → Garage → Vehicle. The audit reveals that the core hierarchy is partially implemented with some gaps that need to be addressed.
🔍 Current Implementation Status
✅ IMPLEMENTED CORRECTLY
1. Registration Step 2 - Private Organization Creation
- Location:
backend/app/services/auth_service.py-complete_kyc()method - Status: ✅ FULLY IMPLEMENTED
- Details: When a user completes KYC (Registration Step 2), the system:
- Creates an
OrganizationwithOrgType.individual - Sets
user.scope_id = str(new_org.id) - Creates a default
Branchwithname="Home Base"andis_main=True - Creates
OrganizationMemberwithrole="OWNER"
- Creates an
- Code Reference: Lines 159-191 in
auth_service.py
2. Organization Model
- Location:
backend/app/models/marketplace/organization.py - Status: ✅ COMPLETE
- Schema:
fleet.organizations - Key Fields:
id,full_name,org_type,owner_id,status,is_active - Relationships: Has
branchesrelationship toBranchmodel
3. Branch Model (Acting as Garage)
- Location:
backend/app/models/marketplace/organization.py-Branchclass - Status: ✅ COMPLETE
- Schema:
fleet.branches - Key Fields:
id(UUID),organization_id,name,is_main,address_id - Note: No dedicated "Garage" model exists - Branch serves as the Garage container
4. Asset Model
- Location:
backend/app/models/vehicle/asset.py-Assetclass - Status: ✅ COMPLETE
- Schema:
vehicle.assets - Key Fields:
id(UUID),vin,license_plate,current_organization_id,owner_org_id
⚠️ PARTIALLY IMPLEMENTED / GAPS IDENTIFIED
1. Asset to Branch/Garage Linkage
- Status: ❌ MISSING
- Issue: Assets are linked to Organizations via
current_organization_idandowner_org_id, but there's no directbranch_idorgarage_idfield to specify which Branch/Garage the asset belongs to. - Current: Assets use
AssetAssignmentmodel for many-to-many relationship with Organizations - Required: Add
branch_idfield to Asset model
2. Verified Purchase Date Field
- Status: ⚠️ PARTIAL
- Current Fields:
first_registration_datein Asset model (line 48)activation_datein AssetFinancials model (line 146)
- Missing: Explicit
verified_purchase_datefield for cost cut-off logic - Required: Add
verified_purchase_dateto AssetFinancials model
3. Relocation Performed Flag
- Status: ❌ MISSING
- Issue: No
relocation_performedflag for one-time relocation logic - Required: Add boolean
relocation_performedfield to Asset model
🗺️ Hierarchy Mapping
User (identity.users)
↓
Organization (fleet.organizations) ← Private Org created during KYC
↓
Branch (fleet.branches) ← Acts as "Garage" container
↓
Asset (vehicle.assets) ← Missing direct branch_id linkage
📊 Database Schema Analysis
Current Asset-Organization Relationship
-- Current linkage (via AssetAssignment)
asset_assignments (fleet schema)
asset_id → vehicle.assets.id
organization_id → fleet.organizations.id
-- Direct fields in Asset
assets (vehicle schema)
current_organization_id → fleet.organizations.id
owner_org_id → fleet.organizations.id
Missing Branch Linkage
-- PROPOSED ADDITION to Asset model
ALTER TABLE vehicle.assets
ADD COLUMN branch_id UUID REFERENCES fleet.branches(id);
🔧 Required Code Modifications
1. Asset Model Updates (backend/app/models/vehicle/asset.py)
# Add to Asset class (around line 64):
branch_id: Mapped[Optional[uuid.UUID]] = mapped_column(
PG_UUID(as_uuid=True),
ForeignKey("fleet.branches.id"),
nullable=True
)
relocation_performed: Mapped[bool] = mapped_column(
Boolean,
default=False,
server_default=text("false")
)
# Add relationship:
branch: Mapped[Optional["Branch"]] = relationship("Branch")
2. AssetFinancials Model Updates
# Add to AssetFinancials class:
verified_purchase_date: Mapped[Optional[datetime]] = mapped_column(
DateTime(timezone=True),
nullable=True
)
3. Schema Updates Required
- Run
sync_engine.pyafter model changes - DO NOT use Alembic migrations directly per project rules
🧪 Test Script for Hierarchy Verification
A test script has been prepared to verify the separation logic:
# Test: Create 1 Private Garage car and 1 Corporate Branch car
# Verify GET /vehicles (with active scope_id) only shows cars belonging to specific context
Test Logic:
- Create User A with Private Organization (Org A)
- Create User B with Corporate Organization (Org B)
- Add Vehicle 1 to Org A's Branch
- Add Vehicle 2 to Org B's Branch
- Verify User A only sees Vehicle 1 when calling GET /vehicles
- Verify User B only sees Vehicle 2 when calling GET /vehicles
🚨 Critical Findings
1. Scope Isolation Works
The user.scope_id mechanism correctly isolates data at the Organization level. When a user queries /vehicles, the API filters by current_organization_id = user.scope_id.
2. Branch-Level Isolation Missing
While Organization-level isolation exists, there's no Branch-level filtering. All assets in an Organization are visible regardless of which Branch they belong to.
3. Cost Cut-off Logic Incomplete
Without verified_purchase_date and relocation_performed fields, the historical cost tracking and one-time relocation logic cannot be properly implemented.
📝 Recommendations
HIGH PRIORITY
- Add
branch_idto Asset model - Enable Branch/Garage level asset management - Add
verified_purchase_dateto AssetFinancials - Support cost cut-off logic - Add
relocation_performedflag to Asset - Enable one-time relocation tracking
MEDIUM PRIORITY
- Update API endpoints to respect
branch_idin queries - Enhance admin interface to show Branch assignment for assets
- Add Branch filtering to vehicle listing endpoints
LOW PRIORITY
- Consider creating dedicated
Garagemodel if Branch semantics differ significantly - Add Branch-level permissions for fleet managers
🔄 Synchronization Process
STRICT RULE: Apply changes ONLY via sync_engine.py:
docker compose exec roo-helper python3 /app/backend/app/scripts/sync_engine.py
DO NOT use Alembic migrations directly. The sync engine is the primary source of truth for schema generation in Masterbook 2.0.1 architecture.
📈 Next Steps
- User Approval: Present this "Gap Report" for approval before implementing changes
- Implementation: Apply the three high-priority model modifications
- Sync: Run
sync_engine.pyto update database schema - Testing: Execute the hierarchy verification test script
- Validation: Confirm GET /vehicles endpoint respects scope isolation
Audit Completed: 2026-03-29
Next Review: After gap implementation approval