Files
motovaultpro/docs/VEHICLES-API.md
Eric Gullickson d8d0ada83f Docs Cleanup
2025-11-03 16:12:29 -06:00

8.6 KiB
Raw Blame History

Vehicles API Platform Rebuild, App Integration, and Operations

This document explains the endtoend 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 productiononly 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, productiononly workflow, AIfriendly 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_id is maintained for a consistent query chain, but engines are enforced by (year, model_id, trim_id).
  • Trims/engines include id to enable the next hop in the UI.

Authentication

  • Header: Authorization: Bearer ${API_KEY}
  • API env: 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: 1 hour (3600 seconds)
  • Configurable: Set via CACHE_TTL environment variable in seconds

Seeds & Specific Examples

Legacy FastAPI SQL seed scripts covered:

  • Base schema (001_schema.sql)
  • Constraints/indexes (002_constraints_indexes.sql)
  • Minimal Honda/Toyota scaffolding (003_seed_minimal.sql)
  • Chevrolet/GMC examples (004_seed_filtered_makes.sql)
  • Targeted sample vehicles (005_seed_specific_vehicles.sql) Contact the data team for access to these archival scripts if reseeding is required.

Reapply seeds on an existing volume:

  • docker compose exec -T mvp-postgres psql -U mvp_user -d mvp_db -f /docker-entrypoint-initdb.d/005_seed_specific_vehicles.sql
  • Clear platform cache: docker compose exec -T mvp-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 /years route for UI bootstrap.

Platform Client & Integration

  • PlatformVehiclesClient:
    • Added getYears()
    • getEngines(year, makeId, modelId, trimId) to pass trim id
  • PlatformIntegrationService consumed by VehiclesService updated accordingly.

Authentication (App)

  • Auth0 JWT enforced via Fastify + JWKS. No mock users.

Migrations (ProductionQuality)

  • 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 table 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
  • Automigrate 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).
  • Validation updated: user must provide either a 17char VIN or a nonempty license plate.
    • VIN Decode button still requires a valid 17char 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 in domain/vehicles.types.ts
  • App DB migrations: backend/src/features/vehicles/migrations/*.sql (automigrated on backend start)

Add a new field (example: bodyStyle)

  1. DB: ALTER TABLE vehicles ADD COLUMN IF NOT EXISTS body_style VARCHAR(100); in a new migration file.
  2. Backend: add bodyStyle?: string; to types; include in repository insert/update mapping as body_style.
  3. Frontend: add bodyStyle to Zod schema and a new input bound via register('bodyStyle').
  4. 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 17char VIN or nonempty 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 (nondestructive): apply 005_seed_specific_vehicles.sql and flush Redis cache.
  • Platform reset (WARNING - DESTRUCTIVE to shared resources):
    • docker compose rm -sf mvp-postgres mvp-redis
    • docker volume rm motovaultpro_postgres_data motovaultpro_redis_data
    • docker 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: 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.yml builds 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/vehicles 500s (migrations not run or DB unavailable).
    • Run make migrate or ensure backend container automigrate is succeeding; check docker compose logs backend.
  • Dropdowns not updating after seed:
    • Run specific seed SQL (see above) and redis-cli FLUSHALL on shared Redis (mvp-redis).
  • 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/*