Files
service-finder/docs/db_consistency_and_zombie_api_report.md
2026-06-23 21:11:21 +00:00

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 vehiclefleet_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:

  1. GET /reports/summary/{vehicle_id} (line 8-32) - Queries FROM vehicle.vehicle_expenses
  2. GET /reports/trends/{vehicle_id} (line 34-50) - Queries FROM 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:

  1. PUT /assets/vehicles/{asset_id}/insurance/{policy_id} - Update insurance policy
  2. DELETE /assets/vehicles/{asset_id}/insurance/{policy_id} - Delete insurance policy
  3. PUT /assets/vehicles/{asset_id}/tax/{tax_id} - Update tax obligation
  4. DELETE /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:

  1. Create schema: InsuranceProviderResponse, InsuranceProviderCreate, InsuranceProviderUpdate
  2. Create new endpoint file or add to existing router
  3. 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