8.8 KiB
8.8 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 backend (Fastify + TypeScript) includes an integrated platform module that shares Postgres and Redis with the rest of the stack.
- Goal: Predictable year→make→model→trim→engine cascades, production‑only workflow, AI‑friendly code layout and docs.
Platform Vehicles Module
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/platform
GET /api/platform/years→[number]distinct years (desc)GET /api/platform/makes?year={year}→{ makes: { id, name }[] }GET /api/platform/models?year={year}&make_id={make_id}→{ models: { id, name }[] }GET /api/platform/trims?year={year}&make_id={make_id}&model_id={model_id}→{ trims: { id, name }[] }GET /api/platform/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
- Auth0 JWT via
Authorization: Bearer ${JWT_TOKEN}(required for all platform endpoints) - Configured in backend:
src/core/plugins/auth.plugin.tswith JWKS validation
Caching (Redis)
- Keys:
dropdown:years,dropdown:makes:{year},dropdown:models:{year}:{make},dropdown:trims:{year}:{model},dropdown:engines:{year}:{model}:{trim} - Dropdown data TTL: 6 hours (21600 seconds)
- VIN decode cache TTL: 7 days (604800 seconds)
- Cache key format for VIN decodes:
vin:decode:{vin} - Implementation:
backend/src/features/platform/domain/platform-cache.service.ts
Seeds & Specific Examples
Platform seed migrations (TypeScript backend):
- Schema definition (
backend/src/features/platform/migrations/001_create_platform_schema.sql) - Constraints and indexes (
backend/src/features/platform/migrations/002_create_indexes.sql) - Sample vehicle data (
backend/src/features/platform/migrations/003_seed_vehicles.sql) Seeds are auto-migrated on backend container start viabackend/src/_system/migrations/run-all.ts.
Clear platform cache:
docker compose exec -T mvp-redis sh -lc "redis-cli FLUSHALL"- Or restart containers:
make rebuild
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
_migrationstable and skips already executed files - Idempotent at file level: Safe to re-run migration system multiple times
- 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 (includes platform module):
docker compose up -d --build backend
Logs & Health
- Backend:
/health– shows status/feature list, including platform readiness - Logs:
make logs-backend,make logs-frontend
Common Reset Sequences
- Platform seed reapply (non‑destructive): apply
005_seed_specific_vehicles.sqland flush Redis cache. - Platform reset (WARNING - DESTRUCTIVE to shared resources):
docker compose rm -sf mvp-postgres mvp-redisdocker volume rm motovaultpro_postgres_data motovaultpro_redis_datadocker compose up -d mvp-postgres mvp-redis mvp-backend- Note: This will destroy ALL application data, not just platform data, as database and cache are shared
Security Summary
- Platform Module: Auth0 JWT via
Authorization: Bearer ${JWT_TOKEN}required on all/api/platform/*endpoints. - Vehicles Feature: Auth0 JWT required on all protected
/api/vehicles/*routes. - Health Check:
/api/healthis unauthenticated (Traefik readiness probe).
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 shared Redis (mvp-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: maintained by database admins (legacy FastAPI scripts available on request)
- Platform API integration:
backend/src/features/platform/api/* - Backend dropdown proxy:
backend/src/features/vehicles/api/* - Backend platform module:
backend/src/features/platform/* - Backend migrations runner:
backend/src/_system/migrations/run-all.ts - Frontend vehicles UI:
frontend/src/features/vehicles/*