Initial Commit

This commit is contained in:
Eric Gullickson
2025-09-17 16:09:15 -05:00
parent 0cdb9803de
commit a052040e3a
373 changed files with 437090 additions and 6773 deletions

175
docs/VEHICLES-API.md Normal file
View File

@@ -0,0 +1,175 @@
# 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/*`