# E-Voting System - Backend & Frontend Integration Setup This guide explains how to run both the FastAPI backend and Next.js frontend together. ## System Requirements - Python 3.12+ - Node.js 18+ (for npm) - MySQL 8.0+ (or SQLite for development) - Poetry (for Python dependency management) ## Project Structure ``` e-voting-system/ ├── backend/ # FastAPI application │ ├── main.py # Entry point │ ├── routes/ # API endpoints (auth, elections, votes) │ ├── models.py # Database models │ ├── schemas.py # Pydantic schemas │ ├── config.py # Configuration │ └── crypto/ # Cryptography modules ├── frontend/ # Next.js application │ ├── app/ # Application pages │ ├── components/ # React components │ ├── lib/ # Utilities (API client, auth context) │ └── package.json # npm dependencies └── pyproject.toml # Python dependencies ``` ## Quick Start (Both Services) ### Prerequisites Setup 1. **Python Environment (Backend)** ```bash # Install Poetry curl -sSL https://install.python-poetry.org | python3 - # Install Python dependencies cd /home/sorti/projects/CIA/e-voting-system poetry install ``` 2. **Node.js Environment (Frontend)** ```bash cd /home/sorti/projects/CIA/e-voting-system/frontend npm install ``` ### Database Setup The backend uses MySQL by default. For development, you can use SQLite instead. **Option 1: Using SQLite (Easy for Development)** ```bash # Set environment variable to use SQLite export DB_URL="sqlite:///./evoting.db" ``` **Option 2: Using MySQL (Production-like)** ```bash # Start MySQL (if using Docker) docker run --name mysql-evoting -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=evoting_db -p 3306:3306 -d mysql:8.0 # Or connect to existing MySQL instance export DB_HOST=localhost export DB_PORT=3306 export DB_NAME=evoting_db export DB_USER=evoting_user export DB_PASSWORD=evoting_pass123 ``` ### Running Both Services **Terminal 1: Start Backend** ```bash cd /home/sorti/projects/CIA/e-voting-system # Activate Poetry shell or use poetry run poetry shell # or poetry run uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000 ``` Backend will be available at: `http://localhost:8000` - Swagger UI: `http://localhost:8000/docs` - ReDoc: `http://localhost:8000/redoc` **Terminal 2: Start Frontend** ```bash cd /home/sorti/projects/CIA/e-voting-system/frontend # Create .env.local if it doesn't exist cat > .env.local << EOF NEXT_PUBLIC_API_URL=http://localhost:8000 EOF # Start development server npm run dev ``` Frontend will be available at: `http://localhost:3000` ## API Endpoints ### Authentication ```http POST /api/auth/register Content-Type: application/json { "email": "user@example.com", "password": "securepass123", "first_name": "Jean", "last_name": "Dupont" } Response 200: { "access_token": "eyJhbGc...", "expires_in": 1800, "id": 1, "email": "user@example.com", "first_name": "Jean", "last_name": "Dupont" } ``` ```http POST /api/auth/login Content-Type: application/json { "email": "user@example.com", "password": "securepass123" } Response 200: { "access_token": "eyJhbGc...", "expires_in": 1800, "id": 1, "email": "user@example.com", "first_name": "Jean", "last_name": "Dupont" } ``` ```http GET /api/auth/profile Authorization: Bearer Response 200: { "id": 1, "email": "user@example.com", "first_name": "Jean", "last_name": "Dupont", "created_at": "2025-11-06T12:00:00Z" } ``` ### Elections ```http GET /api/elections/active Response 200: [Election, ...] GET /api/elections/upcoming Response 200: [Election, ...] GET /api/elections/completed Response 200: [Election, ...] GET /api/elections/{id} Response 200: Election GET /api/elections/{id}/candidates Response 200: [Candidate, ...] GET /api/elections/{id}/results Response 200: ElectionResultResponse ``` ### Votes ```http POST /api/votes Authorization: Bearer Content-Type: application/json { "election_id": 1, "choix": "Candidate Name" } Response 200: { "id": 1, "ballot_hash": "abc123...", "timestamp": "2025-11-06T12:00:00Z" } GET /api/votes/status?election_id=1 Authorization: Bearer Response 200: { "has_voted": false } GET /api/votes/history Authorization: Bearer Response 200: [VoteHistory, ...] ``` ## Frontend Features Integrated ### Pages - ✅ **Home** (`/`) - Landing page with call-to-action - ✅ **Login** (`/auth/login`) - Authentication with backend - ✅ **Register** (`/auth/register`) - User registration - ✅ **Dashboard** (`/dashboard`) - Loads active elections from API - ✅ **Active Votes** (`/dashboard/votes/active`) - List active elections - ✅ **Upcoming Votes** (`/dashboard/votes/upcoming`) - Timeline of future elections - ✅ **Vote History** (`/dashboard/votes/history`) - Past votes - ✅ **Archives** (`/dashboard/votes/archives`) - Historical elections - ✅ **Profile** (`/dashboard/profile`) - User profile management ### Authentication Flow 1. User fills login/register form 2. Form data sent to backend (`/api/auth/login` or `/api/auth/register`) 3. Backend validates credentials and returns JWT token 4. Frontend stores token in localStorage 5. Token included in Authorization header for protected endpoints 6. Dashboard pages protected with `ProtectedRoute` component 7. Non-authenticated users redirected to login ### Protected Routes - Dashboard and all sub-pages require authentication - Automatic redirect to login if token is missing/expired - User name displayed in dashboard header - Logout clears token and redirects to home ## Testing the Integration ### Manual Testing 1. **Register a new user** - Go to `http://localhost:3000/auth/register` - Fill in email, name, and password - Submit form - Should redirect to dashboard 2. **Login** - Go to `http://localhost:3000/auth/login` - Use registered email and password - Should redirect to dashboard 3. **View Elections** - Dashboard loads active elections from backend - See real election data with candidate counts - Loading spinner shows while fetching data 4. **Logout** - Click "Déconnexion" button in dashboard sidebar - Should redirect to home page - Token removed from localStorage ### API Testing with curl ```bash # Register user curl -X POST http://localhost:8000/api/auth/register \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"testpass123","first_name":"Test","last_name":"User"}' # Login curl -X POST http://localhost:8000/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"test@example.com","password":"testpass123"}' # Get active elections (with token) curl -X GET http://localhost:8000/api/elections/active \ -H "Authorization: Bearer YOUR_TOKEN" # Get profile curl -X GET http://localhost:8000/api/auth/profile \ -H "Authorization: Bearer YOUR_TOKEN" ``` ### Testing with Frontend 1. **Check Network Tab (DevTools)** - Open browser DevTools (F12) - Go to Network tab - Try logging in - Should see POST request to `http://localhost:8000/api/auth/login` - Response includes `access_token` 2. **Check Console Tab** - No CORS errors should appear - Auth context logs should show user data 3. **Check Storage Tab** - `localStorage` should contain `auth_token` after login - Token removed after logout ## Environment Variables ### Backend (.env or export) ```bash # Database DB_HOST=localhost DB_PORT=3306 DB_NAME=evoting_db DB_USER=evoting_user DB_PASSWORD=evoting_pass123 # Security SECRET_KEY=your-secret-key-change-in-production DEBUG=false # Application APP_NAME="E-Voting System API" ``` ### Frontend (.env.local) ```bash NEXT_PUBLIC_API_URL=http://localhost:8000 ``` ## Troubleshooting ### "Connection refused" error on login - Ensure backend is running on port 8000 - Check `NEXT_PUBLIC_API_URL` in frontend `.env.local` - Verify backend is accessible: `curl http://localhost:8000/health` ### "CORS error" when logging in - CORS is already enabled in backend (`allow_origins=["*"]`) - Check browser console for specific CORS error - Verify backend CORS middleware is configured ### Token not persisted after page refresh - Check localStorage in DevTools (Storage tab) - Verify `auth_token` key is being set - Check browser privacy/incognito mode (may prevent localStorage) ### "Unauthorized" errors on protected endpoints - Token may have expired (30 minutes by default) - Re-login to get new token - Check `Authorization` header is being sent in requests ### Frontend can't find API - Ensure backend is running: `uvicorn backend.main:app --reload` - Check port: should be 8000 - Check API URL in `.env.local`: `http://localhost:8000` - Try health check: `curl http://localhost:8000/health` ## Performance Optimizations ### Frontend Optimizations - Auto-split code by routes - Tailwind CSS: ~17 kB gzipped - Shared JS bundle: ~102 kB - Individual pages: 2-4 kB each ### Backend Optimizations - Use connection pooling - Index database columns - Cache election data - Compress API responses ## Security Considerations ### Development vs Production **Development (Current)** - CORS: Allow all origins (`["*"]`) - Debug mode: enabled - Secret key: default (not secure) - HTTPS: not required **Production (Required)** - CORS: Restrict to frontend domain - Debug mode: disabled - Secret key: strong, secure, environment variable - HTTPS: required for all API calls - Token expiration: reduce from 30 to 15 minutes - Rate limiting: add to prevent abuse - Hashing: use strong algorithm (bcrypt already configured) ### Authentication Security - ✅ Passwords hashed with bcrypt - ✅ JWT tokens with expiration - ✅ Token stored in localStorage (vulnerable to XSS) - ⚠️ Consider HttpOnly cookies for production - ✅ HTTPS required in production ## Next Steps 1. **Database Population**: Create test elections and candidates 2. **Voting Interface**: Implement actual vote submission 3. **Results Display**: Show election results with charts 4. **Form Validation**: Add Zod validation to frontend forms 5. **Error Handling**: Implement error boundaries 6. **Testing**: Add unit and E2E tests 7. **Deployment**: Deploy to production environment ## Support - Backend Docs: `http://localhost:8000/docs` (Swagger) - Frontend Docs: `frontend/FRONTEND_NEXTJS_GUIDE.md` - Integration Guide: `NEXT_STEPS.md` --- **Status**: Backend and frontend integrated and ready for testing **Date**: 2025-11-06 **Branch**: UI