From 17d27f4b923a6be1e612b3626e1e730cd1c0dd04 Mon Sep 17 00:00:00 2001 From: Eric Gullickson <16152721+ericgullickson@users.noreply.github.com> Date: Wed, 17 Sep 2025 20:47:42 -0500 Subject: [PATCH] k8s improvement --- AGENTS.md | 159 +++++ K8S-REDESIGN.md | 655 ++++++++++++++++++ frontend/src/core/hooks/useDataSync.ts | 7 +- frontend/src/core/sync/data-sync.ts | 44 +- .../etl/__pycache__/__init__.cpython-311.pyc | Bin 129 -> 129 bytes .../etl/__pycache__/config.cpython-311.pyc | Bin 2897 -> 2897 bytes .../__pycache__/connections.cpython-311.pyc | Bin 9053 -> 9053 bytes .../etl/__pycache__/main.cpython-311.pyc | Bin 21643 -> 21643 bytes .../etl/__pycache__/pipeline.cpython-311.pyc | Bin 6147 -> 6147 bytes .../etl/__pycache__/scheduler.cpython-311.pyc | Bin 3755 -> 3755 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 138 -> 138 bytes ...normalized_vehicle_builder.cpython-311.pyc | Bin 17759 -> 17759 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 141 -> 141 bytes .../nhtsa_downloader.cpython-311.pyc | Bin 9535 -> 9535 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 140 -> 140 bytes .../json_extractor.cpython-311.pyc | Bin 33282 -> 33282 bytes .../mssql_extractor.cpython-311.pyc | Bin 18293 -> 18293 bytes .../vin_proc_extractor.cpython-311.pyc | Bin 5448 -> 5448 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 137 -> 137 bytes .../json_manual_loader.cpython-311.pyc | Bin 33284 -> 33284 bytes .../__pycache__/mssql_loader.cpython-311.pyc | Bin 24796 -> 24796 bytes .../postgres_loader.cpython-311.pyc | Bin 18420 -> 18420 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 139 -> 139 bytes .../manual_json_pipeline.cpython-311.pyc | Bin 24357 -> 24357 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 220 -> 220 bytes .../engine_spec_parser.cpython-311.pyc | Bin 16245 -> 16245 bytes .../utils/__pycache__/logging.cpython-311.pyc | Bin 1717 -> 1717 bytes .../__pycache__/make_filter.cpython-311.pyc | Bin 6574 -> 6574 bytes .../make_name_mapper.cpython-311.pyc | Bin 14760 -> 14760 bytes 29 files changed, 836 insertions(+), 29 deletions(-) create mode 100644 AGENTS.md create mode 100644 K8S-REDESIGN.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..5c19949 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,159 @@ +# Development Partnership Guidelines + +## Core Development Principles + +### AI Context Efficiency +**CRITICAL**: All development practices and choices should be made taking into account the most context efficient interaction with another AI. Any AI should be able to understand this application with minimal prompting. + +### Codebase Integrity Rules +- Never create new files that don't already exist +- Never make up things that aren't part of the actual project +- Never skip or ignore existing system architecture +- Only work with the files and structure that already exist +- Be precise and respectful of the current codebase +- **Delete** old code when replacing it +- **Meaningful names**: `userID` not `id` + +## Docker-First Implementation Strategy + +### 1. Package.json Updates Only +File: `frontend/package.json` +- Add `"{package}": "{version}"` to dependencies +- No npm install needed - handled by container rebuild +- Testing: `make rebuild` then verify container starts + +### 2. Container-Validated Development Workflow (Production-only) +```bash +# After each change: +make rebuild # Rebuilds containers with new dependencies +make logs # Monitor for build/runtime errors +``` + +### 3. Docker-Tested Component Development (Production-only) +- All testing in containers: `make shell-frontend` for debugging +- No dev servers; production builds served by nginx +- Changes require rebuild to reflect in production containers + +## Quality Standards + +### Automated Checks Are Mandatory +**ALL hook issues are BLOCKING - EVERYTHING must be ✅ GREEN!** +- No errors. No formatting issues. No linting problems. Zero tolerance +- These are not suggestions. Fix ALL issues before continuing + +### Code Completion Criteria +Our code is complete when: +- ✅ All linters pass with zero issues +- ✅ All tests pass +- ✅ Feature works end-to-end +- ✅ Old code is deleted + +## AI Collaboration Strategy + +### Use Multiple Agents +Leverage subagents aggressively for better results: +- Spawn agents to explore different parts of the codebase in parallel +- Use one agent to write tests while another implements features +- Delegate research tasks: "I'll have an agent investigate the database schema while I analyze the API structure" +- For complex refactors: One agent identifies changes, another implements them + +### Reality Checkpoints +**Stop and validate** at these moments: +- After implementing a complete feature +- Before starting a new major component +- When something feels wrong +- Before declaring "done" + +## Performance & Security Standards + +### Measure First +- No premature optimization +- Benchmark before claiming something is faster + +### Security Always +- Validate all inputs +- Use crypto/rand for randomness +- Prepared statements for SQL (never concatenate!) + +## AI Loading Context Strategies + +### For AI Assistants: Instant Codebase Understanding +To efficiently understand and maintain this codebase, follow this exact sequence: + +#### 1. Load Core Context (Required - 2 minutes) +``` +Read these files in order: +1. AI_PROJECT_GUIDE.md - Complete project overview and architecture +2. .ai/context.json - Loading strategies and feature metadata +3. docs/README.md - Documentation navigation hub +``` + +#### 2. For Specific Tasks + +**Working on Application Features** +- Load entire feature directory: `backend/src/features/[feature-name]/` +- Start with README.md for complete API and business rules +- Everything needed is in this single directory +- Remember: Features are modules within a single application service, not independent microservices + +**Working on Platform Services** +- Load `docs/PLATFORM-SERVICES.md` for complete service architecture +- Hierarchical vehicle API patterns +- Service-to-service communication +- Platform service deployment and operations + +**Cross-Service Work** +- Load platform service docs + consuming feature documentation + +**Database Work** +- Application DB: Load `docs/DATABASE-SCHEMA.md` for app schema +- Platform Services: Load `docs/PLATFORM-SERVICES.md` for service schemas + +**Testing Work** +- Load `docs/TESTING.md` for Docker-based testing workflow +- Only use docker containers for testing. Never install local tools if they do not exist already +- Frontend now uses Jest (like backend). `make test` runs backend + frontend tests +- Jest config file: `frontend/jest.config.ts` (TypeScript configuration) +- Only vehicles feature has implemented tests; other features have scaffolded test directories + +## Architecture Context for AI + +### Hybrid Platform Architecture +**MotoVaultPro uses a hybrid architecture:** MVP Platform Services are true microservices, while the application is a modular monolith containing feature capsules. Application features in `backend/src/features/[name]/` are self-contained modules within a single service that consumes platform services via HTTP APIs. + +### Key Principles for AI Understanding +- **Production-Only**: All services use production builds and configuration +- **Docker-First**: All development in containers, no local installs +- **Platform Service Independence**: Platform services are independent microservices +- **Feature Capsule Organization**: Application features are self-contained modules within a monolith +- **Hybrid Deployment**: Platform services deploy independently, application features deploy together +- **Service Boundaries**: Clear separation between platform microservices and application monolith +- **User-Scoped Data**: All application data isolated by user_id + +### Common AI Tasks +```bash +# Run all migrations (inside containers) +make migrate + +# Run all tests (backend + frontend) inside containers +make test + +# Run specific application feature tests (backend) +make shell-backend +npm test -- features/vehicles + +# Run frontend tests only (inside disposable node container) +make test-frontend + +# View logs (all services) +make logs + +# Container shell access +make shell-backend # Application service +``` + +## Never Use Emojis +Maintain professional documentation standards without emoji usage. + +## Mobile + Desktop Requirement +**ALL features MUST be implemented and tested on BOTH mobile and desktop.** This is a hard requirement that cannot be skipped. Every component, page, and feature needs responsive design and mobile-first considerations. \ No newline at end of file diff --git a/K8S-REDESIGN.md b/K8S-REDESIGN.md new file mode 100644 index 0000000..277a8da --- /dev/null +++ b/K8S-REDESIGN.md @@ -0,0 +1,655 @@ +# Docker Compose → Kubernetes Architecture Redesign + +## Overview + +This document outlines the comprehensive redesign of MotoVaultPro's Docker Compose architecture to closely replicate a Kubernetes deployment pattern. The goal is to maintain all current functionality while preparing for seamless K8s migration and improving development experience. + +## Current Architecture Analysis + +### Existing Services (13 containers) + +**MVP Platform Services (Microservices)** +- `mvp-platform-landing` - Marketing/landing page (nginx) +- `mvp-platform-tenants` - Multi-tenant management API (FastAPI) +- `mvp-platform-vehicles-api` - Vehicle data API (FastAPI) +- `mvp-platform-vehicles-etl` - Data processing pipeline (Python) +- `mvp-platform-vehicles-db` - Vehicle data storage (PostgreSQL) +- `mvp-platform-vehicles-redis` - Vehicle data cache (Redis) +- `mvp-platform-vehicles-mssql` - Monthly ETL source (SQL Server) + +**Application Services (Modular Monolith)** +- `admin-backend` - Application API with feature capsules (Node.js) +- `admin-frontend` - React SPA (nginx) +- `admin-postgres` - Application database (PostgreSQL) +- `admin-redis` - Application cache (Redis) +- `admin-minio` - Object storage (MinIO) + +**Infrastructure** +- `nginx-proxy` - Load balancer and SSL termination +- `platform-postgres` - Platform services database +- `platform-redis` - Platform services cache + +### Current Limitations + +1. **Single Network**: All services on default network +2. **Manual Routing**: nginx configuration requires manual updates +3. **Port Exposure**: Many services expose ports directly +4. **Configuration**: Environment variables scattered across services +5. **Service Discovery**: Hard-coded service names +6. **Observability**: Limited monitoring and debugging capabilities + +## Target Kubernetes-like Architecture + +### Network Segmentation + +```yaml +networks: + frontend: + driver: bridge + labels: + - "com.motovaultpro.network=frontend" + - "com.motovaultpro.purpose=public-facing" + + backend: + driver: bridge + internal: true + labels: + - "com.motovaultpro.network=backend" + - "com.motovaultpro.purpose=api-services" + + database: + driver: bridge + internal: true + labels: + - "com.motovaultpro.network=database" + - "com.motovaultpro.purpose=data-layer" + + platform: + driver: bridge + internal: true + labels: + - "com.motovaultpro.network=platform" + - "com.motovaultpro.purpose=microservices" +``` + +### Service Placement Strategy + +| Network | Services | Purpose | K8s Equivalent | +|---------|----------|---------|----------------| +| `frontend` | traefik, admin-frontend, mvp-platform-landing | Public-facing services | Public LoadBalancer services | +| `backend` | admin-backend, mvp-platform-tenants, mvp-platform-vehicles-api | API services | ClusterIP services | +| `database` | All PostgreSQL, Redis, MinIO | Data persistence | StatefulSets with PVCs | +| `platform` | Platform microservices communication | Internal service mesh | Service mesh networking | + +## Traefik Configuration + +### Core Traefik Setup + +```yaml +traefik: + image: traefik:v3.0 + container_name: traefik + networks: + - frontend + - backend + ports: + - "80:80" + - "443:443" + - "8080:8080" # Dashboard + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./config/traefik:/config:ro + - ./certs:/certs:ro + configs: + - source: traefik-config + target: /etc/traefik/traefik.yml + labels: + - "traefik.enable=true" + - "traefik.http.routers.dashboard.rule=Host(`traefik.motovaultpro.local`)" + - "traefik.http.routers.dashboard.tls=true" +``` + +### Service Discovery Labels + +**Admin Frontend** +```yaml +admin-frontend: + labels: + - "traefik.enable=true" + - "traefik.http.routers.admin-app.rule=Host(`admin.motovaultpro.com`)" + - "traefik.http.routers.admin-app.tls=true" + - "traefik.http.routers.admin-app.middlewares=secure-headers@file" + - "traefik.http.services.admin-app.loadbalancer.server.port=3000" + - "traefik.http.services.admin-app.loadbalancer.healthcheck.path=/" +``` + +**Admin Backend** +```yaml +admin-backend: + labels: + - "traefik.enable=true" + - "traefik.http.routers.admin-api.rule=Host(`admin.motovaultpro.com`) && PathPrefix(`/api`)" + - "traefik.http.routers.admin-api.tls=true" + - "traefik.http.routers.admin-api.middlewares=api-auth@file,cors@file" + - "traefik.http.services.admin-api.loadbalancer.server.port=3001" + - "traefik.http.services.admin-api.loadbalancer.healthcheck.path=/health" +``` + +**Platform Landing** +```yaml +mvp-platform-landing: + labels: + - "traefik.enable=true" + - "traefik.http.routers.landing.rule=Host(`motovaultpro.com`)" + - "traefik.http.routers.landing.tls=true" + - "traefik.http.routers.landing.middlewares=secure-headers@file" + - "traefik.http.services.landing.loadbalancer.server.port=3000" +``` + +### Middleware Configuration + +```yaml +# config/traefik/middleware.yml +http: + middlewares: + secure-headers: + headers: + accessControlAllowMethods: + - GET + - OPTIONS + - PUT + - POST + - DELETE + accessControlAllowOriginList: + - "https://admin.motovaultpro.com" + - "https://motovaultpro.com" + accessControlMaxAge: 100 + addVaryHeader: true + browserXssFilter: true + contentTypeNosniff: true + forceSTSHeader: true + frameDeny: true + stsIncludeSubdomains: true + stsPreload: true + stsSeconds: 31536000 + + cors: + headers: + accessControlAllowCredentials: true + accessControlAllowHeaders: + - "Authorization" + - "Content-Type" + - "X-Requested-With" + accessControlAllowMethods: + - "GET" + - "POST" + - "PUT" + - "DELETE" + - "OPTIONS" + accessControlAllowOriginList: + - "https://admin.motovaultpro.com" + - "https://motovaultpro.com" + accessControlMaxAge: 100 + + api-auth: + forwardAuth: + address: "http://admin-backend:3001/auth/verify" + authResponseHeaders: + - "X-Auth-User" + - "X-Auth-Roles" +``` + +## Enhanced Health Checks + +### Standardized Health Check Pattern + +All services will implement: + +1. **Startup Probe** - Service initialization +2. **Readiness Probe** - Service ready to accept traffic +3. **Liveness Probe** - Service health monitoring + +```yaml +# Example: admin-backend +healthcheck: + test: ["CMD", "node", "-e", " + const http = require('http'); + const options = { + hostname: 'localhost', + port: 3001, + path: '/health/ready', + timeout: 2000 + }; + const req = http.request(options, (res) => { + process.exit(res.statusCode === 200 ? 0 : 1); + }); + req.on('error', () => process.exit(1)); + req.end(); + "] + interval: 15s + timeout: 5s + retries: 3 + start_period: 45s +``` + +### Health Endpoint Standards + +All services must expose: +- `/health` - Basic health check +- `/health/ready` - Readiness probe +- `/health/live` - Liveness probe + +## Configuration Management + +### Docker Configs (K8s ConfigMaps equivalent) + +```yaml +configs: + traefik-config: + file: ./config/traefik/traefik.yml + traefik-middleware: + file: ./config/traefik/middleware.yml + app-config-production: + file: ./config/app/production.yml + platform-config: + file: ./config/platform/services.yml +``` + +### Docker Secrets (K8s Secrets equivalent) + +```yaml +secrets: + auth0-client-secret: + file: ./secrets/auth0-client-secret.txt + database-passwords: + file: ./secrets/database-passwords.txt + platform-api-keys: + file: ./secrets/platform-api-keys.txt + ssl-certificates: + file: ./secrets/ssl-certs.txt +``` + +### Environment Configuration + +```yaml +# config/app/production.yml +database: + host: admin-postgres + port: 5432 + name: motovaultpro + pool_size: 20 + +redis: + host: admin-redis + port: 6379 + db: 0 + +auth0: + domain: ${AUTH0_DOMAIN} + audience: ${AUTH0_AUDIENCE} + +platform: + vehicles_api: + url: http://mvp-platform-vehicles-api:8000 + timeout: 30s + tenants_api: + url: http://mvp-platform-tenants:8000 + timeout: 15s +``` + +## Resource Management + +### Resource Allocation Strategy + +**Tier 1: Critical Services** +```yaml +deploy: + resources: + limits: { memory: 2G, cpus: '2.0' } + reservations: { memory: 1G, cpus: '1.0' } + restart_policy: + condition: on-failure + max_attempts: 3 +``` + +**Tier 2: Supporting Services** +```yaml +deploy: + resources: + limits: { memory: 1G, cpus: '1.0' } + reservations: { memory: 512M, cpus: '0.5' } + restart_policy: + condition: on-failure + max_attempts: 3 +``` + +**Tier 3: Infrastructure Services** +```yaml +deploy: + resources: + limits: { memory: 512M, cpus: '0.5' } + reservations: { memory: 256M, cpus: '0.25' } + restart_policy: + condition: unless-stopped +``` + +### Service Tiers + +| Tier | Services | Resource Profile | Priority | +|------|----------|------------------|----------| +| 1 | admin-backend, mvp-platform-vehicles-api, admin-postgres | High | Critical | +| 2 | admin-frontend, mvp-platform-tenants, mvp-platform-landing | Medium | Important | +| 3 | traefik, redis services, etl services | Low | Supporting | + +## Migration Implementation Plan + +### Phase 1: Infrastructure Foundation (Week 1) + +**Objectives:** +- Implement Traefik service +- Create network segmentation +- Establish basic routing + +**Tasks:** +1. Create new network topology +2. Add Traefik service with basic configuration +3. Migrate nginx routing to Traefik labels +4. Test SSL certificate handling +5. Verify all existing functionality + +**Success Criteria:** +- All services accessible via original URLs +- SSL certificates working +- Health checks functional +- No performance degradation + +### Phase 2: Service Discovery & Labels (Week 2) + +**Objectives:** +- Convert all services to label-based discovery +- Implement middleware for security +- Add service health monitoring + +**Tasks:** +1. Convert each service to Traefik labels +2. Implement security middleware +3. Add CORS and authentication middleware +4. Test service discovery and failover +5. Implement Traefik dashboard access + +**Success Criteria:** +- All services discovered automatically +- Security middleware working +- Dashboard accessible and functional +- Mobile and desktop testing passes + +### Phase 3: Configuration Management (Week 3) + +**Objectives:** +- Implement Docker configs and secrets +- Standardize environment configuration +- Add monitoring and observability + +**Tasks:** +1. Move configuration to Docker configs +2. Implement secrets management +3. Standardize health check endpoints +4. Add service metrics collection +5. Implement log aggregation + +**Success Criteria:** +- No hardcoded secrets in compose files +- Centralized configuration management +- Enhanced monitoring capabilities +- Improved debugging experience + +### Phase 4: Optimization & Documentation (Week 4) + +**Objectives:** +- Optimize resource allocation +- Update development workflow +- Complete documentation + +**Tasks:** +1. Implement resource limits and reservations +2. Update Makefile with new commands +3. Create troubleshooting documentation +4. Performance testing and optimization +5. Final validation of all features + +**Success Criteria:** +- Optimized resource usage +- Updated development workflow +- Complete documentation +- All tests passing + +## Development Workflow Enhancements + +### New Makefile Commands + +```makefile +# Traefik specific commands +traefik-dashboard: + @echo "Opening Traefik dashboard..." + @open https://traefik.motovaultpro.local:8080 + +traefik-logs: + @docker compose logs -f traefik + +service-discovery: + @echo "Discovered services:" + @docker compose exec traefik traefik api --url=http://localhost:8080/api/rawdata + +network-inspect: + @echo "Network topology:" + @docker network ls --filter name=motovaultpro + @docker network inspect motovaultpro_frontend motovaultpro_backend motovaultpro_database motovaultpro_platform + +health-check-all: + @echo "Checking health of all services..." + @docker compose ps --format "table {{.Service}}\t{{.Status}}\t{{.Health}}" + +# Enhanced existing commands +logs: + @echo "Available log targets: all, traefik, backend, frontend, platform" + @docker compose logs -f $(filter-out $@,$(MAKECMDGOALS)) + +%: + @: # This catches the log target argument +``` + +### Enhanced Development Features + +**Service Discovery Dashboard** +- Real-time service status +- Route configuration visualization +- Health check monitoring +- Request tracing + +**Debugging Tools** +- Network topology inspection +- Service dependency mapping +- Configuration validation +- Performance metrics + +**Testing Enhancements** +- Automated health checks +- Service integration testing +- Load balancing validation +- SSL certificate verification + +## Observability & Monitoring + +### Metrics Collection + +```yaml +# Add to traefik configuration +metrics: + prometheus: + addEntryPointsLabels: true + addServicesLabels: true + addRoutersLabels: true +``` + +### Logging Strategy + +**Centralized Logging** +- All services log to stdout/stderr +- Traefik access logs +- Service health check logs +- Application performance logs + +**Log Levels** +- `ERROR`: Critical issues requiring attention +- `WARN`: Potential issues or degraded performance +- `INFO`: Normal operational messages +- `DEBUG`: Detailed diagnostic information (dev only) + +### Health Monitoring + +**Service Health Dashboard** +- Real-time service status +- Historical health trends +- Alert notifications +- Performance metrics + +## Security Enhancements + +### Network Security + +**Network Isolation** +- Frontend network: Public-facing services only +- Backend network: API services with restricted access +- Database network: Data services with no external access +- Platform network: Microservices internal communication + +**Access Control** +- Traefik middleware for authentication +- Service-to-service authentication +- Network-level access restrictions +- SSL/TLS encryption for all traffic + +### Secret Management + +**Secrets Rotation** +- Database passwords +- API keys +- SSL certificates +- Auth0 client secrets + +**Access Policies** +- Least privilege principle +- Service-specific secret access +- Audit logging for secret access +- Encrypted secret storage + +## Testing Strategy + +### Automated Testing + +**Integration Tests** +- Service discovery validation +- Health check verification +- SSL certificate testing +- Load balancing functionality + +**Performance Tests** +- Service response times +- Network latency measurement +- Resource utilization monitoring +- Concurrent user simulation + +**Security Tests** +- Network isolation verification +- Authentication middleware testing +- SSL/TLS configuration validation +- Secret management verification + +### Manual Testing Procedures + +**Development Workflow** +1. Service startup validation +2. Route accessibility testing +3. Mobile/desktop compatibility +4. Feature functionality verification +5. Performance benchmarking + +**Deployment Validation** +1. Service discovery verification +2. Health check validation +3. SSL certificate functionality +4. Load balancing behavior +5. Failover testing + +## Migration Rollback Plan + +### Rollback Triggers + +- Service discovery failures +- Performance degradation > 20% +- SSL certificate issues +- Health check failures +- Mobile/desktop compatibility issues + +### Rollback Procedure + +1. **Immediate**: Switch DNS to backup nginx configuration +2. **Quick**: Restore docker-compose.yml.backup +3. **Complete**: Revert all configuration changes +4. **Verify**: Run full test suite +5. **Monitor**: Ensure service stability + +### Backup Strategy + +- Backup current docker-compose.yml +- Backup nginx configuration +- Export service configurations +- Document current network topology +- Save working environment variables + +## Success Metrics + +### Performance Metrics + +- **Service Startup Time**: < 30 seconds for all services +- **Request Response Time**: < 500ms for API calls +- **Health Check Response**: < 2 seconds +- **SSL Handshake Time**: < 1 second + +### Reliability Metrics + +- **Service Availability**: 99.9% uptime +- **Health Check Success Rate**: > 98% +- **Service Discovery Accuracy**: 100% +- **Failover Time**: < 10 seconds + +### Development Experience Metrics + +- **Development Setup Time**: < 5 minutes +- **Service Debug Time**: < 2 minutes to identify issues +- **Configuration Change Deployment**: < 1 minute +- **Test Suite Execution**: < 10 minutes + +## Post-Migration Benefits + +### Immediate Benefits + +1. **Enhanced Observability**: Real-time service monitoring and debugging +2. **Improved Security**: Network segmentation and middleware protection +3. **Better Development Experience**: Automatic service discovery and routing +4. **Simplified Configuration**: Centralized configuration management +5. **K8s Preparation**: Architecture closely mirrors Kubernetes patterns + +### Long-term Benefits + +1. **Easier K8s Migration**: Direct translation to Kubernetes manifests +2. **Better Scalability**: Load balancing and resource management +3. **Improved Maintainability**: Standardized configuration patterns +4. **Enhanced Monitoring**: Built-in metrics and health monitoring +5. **Professional Development Environment**: Production-like local setup + +## Conclusion + +This comprehensive redesign transforms the Docker Compose architecture to closely mirror Kubernetes deployment patterns while maintaining all existing functionality and improving the development experience. The phased migration approach ensures minimal disruption while delivering immediate benefits in observability, security, and maintainability. + +The new architecture provides a solid foundation for future Kubernetes migration while enhancing current development workflows with modern service discovery, monitoring, and configuration management practices. \ No newline at end of file diff --git a/frontend/src/core/hooks/useDataSync.ts b/frontend/src/core/hooks/useDataSync.ts index a96b091..51fa283 100644 --- a/frontend/src/core/hooks/useDataSync.ts +++ b/frontend/src/core/hooks/useDataSync.ts @@ -4,27 +4,30 @@ import { useEffect, useRef } from 'react'; import { useQueryClient } from '@tanstack/react-query'; +import { useAuth0 } from '@auth0/auth0-react'; import { DataSyncManager } from '../sync/data-sync'; import { useNavigationStore } from '../store/navigation'; export const useDataSync = () => { const queryClient = useQueryClient(); + const { isAuthenticated } = useAuth0(); const syncManagerRef = useRef(null); const navigationStore = useNavigationStore(); useEffect(() => { - // Initialize data sync manager + // Initialize data sync manager with authentication guard syncManagerRef.current = new DataSyncManager(queryClient, { enableCrossTabs: true, enableOptimisticUpdates: true, enableBackgroundSync: true, syncInterval: 30000, + isAuthenticated: () => isAuthenticated, }); return () => { syncManagerRef.current?.cleanup(); }; - }, [queryClient]); + }, [queryClient, isAuthenticated]); // Listen for navigation changes and trigger prefetching useEffect(() => { diff --git a/frontend/src/core/sync/data-sync.ts b/frontend/src/core/sync/data-sync.ts index 8fd8020..8ddb373 100644 --- a/frontend/src/core/sync/data-sync.ts +++ b/frontend/src/core/sync/data-sync.ts @@ -6,12 +6,14 @@ import { QueryClient } from '@tanstack/react-query'; import { useNavigationStore } from '../store/navigation'; import { useUserStore } from '../store/user'; import { Vehicle } from '../../features/vehicles/types/vehicles.types'; +import { apiClient } from '../api/client'; interface SyncConfig { enableCrossTabs: boolean; enableOptimisticUpdates: boolean; enableBackgroundSync: boolean; syncInterval: number; + isAuthenticated?: () => boolean; } export class DataSyncManager { @@ -119,6 +121,11 @@ export class DataSyncManager { } private async performBackgroundSync() { + // Guard: only sync if user is authenticated + if (this.config.isAuthenticated && !this.config.isAuthenticated()) { + return; + } + try { // Update last sync timestamp useUserStore.getState().updateLastSync(); @@ -147,28 +154,14 @@ export class DataSyncManager { // Helper method to fetch vehicle by ID (would normally import from vehicles API) private async fetchVehicleById(id: string): Promise { try { - const response = await fetch(`/api/vehicles/${id}`, { - headers: { - 'Authorization': this.getAuthHeader(), - }, - }); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}`); - } - - return await response.json(); + const response = await apiClient.get(`/vehicles/${id}`); + return response.data; } catch (error) { console.warn(`Failed to fetch vehicle ${id}:`, error); return null; } } - private getAuthHeader(): string { - // This would integrate with Auth0 token from interceptor - // For now, return empty string as token is handled by axios interceptor - return ''; - } // Public methods for optimistic updates public async optimisticVehicleUpdate(vehicleId: string, updates: Partial) { @@ -196,6 +189,12 @@ export class DataSyncManager { } public async prefetchForNavigation(targetScreen: string) { + // Guard: only prefetch if user is authenticated + if (this.config.isAuthenticated && !this.config.isAuthenticated()) { + console.log('DataSync: Skipping prefetch - user not authenticated'); + return; + } + try { switch (targetScreen) { case 'Vehicles': @@ -226,17 +225,8 @@ export class DataSyncManager { private async fetchVehicles(): Promise { try { - const response = await fetch('/api/vehicles', { - headers: { - 'Authorization': this.getAuthHeader(), - }, - }); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}`); - } - - return await response.json(); + const response = await apiClient.get('/vehicles'); + return response.data; } catch (error) { console.warn('Failed to fetch vehicles:', error); return []; diff --git a/mvp-platform-services/vehicles/etl/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/__pycache__/__init__.cpython-311.pyc index 92d694b11163fae3a385b47c78565fc20cff5de4..f49671df866578860859a19b7e9ac7684a6dddfd 100644 GIT binary patch delta 19 ZcmZon3uS0RSde1U&!% delta 19 ZcmZor delta 19 Zcmca8c2SILIWI340}#kcZsc<31^_U01Lpt$ diff --git a/mvp-platform-services/vehicles/etl/__pycache__/connections.cpython-311.pyc b/mvp-platform-services/vehicles/etl/__pycache__/connections.cpython-311.pyc index f3471d348f5ba8ecf3cf12ee86a9f3e824342164..6fdae890191b852812583d0432e8f31f18a6ccb6 100644 GIT binary patch delta 19 ZcmccXcGrz-IWI340}z}@-^dlL3;;en1$+Pi delta 19 ZcmccXcGrz-IWI340}upiZ{!MA1^_xn1jzsZ diff --git a/mvp-platform-services/vehicles/etl/__pycache__/main.cpython-311.pyc b/mvp-platform-services/vehicles/etl/__pycache__/main.cpython-311.pyc index c583a898f13ed1a559fdf10cd882aef2cb176fac..2d08943fcc939001b9afbbbe8ead6440ceb22fdb 100644 GIT binary patch delta 21 bcmeBP$=JP;k!v|GFBbz4$gJAP)ffT*L2m_? delta 21 bcmeBP$=JP;k!v|GFBbz4%t_nG)ffT*LmLIs diff --git a/mvp-platform-services/vehicles/etl/__pycache__/pipeline.cpython-311.pyc b/mvp-platform-services/vehicles/etl/__pycache__/pipeline.cpython-311.pyc index 8294cf95974116e7cbbcc90cee9a3eefbfb989ed..00f91a548a68ab4ae32aecd1febd88f8c55f2c1f 100644 GIT binary patch delta 19 ZcmZoRXg1(l&dbZi00dsy8@Yap0{|@u1iSzM delta 19 ZcmZoRXg1(l&dbZi00h-K8@Yap0{|@Z1g-!8 diff --git a/mvp-platform-services/vehicles/etl/__pycache__/scheduler.cpython-311.pyc b/mvp-platform-services/vehicles/etl/__pycache__/scheduler.cpython-311.pyc index 73d20b7b6cad599d9d30f98327c85c0961e4fb9b..547395171009f21fb84db94d2cd5905774886c0b 100644 GIT binary patch delta 19 ZcmZ22yIPiOIWI340}!n6+Q_w#4*)Ru1i}CS delta 19 ZcmZ22yIPiOIWI340}xoSZRA?W2LLSu1P%ZI diff --git a/mvp-platform-services/vehicles/etl/builders/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/builders/__pycache__/__init__.cpython-311.pyc index 9bc911891224314df5b3c32da2653b2d898c76e4..c5e793dca297f24ddb07edfe14ea674534532656 100644 GIT binary patch delta 19 ZcmeBT>|*3z&dbZi00c=6>n3v70{|zZ1Xut7 delta 19 ZcmeBT>|*3z&dbZi00h~8)=uQE2LLO91snhX diff --git a/mvp-platform-services/vehicles/etl/builders/__pycache__/normalized_vehicle_builder.cpython-311.pyc b/mvp-platform-services/vehicles/etl/builders/__pycache__/normalized_vehicle_builder.cpython-311.pyc index ef85fa6afa388960e702df8455af3528a15a6bef..3ef112f41575aa52a63b9d12b59cf9c5dcceea3b 100644 GIT binary patch delta 21 bcmccL#dyDqk!v|GFBbz4#8qzO3UvhlN$>^M delta 21 bcmccL#dyDqk!v|GFBbz4Jh$1%73vBAOZ5gK diff --git a/mvp-platform-services/vehicles/etl/downloaders/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/downloaders/__pycache__/__init__.cpython-311.pyc index 194faf341b1cc5f82ce9f65485a683ccd6617fac..9ec1273b0cafb2f0c188416955f75d666fc33aab 100644 GIT binary patch delta 18 XcmeBW>}BLy&dbZi00b_66S}BLy&dbZi00cQ46S|x|y&dbZi00c=6>n3tH0strN1YQ6D delta 19 ZcmeBS>|x|y&dbZi00h~8)=uPZ1OO|`1tI_d diff --git a/mvp-platform-services/vehicles/etl/extractors/__pycache__/json_extractor.cpython-311.pyc b/mvp-platform-services/vehicles/etl/extractors/__pycache__/json_extractor.cpython-311.pyc index 6f49d06a3e2fb4122599cf17b0bfabfccb687769..cd7bdbdc7205d66367fa8badc60f86520ed91eda 100644 GIT binary patch delta 21 bcmZo_VQOk&;#$tj%f$c$6@?qQel!9AJpcv+ delta 21 bcmZo_VQOk&;#$tj%f$c$D~&dC{b&RLJnIGZ diff --git a/mvp-platform-services/vehicles/etl/extractors/__pycache__/mssql_extractor.cpython-311.pyc b/mvp-platform-services/vehicles/etl/extractors/__pycache__/mssql_extractor.cpython-311.pyc index 7084e7a55dbfd4d2da26f5240cbd7b534357b3f4..4d2bc8a77f61af0635132da70401c3fdbb43c261 100644 GIT binary patch delta 21 bcmey`$N066k!v|GFBbz4ggx8HmF*4yPyGgm delta 21 bcmey`$N066k!v|GFBbz4yj!u6E886aQdb7y diff --git a/mvp-platform-services/vehicles/etl/extractors/__pycache__/vin_proc_extractor.cpython-311.pyc b/mvp-platform-services/vehicles/etl/extractors/__pycache__/vin_proc_extractor.cpython-311.pyc index 87dc996c0a1fc67e4ac8120ffaf5d955c0d59a9f..c7b6ddf39271e335a6819b29b3d577c8f6781f7b 100644 GIT binary patch delta 19 ZcmX@1bwZ14IWI340}v#6ZRD~O1pqW-1atrZ delta 19 ZcmX@1bwZ14IWI340}vGPZsf8P1pqUW1V;b> diff --git a/mvp-platform-services/vehicles/etl/loaders/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/loaders/__pycache__/__init__.cpython-311.pyc index 38273719a5ebfc11cdfaf5cb921e63e1d7c61e84..b9791142c9ad41dec0869025e61e3dd80ce12458 100644 GIT binary patch delta 18 XcmeBV>}2Fx&dbZi00dQj6S?XEBH9DY delta 18 YcmeBV>}2Fx&dbZi00fITCUVsS03wP5t^fc4 diff --git a/mvp-platform-services/vehicles/etl/loaders/__pycache__/json_manual_loader.cpython-311.pyc b/mvp-platform-services/vehicles/etl/loaders/__pycache__/json_manual_loader.cpython-311.pyc index 7fa697edf65a1a997b810a5258f22afd4aff6c25..96cecb84939ad86c105caa00d7c78856115dc235 100644 GIT binary patch delta 21 bcmZo^VQOh%;#$tj%f$c$f3|Pr`qc;kLC6Nv delta 21 bcmZo^VQOh%;#$tj%f$c$UrIJ|{b~dNKuHFO diff --git a/mvp-platform-services/vehicles/etl/loaders/__pycache__/mssql_loader.cpython-311.pyc b/mvp-platform-services/vehicles/etl/loaders/__pycache__/mssql_loader.cpython-311.pyc index 41f67cf2c7ff7b629e60fac58dc6748bc2df74a5..dc7c91a48f8ae50002a266c9e45d938319f1669b 100644 GIT binary patch delta 21 bcmca}knzqzMy}<&yj%=G@TX)W*QEpiRvrg$ delta 21 bcmca}knzqzMy}<&yj%=GFvWZ$*QEpiQhf%> diff --git a/mvp-platform-services/vehicles/etl/loaders/__pycache__/postgres_loader.cpython-311.pyc b/mvp-platform-services/vehicles/etl/loaders/__pycache__/postgres_loader.cpython-311.pyc index e13f4c434bfc99608a05a664af32ab7e2d3b53f0..8da7eb76a49a10411e55c58fcfd38b1d46a47445 100644 GIT binary patch delta 21 bcmey;&-kUEk!v|GFBbz4lx1(^dgTrPPf`Y} delta 21 bcmey;&-kUEk!v|GFBbz4OxNAW^~xOpPT~fR diff --git a/mvp-platform-services/vehicles/etl/pipelines/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/pipelines/__pycache__/__init__.cpython-311.pyc index 4b30de3327d338c3807189e277b4c0b8ab778664..a6758ebbedf63d6a2d4b1865b60a73a73d07bfde 100644 GIT binary patch delta 18 YcmeBX>}KRz&dbZi00cW$PULC?042f%YXATM delta 18 XcmeBX>}KRz&dbZi00bGy6S*1zBN_wM diff --git a/mvp-platform-services/vehicles/etl/pipelines/__pycache__/manual_json_pipeline.cpython-311.pyc b/mvp-platform-services/vehicles/etl/pipelines/__pycache__/manual_json_pipeline.cpython-311.pyc index 1c69bb17c7f851b4ede7f27789a4f5726ec6bd78..1d840cb290fa6819eafcfadcc96794a758cbf9e1 100644 GIT binary patch delta 21 bcmZ3wk8$ZfMy}<&yj%=GAhT*CmvlS;N38{! delta 21 bcmZ3wk8$ZfMy}<&yj%=Ga5i}(mvlS;N^k}P diff --git a/mvp-platform-services/vehicles/etl/utils/__pycache__/__init__.cpython-311.pyc b/mvp-platform-services/vehicles/etl/utils/__pycache__/__init__.cpython-311.pyc index 12e49fd9ec3b0cbd7d0d5e44893e12fe9a840616..8f4d673fdfc7d428d7daf37240383adc70e30be7 100644 GIT binary patch delta 18 Ycmcb^c!!Z|IWI340}vQJo5*zu052;A6#xJL delta 18 Ycmcb^c!!Z|IWI340}v!FpU8Cy052Z}1^@s6 diff --git a/mvp-platform-services/vehicles/etl/utils/__pycache__/engine_spec_parser.cpython-311.pyc b/mvp-platform-services/vehicles/etl/utils/__pycache__/engine_spec_parser.cpython-311.pyc index 9e5e0a7cb5680ebf02505f78bf93323115e8db3d..c95e4662386906c2af0592a9ee41bad46403638e 100644 GIT binary patch delta 19 Zcmexb_qC2|IWI340}yP;-N=<~4**E!20j1) delta 19 Zcmexb_qC2|IWI340}v#rZ{*6h2LMH=1*iZ3 diff --git a/mvp-platform-services/vehicles/etl/utils/__pycache__/logging.cpython-311.pyc b/mvp-platform-services/vehicles/etl/utils/__pycache__/logging.cpython-311.pyc index 35d688a5b741acdeea4f520ecc2f1affdd2fb334..6fc0496c1ab272f83806ec057ebf8cfa550d1c4b 100644 GIT binary patch delta 20 acmdnWyOo!FIWI340}v!RtlP-FiVXlX=>-=6 delta 20 acmdnWyOo!FIWI340}y2YS-X*Y6&nCKiv`;N diff --git a/mvp-platform-services/vehicles/etl/utils/__pycache__/make_filter.cpython-311.pyc b/mvp-platform-services/vehicles/etl/utils/__pycache__/make_filter.cpython-311.pyc index 71fb55c014763912ba668ecaf7300bf5970c2e67..72cea53fece857149bc80db87ca93d6a603a9a99 100644 GIT binary patch delta 19 ZcmZ2yyv~?wIWI340}$BdZ{%7c2>>#l1ib(N delta 19 ZcmZ2yyv~?wIWI340}$jJY~)%Z2>>#Q1g`)9 diff --git a/mvp-platform-services/vehicles/etl/utils/__pycache__/make_name_mapper.cpython-311.pyc b/mvp-platform-services/vehicles/etl/utils/__pycache__/make_name_mapper.cpython-311.pyc index e99949ee1018905d812030ecebdd5e41ac470e54..6c6c9cda32ccded501138dbec0612c05beef0594 100644 GIT binary patch delta 19 ZcmZ2cyrP(EIWI340}#|DZ{(V12>?5u1%Chl delta 19 ZcmZ2cyrP(EIWI340}!aIZseM02>>`=1nK|)