# MotoVaultPro Architecture Overview

## Architecture Summary

MotoVaultPro is a single-tenant vehicle management application built with a **5-container Docker-first architecture**. All development and deployment occurs in production-configured containers with no local installation dependencies.

### Core Containers
1. **Traefik** - Reverse proxy and service discovery
2. **Frontend** - React SPA with Vite (Node.js 20 + nginx)
3. **Backend** - Node.js API with Fastify (Node.js 20) - includes platform feature module
4. **PostgreSQL** - Primary database (PostgreSQL 18)
5. **Redis** - Caching layer (Redis 8)

### Key Architectural Principles
- **Production-Only**: All services use production builds and configuration
- **Docker-First**: Zero local installations, all work happens in containers
- **Single-Tenant**: Application serves a single user/tenant
- **User-Scoped Data**: All application data isolated by `user_id`
- **Feature Capsule Organization**: Self-contained feature modules in `backend/src/features/`

## Container Interaction Diagram

```
                                     Internet/Users
                                           |
                                           v
                         +----------------+------------------+
                         |           Traefik                 |
                         |   (Reverse Proxy & TLS)          |
                         |   Ports: 80, 443, 8080           |
                         +----------------+------------------+
                                          |
                    +---------------------+---------------------+
                    |                                           |
                    v                                           v
         +------------------+                        +--------------------+
         |    Frontend      |                        |      Backend       |
         |   React + Vite   |                        |  Node.js + Fastify |
         |   Port: 3000     |                        |    Port: 3001      |
         +------------------+                        +--------------------+
              (frontend network)                          (backend network)
                                                              |
                                                              |
                            +---------------------------------+
                            |                                 |
                            v                                 v
                    +---------------+                  +-------------+
                    |  PostgreSQL   |                  |    Redis    |
                    |   Port: 5432  |                  | Port: 6379  |
                    +---------------+                  +-------------+
                        (database network - internal)
```

## Network Topology

### Frontend Network
- **Purpose**: Public traffic routing
- **Type**: Bridge (non-internal)
- **Connected Services**: Traefik, Frontend
- **Access**: External (for Traefik public endpoints)

### Backend Network
- **Purpose**: API service communication
- **Type**: Bridge (non-internal)
- **Connected Services**: Traefik, Backend
- **Access**: External (requires Auth0 JWT validation)

### Database Network
- **Purpose**: Data layer isolation
- **Type**: Bridge (internal)
- **Connected Services**: Backend, PostgreSQL, Redis
- **Access**: Internal only, no external exposure

## Request Flow

### User Request Flow
```
1. User → HTTPS Request
2. Traefik → TLS Termination + Route Selection
   - Domain: motovaultpro.com or www.motovaultpro.com
   - Path: / → Frontend (priority 10)
   - Path: /api → Backend (priority 20)
   - Path: /api/platform/* → Backend (platform feature module)
3. Frontend/Backend → Process Request
4. Response → Traefik → User
```

### Authentication Flow
```
1. User → Frontend → Auth0 (Login)
2. Auth0 → JWT Token → Frontend
3. Frontend → Backend (with Authorization: Bearer <JWT>)
4. Backend → Validate JWT via Auth0 JWKS
5. Backend → Extract user_id from JWT (request.user.sub)
6. Backend → Execute user-scoped queries
7. Backend → Response → Frontend
```

### Backend Platform Flow
```
1. Backend Feature → Calls platform domain services (TypeScript in-process)
2. Platform module → Query PostgreSQL (vehicles schema)
3. Platform module → Check/Update Redis cache
4. Platform response → Returned to caller (vehicles, frontend proxies, etc.)
```

### Data Access Flow
```
1. Backend/Platform → PostgreSQL Query
   - Database: motovaultpro
   - Connection: Internal via database network
2. Backend/Platform → Redis Cache Check
   - Connection: Internal via database network
3. Response → Backend → Frontend
```

## Service Details

### Traefik (Reverse Proxy)
- **Image**: traefik:v3.0
- **Purpose**: Service discovery, TLS termination, load balancing
- **Ports**:
  - 80 (HTTP)
  - 443 (HTTPS)
  - 8080 (Dashboard)
