CIA/e-voting-system/.claude/INTEGRATION_SETUP.md
E-Voting Developer 3efdabdbbd fix: Implement vote check endpoint in frontend API proxy
- Created `/frontend/app/api/votes/check/route.ts` to handle GET requests for checking if a user has voted in a specific election.
- Added error handling for unauthorized access and missing election ID.
- Forwarded requests to the backend API and returned appropriate responses.
- Updated `/frontend/app/api/votes/history/route.ts` to fetch user's voting history with error handling.
- Ensured both endpoints utilize the authorization token for secure access.
2025-11-10 02:56:47 +01:00

10 KiB

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)
# Install Poetry
curl -sSL https://install.python-poetry.org | python3 -

# Install Python dependencies
cd /home/sorti/projects/CIA/e-voting-system
poetry install
  1. Node.js Environment (Frontend)
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)

# Set environment variable to use SQLite
export DB_URL="sqlite:///./evoting.db"

Option 2: Using MySQL (Production-like)

# 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

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

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

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"
}
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"
}
GET /api/auth/profile
Authorization: Bearer <token>

Response 200:
{
  "id": 1,
  "email": "user@example.com",
  "first_name": "Jean",
  "last_name": "Dupont",
  "created_at": "2025-11-06T12:00:00Z"
}

Elections

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

POST /api/votes
Authorization: Bearer <token>
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 <token>

Response 200:
{
  "has_voted": false
}

GET /api/votes/history
Authorization: Bearer <token>

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

# 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)

# 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)

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