10 KiB
P0 DEEP AUDIT - Database Consistency & Zombie API Hunt Report
Date: 2026-06-21
Author: Fast Coder (Core Developer)
Gitea Issue: #274
Scope: Database schemas vehicle, finance, fleet_finance + Backend API endpoints
1. Database Cleanliness
1.1 Schema: vehicle (20 tables)
| Table | Purpose | Status |
|---|---|---|
assets |
Core vehicle assets (thick model) | ✅ Clean |
asset_events |
Service/maintenance events | ✅ Clean |
asset_inspections |
Inspection records | ✅ Clean |
asset_reviews |
User reviews | ✅ Clean |
asset_telemetry |
Telemetry data | ✅ Clean |
auto_data_crawler_queue |
Crawler queue | ✅ Clean |
catalog_discovery |
Catalog discovery queue | ✅ Clean |
dict_body_types |
Body type dictionary | ✅ Clean |
external_reference_library |
External reference data | ✅ Clean |
feature_definitions |
Feature definitions | ✅ Clean |
gb_catalog_discovery |
GB catalog discovery | ✅ Clean |
model_feature_maps |
Model-feature mappings | ✅ Clean |
motorcycle_specs |
Motorcycle specs | ✅ Clean |
odometer_readings |
Odometer readings | ✅ Clean |
reference_lookup |
Reference lookup | ✅ Clean |
vehicle_catalog |
Vehicle catalog | ✅ Clean |
vehicle_logbook |
Trip logbook | ✅ Clean |
vehicle_model_definitions |
Master model definitions | ✅ Clean |
vehicle_ownership_history |
Ownership history | ✅ Clean |
vehicle_transfer_requests |
Transfer requests | ✅ Clean |
vehicle_types |
Vehicle type dictionary | ✅ Clean |
vehicle_user_ratings |
User ratings | ✅ Clean |
1.2 Schema: fleet_finance (6 tables)
| Table | Purpose | Status |
|---|---|---|
asset_costs |
Cost ledger (moved from vehicle) |
✅ Clean |
asset_financials |
Purchase/financing data (moved from vehicle) |
✅ Clean |
cost_categories |
Cost category hierarchy (moved from vehicle) |
✅ Clean |
insurance_providers |
Insurance provider catalog | ✅ Clean |
vehicle_insurance_policies |
Vehicle insurance policies | ✅ Clean |
vehicle_tax_obligations |
Vehicle tax obligations | ✅ Clean |
1.3 Schema: finance (7 tables)
| Table | Purpose | Status |
|---|---|---|
credit_logs |
Credit transactions | ✅ Clean |
exchange_rates |
Currency exchange rates | ✅ Clean |
issuers |
Billing entities | ✅ Clean |
org_subscriptions |
Organization subscriptions | ✅ Clean |
payment_intents |
Payment intents | ✅ Clean |
user_subscriptions |
User subscriptions | ✅ Clean |
withdrawal_requests |
Withdrawal requests | ✅ Clean |
1.4 Critical Checks
| Check | Result |
|---|---|
vehicle.vehicle_expenses exists? |
❌ NOT FOUND - Correctly removed |
vehicle.costs (VehicleCost) exists? |
❌ NOT FOUND - Correctly removed |
data schema has leftover tables? |
❌ NOT FOUND - Schema is empty |
Duplicate table names between vehicle and fleet_finance? |
❌ NONE - No overlap |
Legacy expense/cost tables anywhere? |
❌ NONE - Clean |
Verdict: ✅ DATABASE IS CLEAN. No duplicated tables, no legacy tables left behind. The migration of AssetCost, CostCategory, AssetFinancials from vehicle → fleet_finance schema is complete.
2. Zombie API Endpoints
2.1 🔴 CRITICAL: reports.py - References vehicle.vehicle_expenses
File: backend/app/api/v1/endpoints/reports.py
Two endpoints use raw SQL queries referencing the non-existent vehicle.vehicle_expenses table:
GET /reports/summary/{vehicle_id}(line 8-32) - QueriesFROM vehicle.vehicle_expensesGET /reports/trends/{vehicle_id}(line 34-50) - QueriesFROM vehicle.vehicle_expenses
Impact: These endpoints will ALWAYS return 500 errors because the table vehicle.vehicle_expenses does not exist in the database.
Router registration: api.py - Registered as prefix="/reports"
2.2 🟡 WARNING: expenses.py - Uses AssetCost from fleet_finance (correct)
File: backend/app/api/v1/endpoints/expenses.py
Imports AssetCost and CostCategory from app.models which correctly resolves to fleet_finance schema models. This is NOT a zombie - it's correctly using the moved models.
2.3 🟡 WARNING: assets.py - Uses AssetCost from fleet_finance (correct)
File: backend/app/api/v1/endpoints/assets.py
Imports AssetCost, CostCategory from app.models and AssetFinancials, VehicleInsurancePolicy, VehicleTaxObligation from app.models.fleet_finance. Correctly references the new schema.
2.4 🟢 OK: dictionaries.py - Uses CostCategory from fleet_finance
File: backend/app/api/v1/endpoints/dictionaries.py
Imports CostCategory from app.models.fleet_finance. Correct.
2.5 Zombie API Summary
| Endpoint File | Route Prefix | Status | Issue |
|---|---|---|---|
reports.py |
/reports/summary/{id} |
🔴 ZOMBIE | References vehicle.vehicle_expenses (DNE) |
reports.py |
/reports/trends/{id} |
🔴 ZOMBIE | References vehicle.vehicle_expenses (DNE) |
reports.py |
/reports/summary/latest |
🟢 OK | Returns mock data only |
expenses.py |
/expenses/{asset_id} |
🟢 OK | Uses AssetCost from fleet_finance |
assets.py |
/assets/vehicles/{id}/costs |
🟢 OK | Uses AssetCost from fleet_finance |
assets.py |
/assets/vehicles/{id}/insurance |
🟢 OK | Uses VehicleInsurancePolicy |
assets.py |
/assets/vehicles/{id}/tax |
🟢 OK | Uses VehicleTaxObligation |
dictionaries.py |
/dictionaries/cost-categories |
🟢 OK | Uses CostCategory from fleet_finance |
3. InsuranceProvider & Missing CRUD Analysis
3.1 InsuranceProvider Model
The InsuranceProvider model exists in fleet_finance.insurance_providers with fields:
id(Integer, PK)name(String, unique)claim_phone(String, nullable)claim_url(String, nullable)services_offered(JSONB)is_active(Boolean)
3.2 Existing Insurance/Tax Endpoints in assets.py
| Method | Route | Exists? |
|---|---|---|
GET |
/assets/vehicles/{asset_id}/insurance |
✅ Yes (list) |
POST |
/assets/vehicles/{asset_id}/insurance |
✅ Yes (create) |
PUT |
/assets/vehicles/{asset_id}/insurance/{policy_id} |
❌ MISSING |
DELETE |
/assets/vehicles/{asset_id}/insurance/{policy_id} |
❌ MISSING |
GET |
/assets/vehicles/{asset_id}/tax |
✅ Yes (list) |
POST |
/assets/vehicles/{asset_id}/tax |
✅ Yes (create) |
PUT |
/assets/vehicles/{asset_id}/tax/{tax_id} |
❌ MISSING |
DELETE |
/assets/vehicles/{asset_id}/tax/{tax_id} |
❌ MISSING |
3.3 InsuranceProvider CRUD (Standalone)
| Method | Route | Exists? |
|---|---|---|
GET |
/insurance-providers |
❌ MISSING |
GET |
/insurance-providers/{id} |
❌ MISSING |
POST |
/insurance-providers |
❌ MISSING |
PUT |
/insurance-providers/{id} |
❌ MISSING |
DELETE |
/insurance-providers/{id} |
❌ MISSING |
No schema exists for InsuranceProvider - searched backend/app/schemas/ for InsuranceProvider patterns - 0 results.
4. Action Plan
4.1 🔴 P0 - Fix Zombie Endpoints in reports.py
Problem: Two endpoints in reports.py reference the non-existent vehicle.vehicle_expenses table.
Solution: Rewrite the raw SQL queries to use the new fleet_finance.asset_costs table with proper joins to cost_categories:
# Replace raw SQL with SQLAlchemy ORM queries using AssetCost + CostCategory
from app.models import AssetCost, CostCategory
from sqlalchemy import select, func
# GET /reports/summary/{vehicle_id}
stmt = select(
CostCategory.code.label("category"),
func.sum(AssetCost.amount_gross).label("total_amount"),
func.count(AssetCost.id).label("transaction_count")
).outerjoin(CostCategory, AssetCost.category_id == CostCategory.id
).where(AssetCost.asset_id == vehicle_id
).group_by(CostCategory.code)
Estimated effort: 30 minutes
4.2 🟡 P1 - Add UPDATE/DELETE for Insurance Policies and Tax Obligations
Missing endpoints in assets.py:
PUT /assets/vehicles/{asset_id}/insurance/{policy_id}- Update insurance policyDELETE /assets/vehicles/{asset_id}/insurance/{policy_id}- Delete insurance policyPUT /assets/vehicles/{asset_id}/tax/{tax_id}- Update tax obligationDELETE /assets/vehicles/{asset_id}/tax/{tax_id}- Delete tax obligation
Estimated effort: 1 hour
4.3 🟡 P1 - Create InsuranceProvider CRUD Endpoints
Missing: Complete CRUD for standalone InsuranceProvider catalog:
- Create schema:
InsuranceProviderResponse,InsuranceProviderCreate,InsuranceProviderUpdate - Create new endpoint file or add to existing router
- Endpoints:
GET /insurance-providers,GET /insurance-providers/{id},POST /insurance-providers,PUT /insurance-providers/{id},DELETE /insurance-providers/{id}
Estimated effort: 1.5 hours
4.4 🟢 P2 - Add InsuranceProvider to Admin UI
Once the API endpoints exist, add the InsuranceProvider management to the admin panel.
Estimated effort: 1 hour
5. Summary
| Category | Status |
|---|---|
| Database Cleanliness | ✅ PASS - No duplicates, no legacy tables |
| Zombie API Endpoints | 🔴 2 CRITICAL - reports.py references vehicle.vehicle_expenses |
| InsuranceProvider CRUD | ❌ FULLY MISSING - No standalone endpoints |
| Insurance Policy UPDATE/DELETE | ❌ MISSING - Only GET and POST exist |
| Tax Obligation UPDATE/DELETE | ❌ MISSING - Only GET and POST exist |
Total estimated fix effort: ~4 hours