- **Networks**: frontend, backend
- **Health Check**: `traefik healthcheck` (30s interval)
- **Configuration**:
  - `/etc/traefik/traefik.yml` - Main config
  - `/etc/traefik/middleware.yml` - Middleware rules
  - Dynamic routing via Docker labels

### Frontend (React SPA)
- **Technology**: React 18 + Vite + TypeScript
- **Build**: Multi-stage Dockerfile (node:lts-alpine → nginx:alpine)
- **Port**: 3000 (internal)
- **Networks**: frontend
- **Dependencies**: Backend (API calls)
- **Health Check**: `curl https://motovaultpro.com` (30s interval)
- **Environment Variables**:
  - `VITE_AUTH0_DOMAIN` - Auth0 tenant
  - `VITE_AUTH0_CLIENT_ID` - Auth0 application ID
  - `VITE_AUTH0_AUDIENCE` - API identifier
  - `VITE_API_BASE_URL` - Backend API path (/api)
- **Routing**: Traefik routes non-/api paths to frontend

### Backend (Node.js API)
- **Technology**: Node.js 20 + Fastify + TypeScript
- **Build**: Production build in node:lts-alpine
- **Port**: 3001 (internal)
- **Networks**: backend, database
- **Dependencies**: PostgreSQL, Redis, Platform
- **Health Check**: `https://motovaultpro.com/api/health` (30s interval)
- **Configuration**:
  - `/app/config/production.yml` - Main config
  - `/app/config/shared.yml` - Shared config
  - `/run/secrets/*` - Secret files (K8s pattern)
- **Secrets**:
  - `postgres-password` - Database password
  - `platform-vehicles-api-key` - Platform service auth
  - `auth0-client-secret` - Auth0 M2M secret
  - `google-maps-api-key` - Maps API key
- **Storage**: `/app/data/documents` - Document uploads

### PostgreSQL (Primary Database)
- **Image**: postgres:15-alpine
- **Database**: motovaultpro
- **Port**: 5432 (exposed for development)
- **Networks**: database (internal)
- **User**: postgres
- **Password**: File-based secret (`/run/secrets/postgres-password`)
- **Health Check**: `pg_isready -U postgres` (10s interval)
- **Storage**: Named volume `mvp_postgres_data`
- **Schemas**:
  - `public` - Application data (user-scoped)
  - `vehicles` - Platform vehicle data (shared)

### Redis (Cache Layer)
- **Image**: redis:7-alpine
- **Port**: 6379 (exposed for development)
- **Networks**: database (internal)
- **Persistence**: AOF enabled (`--appendonly yes`)
- **Health Check**: `redis-cli ping` (10s interval)
- **Storage**: Named volume `mvp_redis_data`
- **Usage**:
  - Vehicle data caching (year-based hierarchy)
  - Session storage (future)
  - Rate limiting (future)

### Platform Module (Vehicle Data)
- **Technology**: TypeScript feature capsule inside `backend/src/features/platform/`
- **Runtime**: Shares the `mvp-backend` Fastify container
- **Dependencies**: PostgreSQL, Redis (accessed via backend connection pool)
- **Deployment**: Bundled with backend build; no separate container or port
- **Health**: Covered by backend `/health` endpoint and feature-specific logs
- **Configuration**:
  - `backend/src/features/platform/domain/*.ts` - Business logic
  - `backend/src/features/platform/data/*.ts` - Database queries
- **Secrets**:
  - Reuses backend secrets (PostgreSQL, Auth0, etc.)
- **Purpose**:
  - Vehicle hierarchical data (years, makes, models, trims, engines)
  - VIN decoding (Planned/Future - not yet implemented)
  - Standardized vehicle information

## Platform Module Integration

### Current Architecture
Platform capabilities now run **in-process** within the backend as a feature capsule. This delivers:
- **Shared Language & Tooling**: TypeScript across the stack
- **Centralized Caching**: Reuses backend Redis helpers for year-based lookups
- **Simplified Operations**: No extra container to build, scale, or monitor

