8.6 KiB
8.6 KiB
Vehicles API – Platform Rebuild, App Integration, and Operations
This document explains the end‑to‑end Vehicles API architecture after the platform service rebuild, how the MotoVaultPro app consumes it, how migrations/seeding work, and how to operate the stack in production‑only development.
Overview
- Architecture: MotoVaultPro Application Service (Fastify + TS) consumes the MVP Platform Vehicles Service (FastAPI + Postgres + Redis).
- Goal: Predictable year→make→model→trim→engine cascades, production‑only workflow, AI‑friendly code layout and docs.
Platform Vehicles Service
Database Schema (Postgres schema: vehicles)
make(id, name)model(id, make_id → make.id, name)model_year(id, model_id → model.id, year)trim(id, model_year_id → model_year.id, name)engine(id, name, code, displacement_l, cylinders, fuel_type, aspiration)trim_engine(trim_id → trim.id, engine_id → engine.id)- Optional (present, not exposed yet):
transmission,trim_transmission,performance
Idempotent constraints/indexes added where applicable (e.g., unique lower(name), unique(model_id, year), guarded CREATE INDEX IF NOT EXISTS, guarded trigger).
API Endpoints (Bearer auth required)
Prefix: /api/v1/vehicles
GET /years→[number]distinct years (desc)GET /makes?year={year}→{ makes: { id, name }[] }GET /models?year={year}&make_id={make_id}→{ models: { id, name }[] }GET /trims?year={year}&make_id={make_id}&model_id={model_id}→{ trims: { id, name }[] }GET /engines?year={year}&make_id={make_id}&model_id={model_id}&trim_id={trim_id}→{ engines: { id, name }[] }
Notes:
make_idis maintained for a consistent query chain, but engines are enforced by(year, model_id, trim_id).- Trims/engines include
idto enable the next hop in the UI.
Authentication
- Header:
Authorization: Bearer ${API_KEY} - API env:
API_KEY - Backend env (consumer):
PLATFORM_VEHICLES_API_KEY
Caching (Redis)
- Keys:
dropdown:years,dropdown:makes:{year},dropdown:models:{year}:{make},dropdown:trims:{year}:{model},dropdown:engines:{year}:{model}:{trim} - Default TTL: 6 hours
Seeds & Specific Examples
Seed files under mvp-platform-services/vehicles/sql/schema/:
001_schema.sql– base tables002_constraints_indexes.sql– constraints/indexes003_seed_minimal.sql– minimal Honda/Toyota scaffolding004_seed_filtered_makes.sql– Chevrolet/GMC examples005_seed_specific_vehicles.sql– requested examples:- 2023 GMC Sierra 1500 AT4x → Engine L87 (6.2L V8)
- 2017 Chevrolet Corvette Z06 Convertible → Engine LT4 (6.2L V8 SC)
Reapply seeds on an existing volume:
docker compose exec -T mvp-platform-vehicles-db psql -U mvp_platform_user -d vehicles -f /docker-entrypoint-initdb.d/005_seed_specific_vehicles.sql- Clear platform cache:
docker compose exec -T mvp-platform-vehicles-redis sh -lc "redis-cli FLUSHALL"
MotoVaultPro Backend (Application Service)
Proxy Dropdown Endpoints
Prefix: /api/vehicles/dropdown
GET /years→[number](calls platform/years)GET /makes?year=YYYY→{ id, name }[]GET /models?year=YYYY&make_id=ID→{ id, name }[]GET /trims?year=YYYY&make_id=ID&model_id=ID→{ id, name }[]GET /engines?year=YYYY&make_id=ID&model_id=ID&trim_id=ID→{ id, name }[]
Changes:
- Engines route now requires
trim_id. - New
/yearsroute for UI bootstrap.
Platform Client & Integration
PlatformVehiclesClient:- Added
getYears() getEngines(year, makeId, modelId, trimId)to pass trim id
- Added
PlatformIntegrationServiceconsumed byVehiclesServiceupdated accordingly.
Authentication (App)
- Auth0 JWT enforced via Fastify + JWKS. No mock users.
Migrations (Production‑Quality)
- Migrations packaged in image under
/app/migrations/features/[feature]/migrations. - Runner (
backend/src/_system/migrations/run-all.ts):- Reads base dir from
MIGRATIONS_DIR(env in Dockerfile) - Tracks executed files in
_migrations(idempotent) - Wait/retry for DB readiness to avoid flapping on cold starts
- Reads base dir from
- Auto‑migrate on backend container start:
node dist/_system/migrations/run-all.js && npm start - Manual:
make migrate(runs runner inside the container)
Frontend Changes
- Vehicles form cascades: year → make → model → trim → engine.
- Engines load only after a trim is selected (requires
trim_id).
- Engines load only after a trim is selected (requires
- Validation updated: user must provide either a 17‑char VIN or a non‑empty license plate.
- VIN Decode button still requires a valid 17‑char VIN.
- APIs used:
/api/vehicles/dropdown/years/api/vehicles/dropdown/makes|models|trims|engines
Add Vehicle Form – Change/Add/Modify/Delete Fields (Fast Track)
Where to edit
- UI + validation:
frontend/src/features/vehicles/components/VehicleForm.tsx - Frontend types:
frontend/src/features/vehicles/types/vehicles.types.ts - Backend controller/service/repo:
backend/src/features/vehicles/api/vehicles.controller.ts,domain/vehicles.service.ts,data/vehicles.repository.ts, types indomain/vehicles.types.ts - App DB migrations:
backend/src/features/vehicles/migrations/*.sql(auto‑migrated on backend start)
Add a new field (example: bodyStyle)
- DB:
ALTER TABLE vehicles ADD COLUMN IF NOT EXISTS body_style VARCHAR(100);in a new migration file. - Backend: add
bodyStyle?: string;to types; include in repository insert/update mapping asbody_style. - Frontend: add
bodyStyleto Zod schema and a new input bound viaregister('bodyStyle'). - Rebuild frontend/backend and verify in Network + logs.
Modify an existing field
- Update labels/placeholders in VehicleForm.
- Update Zod schema for new validation rules; mirror on the server if desired.
- Adjust service logic only if business behavior changes.
Delete a field (safe path)
- Remove from VehicleForm and frontend types.
- Remove from backend types/repository mapping.
- Optional migration to drop the column later.
Dropdown ordering
- Implemented in VehicleForm; current order is Year → Make → Model → Trim → Engine → Transmission (static).
- Engine select is enabled only after a Trim is selected.
VIN/License rule
- Frontend Zod: either 17‑char VIN or non‑empty license plate; if no plate, VIN must be 17.
- Backend controller enforces the same rule; service decodes/validates only when VIN is present.
- Repository normalizes empty VIN to NULL to avoid unique collisions.
Operations
Rebuild a single service
- Frontend:
docker compose up -d --build frontend - Backend:
docker compose up -d --build backend - Platform API:
docker compose up -d --build mvp-platform-vehicles-api
Logs & Health
- Backend:
/health– shows status/feature list - Platform:
/health– shows database/cache status - Logs:
make logs-backend,make logs-frontenddocker compose logs -f mvp-platform-vehicles-api
Common Reset Sequences
- Platform seed reapply (non‑destructive): apply
005_seed_specific_vehicles.sqland flush Redis cache. - Platform reset (destructive only to platform DB/cache):
docker compose rm -sf mvp-platform-vehicles-db mvp-platform-vehicles-redisdocker volume rm motovaultpro_platform_vehicles_data motovaultpro_platform_vehicles_redis_datadocker compose up -d mvp-platform-vehicles-db mvp-platform-vehicles-redis mvp-platform-vehicles-api
Security Summary
- Platform:
Authorization: Bearer ${API_KEY}required on all/api/v1/vehicles/*endpoints. - App Backend: Auth0 JWT required on all protected
/api/*routes.
CI Summary
- Workflow
.github/workflows/ci.ymlbuilds backend/frontend/platform API. - Runs backend lint/tests in a builder image on a stable network.
Troubleshooting
- Frontend shows generic “Server error” right after login:
- Check backend
/api/vehicles500s (migrations not run or DB unavailable). - Run
make migrateor ensure backend container auto‑migrate is succeeding; checkdocker compose logs backend.
- Check backend
- Dropdowns not updating after seed:
- Run specific seed SQL (see above) and
redis-cli FLUSHALLon platform Redis.
- Run specific seed SQL (see above) and
- Backend flapping on start after rebuild:
- Ensure Postgres is up; the runner now waits/retries, but confirm logs.
Notable Files
- Platform schema & seeds:
mvp-platform-services/vehicles/sql/schema/001..005 - Platform API code:
mvp-platform-services/vehicles/api/* - Backend dropdown proxy:
backend/src/features/vehicles/api/* - Backend platform client:
backend/src/features/vehicles/external/platform-vehicles/* - Backend migrations runner:
backend/src/_system/migrations/run-all.ts - Frontend vehicles UI:
frontend/src/features/vehicles/*