Files
motovaultpro/docs/VEHICLES-API.md
Eric Gullickson 3693ce5761 Docs Cleanup
2025-11-02 10:34:43 -06:00

179 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 service (FastAPI) with shared Postgres and 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: 1 hour (3600 seconds)
- **Configurable**: Set via `CACHE_TTL` environment variable in seconds
### 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-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: `docker compose up -d --build backend`
- Platform API: `docker compose up -d --build mvp-platform`
### 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`
### 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-platform`
- 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: `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/*`