### Shared Infrastructure
- **Database**: Uses the backend connection pool against `mvp-postgres`
- **Cache**: Shares the backend Redis client (`mvp-redis`)
- **Runtime**: Packaged with the `mvp-backend` container and Fastify plugins
- **Secrets**: Relies on the same secret files as the backend (PostgreSQL, Auth0, etc.)

### Communication Pattern
```typescript
// Vehicles feature pulling platform data via domain services
const platformService = new PlatformVehicleDataService({
  db: postgresPool,
  cache: redisClient
});

const makes = await platformService.getMakes({ year: 2024 });
```

### Ongoing Work
- Continue migrating remaining FastAPI utilities into TypeScript where needed
- Expand `/api/platform/*` endpoints as new lookup types are added
- Monitor backend logs for `platform` namespace entries to verify health

## Feature Capsule Architecture

### Organization Pattern
Features are **self-contained modules** within the backend service at `backend/src/features/[name]/`:

```
backend/src/features/
├── admin/             # Admin role management
├── auth/              # User authentication
├── backup/            # Database backup/restore
├── documents/         # Document storage
├── fuel-logs/         # Fuel tracking
├── maintenance/       # Service records and schedules
├── notifications/     # Email and toast notifications
├── onboarding/        # User onboarding flow
├── platform/          # Vehicle data + VIN decoding
├── stations/          # Gas station locations
├── terms-agreement/   # T&C acceptance audit
├── user-export/       # GDPR data export
├── user-preferences/  # User settings
├── user-profile/      # User profile management
└── vehicles/          # Vehicle management
```

### Feature Structure
Each feature follows a standardized structure:
```
feature-name/
├── README.md          # Feature documentation
├── api/               # Route handlers
├── domain/            # Business logic
├── data/              # Data access layer
├── migrations/        # Database migrations
├── tests/             # Unit and integration tests
├── events/            # Event handlers (optional)
└── external/          # External service integrations (optional)
```

### Current Features (15)

#### Admin
- **Purpose**: Admin role management and oversight
- **Tables**: `admin_users`, `admin_audit_logs`
- **Endpoints**: Admin CRUD, catalog management, station oversight

#### Auth
- **Purpose**: User authentication and signup
- **Tables**: None (uses Auth0)
- **Integration**: Auth0 for identity management
- **Endpoints**: Signup, verify email, resend verification

#### Backup
- **Purpose**: Database and document backup/restore
- **Tables**: `backup_schedules`, `backup_history`, `backup_settings`
- **Storage**: `/app/data/backups/`
- **Endpoints**: Admin backup CRUD, restore, schedules

#### Documents
- **Purpose**: Document storage and retrieval
- **Tables**: `documents` (user-scoped)
- **Storage**: Filesystem (`/app/data/documents/`)
- **Endpoints**: Upload + download + delete

#### Fuel Logs
- **Purpose**: Fuel purchase and efficiency tracking
- **Tables**: `fuel_logs` (user-scoped)
- **Integration**: Stations feature for location data
- **Endpoints**: CRUD + analytics

#### Maintenance
- **Purpose**: Service and maintenance record tracking
- **Tables**: `maintenance_logs`, `maintenance_schedules` (user-scoped)
- **Integration**: Vehicles feature, notifications
- **Endpoints**: CRUD + schedules + reminders

#### Notifications
- **Purpose**: Email and toast notifications
- **Tables**: `email_templates`, `notification_logs`
- **Integration**: Resend API for email delivery
- **Endpoints**: User summary, admin template management

#### Onboarding
- **Purpose**: User onboarding after signup
- **Tables**: Uses `user_profiles`, `user_preferences`
- **Integration**: User profile and preferences features
- **Endpoints**: Preferences, complete, status

#### Platform
- **Purpose**: Vehicle data and VIN decoding
- **Tables**: `engines`, `transmissions`, `vehicle_options`
- **Integration**: Backend dropdown cascade queries
- **Endpoints**: Years, makes, models, trims, engines

