Files
motovaultpro/docs/VEHICLES-API.md
Eric Gullickson a052040e3a Initial Commit
2025-09-17 16:09:15 -05: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 Application Service (Fastify + TS) consumes the MVP Platform Vehicles Service (FastAPI + Postgres + Redis).
  • Goal: Predictable year→make→model→trim→engine cascades, productiononly workflow, AIfriendly 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_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
  • 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 tables
  • 002_constraints_indexes.sql constraints/indexes
  • 003_seed_minimal.sql minimal Honda/Toyota scaffolding
  • 004_seed_filtered_makes.sql Chevrolet/GMC examples
  • 005_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 /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 (idempotent)
    • 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: 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-frontend
    • docker compose logs -f mvp-platform-vehicles-api

Common Reset Sequences

  • Platform seed reapply (nondestructive): apply 005_seed_specific_vehicles.sql and flush Redis cache.
  • Platform reset (destructive only to platform DB/cache):
    • docker compose rm -sf mvp-platform-vehicles-db mvp-platform-vehicles-redis
    • docker volume rm motovaultpro_platform_vehicles_data motovaultpro_platform_vehicles_redis_data
    • docker 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.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 platform Redis.
  • 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/*