Files
motovaultpro/docs/VEHICLES-API.md
Eric Gullickson 0c3ed01f4b Pre-web changes
2025-11-05 11:04:48 -06:00

9.3 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).

Dropdown API (Bearer auth required)

Prefix: /api/vehicles/dropdown

  • GET /years[number] (latest to oldest model years)
  • GET /makes?year={year}{ id, name }[] (makes available in that year)
  • GET /models?year={year}&make_id={make}{ id, name }[] (models filtered by year + make)
  • GET /trims?year={year}&make_id={make}&model_id={model}{ id, name }[] (trims for the selection)
  • GET /engines?year={year}&make_id={make}&model_id={model}&trim_id={trim}{ id, name }[] (engines for the trim)
  • GET /transmissions?year={year}&make_id={make}&model_id={model}{ id, name }[] (Automatic, Manual)

Selection order is enforced: each endpoint requires the IDs returned by the previous stage, so users never see invalid combinations (e.g., 2023 Chevrolet excludes the S-10, 1999 GMC trims exclude AT4X, etc.).

Platform module (internal bridge)

Prefix: /api/platform

  • Same hierarchical endpoints as above, but responses are wrapped ({ makes: [...] }, { models: [...] }) for service-to-service integrations.
  • VIN decode endpoint: GET /api/platform/vehicle?vin={vin}

Authentication

  • Auth0 JWT via Authorization: Bearer ${JWT_TOKEN} (required for both /api/vehicles/* and /api/platform/*)
  • Configured in backend: src/core/plugins/auth.plugin.ts with JWKS validation

Caching (Redis)

  • Keys: platform:years, platform:vehicle-data:makes:{year}, platform:vehicle-data:models:{year}:{make}, platform:vehicle-data:trims:{year}:{model}, platform:vehicle-data:engines:{year}:{model}:{trim}
  • Dropdown TTL: 6 hours (21600s)
  • VIN decode TTL: 7 days (604800s) via platform: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 via backend/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

Vehicles service simply re-emits the data returned by Platform VehicleDataService, normalizing it to { id, name }[] arrays for frontend consumption. Redis caching and Postgres lookups all remain centralized in the platform module.

Platform Integration

  • VehiclesService lazily instantiates VehicleDataService via getVehicleDataService(), guaranteeing a shared cache.
  • Each dropdown call passes the shared Postgres pool (getPool()) and propagates selection context (year/make/model/trim).
  • Transmission dropdown is intentionally static (Automatic, Manual) until richer metadata is available.

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
    • /api/vehicles/dropdown/transmissions

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: https://motovaultpro.com/api/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 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/health is unauthenticated (Traefik readiness probe).

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/*