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

### 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 (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` 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
- 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`).
- 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`
  - `/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` (auto‑migrated 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 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: `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 (non‑destructive): 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 auto‑migrate 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/*`