#### Stations
- **Purpose**: Gas station location and pricing
- **Tables**: `stations`, `community_stations`
- **Integration**: Google Maps API
- **Endpoints**: Search + favorites + community reports

#### Terms Agreement
- **Purpose**: Legal audit trail for T&C acceptance
- **Tables**: `terms_agreements`
- **Integration**: Created during signup flow
- **Endpoints**: None (internal use)

#### User Export
- **Purpose**: GDPR-compliant data export
- **Tables**: None (reads from all user data)
- **Storage**: Temporary TAR.GZ archives
- **Endpoints**: Export download

#### User Preferences
- **Purpose**: User preference management
- **Tables**: `user_preferences` (user-scoped)
- **Endpoints**: GET/PUT preferences

#### User Profile
- **Purpose**: User profile management
- **Tables**: `user_profiles` (user-scoped)
- **Endpoints**: GET/PUT profile

#### Vehicles
- **Purpose**: Vehicle inventory management
- **Tables**: `vehicles` (user-scoped)
- **Integration**: Platform service for make/model/trim data
- **Endpoints**: CRUD + dropdown data + images

## Data Flow

### Authentication via Auth0 JWT
```
1. Frontend → Auth0 Login
2. Auth0 → JWT Token (contains user_id in 'sub' claim)
3. Frontend → Backend (Authorization: Bearer <JWT>)
4. Backend → Validate JWT:
   - Verify signature via Auth0 JWKS endpoint
   - Check issuer: https://{AUTH0_DOMAIN}/
   - Check audience: {AUTH0_AUDIENCE}
5. Backend → Extract user_id from token.sub
6. Backend → Execute user-scoped queries
```

### User ID Extraction
```typescript
// From auth.plugin.ts
await request.jwtVerify(); // Validates and populates request.user
const userId = request.user.sub; // Auth0 user ID (e.g., "auth0|123456")
```

### User-Scoped Data Access
All application data is isolated by `user_id`:

```sql
-- Example: Get user's vehicles
SELECT * FROM vehicles WHERE user_id = $1;

-- Example: Create fuel log (user_id inserted)
INSERT INTO fuel_logs (user_id, vehicle_id, gallons, cost, ...)
VALUES ($1, $2, $3, $4, ...);

-- Example: Soft delete (preserves audit trail)
UPDATE vehicles
SET deleted_at = NOW()
WHERE id = $1 AND user_id = $2;
```

### Data Isolation Strategy
- **Foreign Keys**: All user data tables have `user_id` foreign key
- **Query Scoping**: All queries filtered by authenticated user's ID
- **Soft Deletes**: `deleted_at` timestamp for audit trail
- **No Cascade Deletes**: Prevents accidental data loss
- **Index Strategy**: Composite indexes on (`user_id`, primary key)

### Cross-Feature Data Flow
```
1. User creates vehicle (Vehicles feature)
2. User logs fuel purchase (Fuel Logs feature)
   - References vehicle_id
   - References station_id (Stations feature)
3. User adds maintenance record (Maintenance feature)
   - References vehicle_id
   - Can attach documents (Documents feature)
```

## Configuration Management

### Kubernetes-Style Patterns
The application uses Kubernetes-inspired configuration patterns:

**ConfigMaps** (YAML files):
- `/app/config/production.yml` - Service-specific config
- `/app/config/shared.yml` - Cross-service config

**Secrets** (File-based):
- `/run/secrets/postgres-password` - Database credentials
- `/run/secrets/auth0-client-secret` - OAuth credentials
- `/run/secrets/google-maps-api-key` - External API keys

### Environment Variables
Used for service references and runtime configuration:
```yaml
NODE_ENV: production
CONFIG_PATH: /app/config/production.yml
SECRETS_DIR: /run/secrets
DATABASE_HOST: mvp-postgres
REDIS_HOST: mvp-redis
```

## Development Workflow

### Container Commands (via Makefile)
```bash
make start          # Start all containers
make stop           # Stop all containers
make restart        # Restart all containers
make rebuild        # Rebuild and restart containers
make logs           # View all container logs
make logs-backend   # View backend logs only
make clean          # Remove containers and volumes
```

