# Development & Architecture Guide ## Project Structure Overview ``` aws-final-project/ ├── backend/ # FastAPI Python application ├── frontend/ # React Vite SPA ├── helm/dating-app/ # Kubernetes Helm chart ├── docker-compose.yml # Local dev environment ├── README.md # Main documentation ├── DEPLOYMENT.md # Deployment instructions └── DEVELOPMENT.md # This file ``` ## Backend Architecture ### Core Components **app/db.py** - Database Connection - SimpleConnectionPool for connection management - Auto-initialization of tables on startup - Safe context manager for connections **app/config.py** - Configuration Management - Environment variable loading with defaults - Settings validation - Centralized config source **app/auth/** - Authentication - `utils.py`: Password hashing (bcrypt), JWT creation/validation - `__init__.py`: Authorization dependency for FastAPI **app/models/** - Database Models - Pure Python classes representing database entities - User, Profile, Photo, Like, Conversation, Message - to_dict() methods for serialization **app/schemas/** - Pydantic Schemas - Request/response validation - Type hints and documentation - Automatic OpenAPI schema generation **app/services/** - Business Logic - `auth_service.py`: Registration, login - `profile_service.py`: Profile CRUD, discovery - `photo_service.py`: Upload, storage, deletion - `like_service.py`: Like tracking, match detection - `chat_service.py`: Message operations, conversations **app/routers/** - API Endpoints - Modular organization by feature - Protected endpoints with `get_current_user` dependency - Consistent error handling ### Database Design #### users table ```sql id (PK), email (UNIQUE), hashed_password, created_at, updated_at ``` #### profiles table ```sql id (PK), user_id (FK UNIQUE), display_name, age, gender, location, bio, interests (JSONB), created_at, updated_at ``` #### photos table ```sql id (PK), profile_id (FK), file_path, display_order, created_at ``` #### likes table ```sql id (PK), liker_id (FK), liked_id (FK), created_at UNIQUE(liker_id, liked_id) ``` #### conversations table ```sql id (PK), user_id_1 (FK), user_id_2 (FK), created_at, updated_at UNIQUE(user_id_1, user_id_2) ``` #### messages table ```sql id (PK), conversation_id (FK), sender_id (FK), content, created_at ``` ### Key Design Decisions 1. **Synchronous psycopg2** - Per requirements, enables simpler debugging 2. **Connection Pooling** - SimpleConnectionPool provides basic pooling 3. **Auto-initialization** - Tables created on startup, no separate migration step 4. **JWT Tokens** - Stateless auth, no session storage needed 5. **Local File Storage** - Disk-based for lab, easily swappable to S3 6. **Match Logic** - Dual-directional like check in database ### Adding New Features **Example: Add "message read receipts"** 1. Add schema to `app/schemas/message.py`: ```python class MessageResponse(BaseModel): # ... existing fields ... read_at: Optional[str] = None ``` 2. Update database in `app/db.py`: ```python cur.execute(""" ALTER TABLE messages ADD COLUMN read_at TIMESTAMP """) ``` 3. Add method to `app/services/chat_service.py`: ```python @staticmethod def mark_message_read(message_id: int): # Implementation ``` 4. Add endpoint to `app/routers/chat.py`: ```python @router.patch("/messages/{message_id}/read") def mark_read(message_id: int, current_user: dict = Depends(get_current_user)): # Implementation ``` ## Frontend Architecture ### Project Structure ``` frontend/src/ ├── pages/ # Full page components │ ├── Login.jsx │ ├── Register.jsx │ ├── ProfileEditor.jsx │ ├── Discover.jsx │ ├── Matches.jsx │ └── Chat.jsx ├── styles/ # CSS for each page │ ├── auth.css │ ├── profileEditor.css │ ├── discover.css │ ├── matches.css │ └── chat.css ├── api.js # Centralized API client ├── App.jsx # Main app component ├── App.css # Global styles ├── main.jsx # React entry point └── index.css # Global CSS ``` ### API Client Pattern **src/api.js** provides: - Axios instance with base configuration - Request interceptor for JWT token injection - Response interceptor for 401 handling - Organized API methods by feature: - authAPI.register(), authAPI.login() - profileAPI.getMyProfile(), profileAPI.discoverProfiles() - etc. **Usage in components:** ```javascript import { profileAPI } from '../api' const response = await profileAPI.getMyProfile() const profiles = await profileAPI.discoverProfiles() ``` ### State Management **Simple localStorage approach:** - JWT stored in localStorage, auto-attached to requests - User ID stored for context - Component-level state with useState for forms - No Redux/MobX needed for MVP **Example:** ```javascript // After login localStorage.setItem('token', response.data.access_token) localStorage.setItem('user_id', response.data.user_id) // On API calls // Automatically added by axios interceptor Authorization: `Bearer ${token}` // On logout localStorage.removeItem('token') localStorage.removeItem('user_id') ``` ### Component Patterns **Page Component Template:** ```jsx export default function FeaturePage() { const [data, setData] = useState([]) const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState('') useEffect(() => { loadData() }, []) const loadData = async () => { try { setIsLoading(true) const response = await featureAPI.getData() setData(response.data) } catch (err) { setError(err.response?.data?.detail || 'Error') } finally { setIsLoading(false) } } return (
{error &&
{error}
} {/* JSX */}
) } ``` ### Styling Approach - CSS modules for component isolation - Global styles in index.css and App.css - BEM naming convention for clarity - Mobile-responsive with flexbox/grid ### Environment Configuration Frontend uses Vite's import.meta.env: ```javascript // In src/api.js const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000' ``` In `frontend/.env`: ``` VITE_API_URL=http://localhost:8000 ``` ## Docker Build Process ### Backend Dockerfile ```dockerfile # Multi-stage not needed # Single stage with Python 3.11 # System dependencies: gcc, postgresql-client # Python dependencies: fastapi, uvicorn, etc. # Health check via /health endpoint # CMD: uvicorn main:app ``` ### Frontend Dockerfile ```dockerfile # Multi-stage: builder + runtime # Stage 1: Build with Node # - npm install # - npm run build -> dist/ # Stage 2: Runtime with nginx # - nginx:alpine # - Copy dist to /usr/share/nginx/html # - Custom nginx.conf for SPA routing # - Health check via /health endpoint ``` ### Nginx Configuration Handles: - SPA routing: try_files fallback to index.html - Static file caching: 1-year expiry for assets - Deny access to hidden files - Health check endpoint ## Kubernetes Deployment ### Helm Chart Structure **Chart.yaml** - Chart metadata **values.yaml** - Default configuration (override for different environments) **values-lab.yaml** - Home-lab specific values - Single replicas - Local storage classes - Default passwords (change in production) **values-aws.yaml** - AWS specific values - Multiple replicas - EBS storage class - ALB ingress class - RDS database URL **Templates:** - `namespace.yaml` - Creates dedicated namespace - `configmap.yaml` - Backend and frontend config - `secret.yaml` - PostgreSQL credentials - `postgres.yaml` - PostgreSQL deployment + PVC + service - `backend.yaml` - Backend deployment + service - `frontend.yaml` - Frontend deployment + service - `ingress.yaml` - Ingress for both services ### Deployment Flow 1. Helm reads values file 2. Templates rendered with values 3. Kubernetes resources created in order: - Namespace - ConfigMap, Secret - PVC - Postgres deployment waits for PVC - Backend deployment waits for postgres - Frontend deployment (no deps) - Services for each - Ingress routes traffic ### Network Architecture ``` Internet | Ingress (nginx/traefik) | +-> Frontend Service (80) -> Frontend Pods | +-> Backend Service (8000) -> Backend Pods | Postgres Service (5432) | Postgres Pod ``` ### Storage **PVC for Postgres:** - ReadWriteOnce access mode - Survives pod restarts - Data persists across deployments **PVC for Backend Media:** - ReadWriteMany access mode (for multiple replicas) - Shared media storage across pods - Migrates to S3 for cloud deployments ## Development Workflow ### Local Testing ```bash # 1. Modify code # 2. Test with compose docker-compose up -d curl http://localhost:8000/docs # 3. Modify Helm values # 4. Test with Helm (dry-run) helm install dating-app ./helm/dating-app \ -n dating-app --dry-run --debug # 5. Test with Helm (actual) helm install dating-app ./helm/dating-app \ -n dating-app --create-namespace # 6. Verify kubectl get all -n dating-app ``` ### Code Changes **Backend changes:** - Edit Python files in app/ - Changes automatically available in dev environment - Production requires rebuilding Docker image **Frontend changes:** - Edit .jsx files - Changes automatically available in dev environment - Production requires rebuilding and redeploying **Database schema changes:** - Modify app/db.py init_db() - For Alembic (future): `alembic revision --autogenerate` - Existing migrations: Update manually or recreate database ## Performance Considerations ### Backend - Connection pooling limits: Currently 1-20 connections - Query optimization: Use indexes on foreign keys - Response caching: Can add for discover endpoint - Pagination: Not implemented yet, add for large datasets ### Frontend - Image optimization: Profile pictures should be compressed - Lazy loading: Add for discover card images - Code splitting: Can split by route - Caching: Service workers for offline support ### Database - Indexes created on common query columns - JSONB for interests enables efficient queries - Unique constraints prevent duplicates - Foreign keys maintain referential integrity ## Testing Strategy ### Unit Tests (Future) ```python # backend/tests/ # test_auth.py - Auth functions # test_services.py - Service logic # test_routers.py - API endpoints ``` ### Integration Tests (Future) ```python # Full workflow testing # Database interactions # API contract validation ``` ### E2E Tests (Future) ```javascript # frontend/tests/ # User registration flow # Profile creation # Swiping and matching # Chat functionality ``` ### Manual Testing Checklist - [ ] Registration with new email - [ ] Login with correct password - [ ] Create and update profile - [ ] Upload multiple photos - [ ] Delete photos - [ ] View discover profiles - [ ] Like a user - [ ] Check matches - [ ] Send message to match - [ ] View conversation history - [ ] Logout ## Security Considerations ### Current Implementation - ✅ Password hashing with bcrypt - ✅ JWT with expiration - ✅ CORS configured - ✅ Protected endpoints - ✅ SQL injection prevention (parameterized queries) ### Recommended Additions - [ ] Rate limiting on auth endpoints - [ ] HTTPS/TLS enforcement - [ ] CSRF token for state-changing operations - [ ] Input validation and sanitization - [ ] Audit logging - [ ] API key authentication for service-to-service - [ ] Secrets management (Vault) - [ ] Regular security scanning - [ ] Penetration testing ### Data Protection - [ ] Encrypt sensitive data in transit (HTTPS) - [ ] Encrypt sensitive data at rest - [ ] Implement data retention policies - [ ] GDPR compliance (right to delete, data export) - [ ] Regular backups with encryption - [ ] Secure backup storage ## Common Issues & Solutions ### Issue: Photo uploads fail **Cause:** Media directory not writable **Solution:** Check MEDIA_DIR permissions, ensure PVC mounted ### Issue: Matches not showing **Cause:** Mutual like check query fails **Solution:** Verify both users liked each other, check database ### Issue: Slow profile discovery **Cause:** N+1 query problem **Solution:** Add query optimization, batch load photos ### Issue: Connection pool exhausted **Cause:** Too many concurrent requests **Solution:** Increase pool size, add connection timeout ## Future Enhancements 1. **WebSocket Chat** - Real-time messages without polling - Typing indicators - Read receipts 2. **Image Optimization** - Automatic compression - Multiple sizes for responsive design - CDN distribution 3. **Recommendation Engine** - Machine learning for match suggestions - Interest-based filtering - Location-based matching 4. **Advanced Features** - Video calls - Story features - Search and filtering - Blocking/reporting - Verification badges 5. **Infrastructure** - Load balancing improvements - Caching layer (Redis) - Message queue (RabbitMQ) for async tasks - Monitoring and alerting - CI/CD pipeline - Database read replicas