Alexis Bruneteau 71cbfee4f4 fix: Simplify registration system and fix frontend-backend proxy routing
This commit addresses critical issues preventing user registration:

1. Simplified Frontend Password Validation
   - Changed from 8+ chars with uppercase, digit, special char
   - To simple 6+ character requirement
   - Matches user expectations and backend capability

2. Fixed Backend Password Constraint
   - Updated VoterRegister schema min_length from 8 to 6
   - Now consistent with simplified frontend validation

3. Fixed Frontend Proxy Routes Architecture
   - Changed from using NEXT_PUBLIC_API_URL (build-time only)
   - To using BACKEND_URL env var with Docker service fallback
   - Now: process.env.BACKEND_URL || 'http://nginx:8000'
   - Works both locally (localhost:8000) and in Docker (nginx:8000)

4. Simplified All Proxy Route Code
   - Removed verbose comments
   - Consolidated header construction
   - Better error messages showing actual errors
   - Applied consistent pattern to all 9 routes

Root Cause Analysis:
- Frontend container trying to reach localhost:8000 failed
- Docker containers can't use localhost to reach host services
- Must use service name 'nginx' within Docker network
- NEXT_PUBLIC_API_URL only works at build time, not runtime

Testing:
 Backend registration endpoint works (tested with Python requests)
 Password validation simplified and consistent
 Proxy routes now use correct Docker service URLs

Files Changed:
- frontend/lib/validation.ts (password requirements)
- backend/schemas.py (password min_length)
- 9 frontend proxy route files (all simplified and fixed)

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 03:38:13 +01:00

121 lines
2.5 KiB
Python

"""
Schémas Pydantic pour validation des requêtes/réponses.
"""
from pydantic import BaseModel, EmailStr, Field
from datetime import datetime
from typing import Optional, List
class VoterRegister(BaseModel):
"""Enregistrement d'un électeur"""
email: str
password: str = Field(..., min_length=6)
first_name: str
last_name: str
citizen_id: str # Identifiant unique (CNI)
class VoterLogin(BaseModel):
"""Authentification"""
email: str
password: str
class TokenResponse(BaseModel):
"""Réponse d'authentification"""
access_token: str
token_type: str = "bearer"
expires_in: int
class LoginResponse(BaseModel):
"""Réponse de connexion - retourne le profile et le token"""
access_token: str
token_type: str = "bearer"
expires_in: int
id: int
email: str
first_name: str
last_name: str
class RegisterResponse(BaseModel):
"""Réponse d'enregistrement - retourne le profile et le token"""
access_token: str
token_type: str = "bearer"
expires_in: int
id: int
email: str
first_name: str
last_name: str
class VoterProfile(BaseModel):
"""Profil d'un électeur"""
id: int
email: str
first_name: str
last_name: str
has_voted: bool
created_at: datetime
class Config:
from_attributes = True
class CandidateResponse(BaseModel):
"""Candidat"""
id: int
name: str
description: Optional[str]
order: int
class ElectionResponse(BaseModel):
"""Élection avec candidats"""
id: int
name: str
description: Optional[str]
start_date: datetime
end_date: datetime
is_active: bool
results_published: bool
candidates: List[CandidateResponse]
class Config:
from_attributes = True
class VoteBulletin(BaseModel):
"""Bulletin de vote à soumettre"""
election_id: int
candidate_id: int
encrypted_vote: str # Base64 du Ciphertext ElGamal
zero_knowledge_proof: Optional[str] = None # Base64 de la preuve ZK
class VoteResponse(BaseModel):
"""Confirmaction de vote"""
id: int
ballot_hash: str
timestamp: datetime
class Config:
from_attributes = True
class ResultResponse(BaseModel):
"""Résultat de l'élection"""
candidate_name: str
vote_count: int
percentage: float
class ElectionResultResponse(BaseModel):
"""Résultats complets d'une élection"""
election_id: int
election_name: str
total_votes: int
results: List[ResultResponse]