### Health Monitoring
```bash
# Check container health
docker ps

# View specific service logs
docker logs mvp-backend -f
docker logs mvp-postgres -f

# Test health endpoints (via Traefik)
curl https://motovaultpro.com/api/health  # Backend (includes platform module)

# Or from within backend container
docker compose exec mvp-backend curl https://motovaultpro.com/api/health
```

### Database Access
```bash
# PostgreSQL shell
make db-shell-app

# Execute SQL
docker exec -it mvp-postgres psql -U postgres -d motovaultpro

# View Redis data
docker exec -it mvp-redis redis-cli
```

## Security Architecture

### Authentication & Authorization
- **Provider**: Auth0 (OAuth 2.0 / OpenID Connect)
- **Token Type**: JWT (JSON Web Token)
- **Validation**: JWKS-based signature verification
- **Token Cache**: 1 hour TTL for Auth0 public keys
- **Issuer Validation**: Prevents token spoofing
- **Audience Validation**: API-specific tokens only

### Protected Resources
All API endpoints require valid JWT except:
- `/health` - Health check (priority routing)
- `/api/health` - API health check (bypass auth)

### Data Security
- **VIN Handling**: Check digit validation, no VIN in logs
- **User Isolation**: Queries filtered by authenticated `user_id`
- **Soft Deletes**: Audit trail preservation
- **No Cascading Deletes**: Manual data cleanup only
- **Encrypted Connections**: PostgreSQL SSL/TLS

### Infrastructure Security
- **Non-root Containers**: All services run as non-root users
- **Network Isolation**: Internal database network
- **Secret Management**: File-based secrets (K8s pattern)
- **No Hardcoded Credentials**: Environment and file injection only

## Deployment Strategy

### Production Environment
- **Container Orchestration**: Docker Compose (current) → Kubernetes (future)
- **Service Discovery**: Traefik with Docker provider
- **TLS**: Automatic certificate management via Traefik
- **Scaling**: Single instance per service (MVP phase)
- **Monitoring**: Container health checks + log aggregation

### Zero-Downtime Deployment
```bash
# Build new images
make rebuild

# Traefik handles traffic routing during restart
# Health checks ensure services are ready before traffic
```

## Observability

### Logging Strategy
- **Format**: Structured JSON logging
- **Levels**: ERROR, WARN, INFO, DEBUG
- **Context**: Request ID, User ID (truncated), Service name
- **Aggregation**: Docker logs → Future: ELK/Loki stack

### Health Checks
Every service exposes health endpoints:
- **Backend**: `GET /health` - Database + Redis connectivity
- **Platform**: `GET /health` - Database + Redis connectivity
- **Frontend**: Nginx status check
- **PostgreSQL**: `pg_isready`
- **Redis**: `redis-cli ping`

### Metrics (Future)
- Request rate and latency
- Database query performance
- Cache hit rates
- Error rates by endpoint

## Performance Considerations

### Caching Strategy
- **Vehicle Data**: Year-based hierarchical caching in Redis
- **JWT Keys**: 1-hour cache for Auth0 public keys
- **Database Queries**: Indexed by (`user_id`, primary key)

### Database Optimization
- **Connection Pooling**: Fastify PostgreSQL plugin
- **Prepared Statements**: SQL injection prevention + performance
- **Indexes**: Composite indexes on frequently queried columns
- **Query Scoping**: All queries filtered by `user_id` for data locality

### Horizontal Scaling (Future)
- **Stateless Services**: Backend and Platform can scale horizontally
- **Shared State**: PostgreSQL and Redis as centralized state
- **Load Balancing**: Traefik distributes traffic across instances

## Related Documentation

- Feature Documentation: `backend/src/features/{feature}/README.md`
- Platform Architecture: `docs/PLATFORM-SERVICES.md`
- Security Details: `docs/SECURITY.md`
- Database Schema: `docs/DATABASE-SCHEMA.md`
- Testing Guide: `docs/TESTING.md`
- Vehicles API: `docs/VEHICLES-API.md`
- Development Commands: `Makefile`
