# ๐Ÿ“š Documentation Technique - CV Generator ## ๐ŸŽฏ Vue d'ensemble du Projet **CV Generator** est une application web moderne permettant de gรฉnรฉrer des CV professionnels au format PDF, optimisรฉs pour les systรจmes ATS (Applicant Tracking System). L'application utilise l'intelligence artificielle pour amรฉliorer le contenu du CV. --- ## ๐Ÿ—๏ธ Architecture du Projet ### Structure des Dossiers ``` CVGENERATOR/ โ”œโ”€โ”€ backend/ โ”‚ โ”œโ”€โ”€ app/ โ”‚ โ”‚ โ”œโ”€โ”€ models/ # Modรจles de donnรฉes Pydantic โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ cv_models.py โ”‚ โ”‚ โ”œโ”€โ”€ services/ # Logique mรฉtier โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ gemini_service.py โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ document_service.py โ”‚ โ”‚ โ”œโ”€โ”€ routes/ # Points d'entrรฉe API โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ cv_routes.py โ”‚ โ”‚ โ””โ”€โ”€ main.py # Configuration FastAPI โ”‚ โ”œโ”€โ”€ venv/ # Environnement virtuel Python โ”‚ โ””โ”€โ”€ requirements.txt โ”œโ”€โ”€ frontend/ โ”‚ โ”œโ”€โ”€ index.html # Interface utilisateur โ”‚ โ”œโ”€โ”€ styles.css # Styles responsive โ”‚ โ””โ”€โ”€ script.js # Logique frontend โ”œโ”€โ”€ app.py # Point d'entrรฉe Hugging Face โ”œโ”€โ”€ Dockerfile # Configuration Docker โ”œโ”€โ”€ requirements.txt # Dรฉpendances production โ””โ”€โ”€ README.md ``` --- ## ๐Ÿ”ง Principes SOLID Appliquรฉs Notre architecture respecte les 5 principes SOLID pour garantir un code maintenable et รฉvolutif. ### 1. **S** - Single Responsibility Principle (SRP) Chaque classe a une seule responsabilitรฉ : | Classe | Responsabilitรฉ Unique | |--------|----------------------| | `GeminiService` | Communication avec l'API Gemini AI | | `DocxGenerator` | Gรฉnรฉration de documents DOCX | | `PDFConverter` | Conversion DOCX vers PDF | | `CVGeneratorService` | Orchestration du processus de gรฉnรฉration | ```python class DocxGenerator(DocumentGeneratorInterface): def generate(self, cv_data: CVData, output_path: str) -> str: # Gรฉnรจre uniquement le document DOCX pass ``` ### 2. **O** - Open/Closed Principle (OCP) Les classes sont ouvertes ร  l'extension mais fermรฉes ร  la modification : ```python # Interface abstraite - peut รชtre รฉtendue sans modifier l'existant class DocumentGeneratorInterface(ABC): @abstractmethod def generate(self, cv_data: CVData, output_path: str) -> str: pass # Extension possible sans modifier l'interface class DocxGenerator(DocumentGeneratorInterface): pass class LatexGenerator(DocumentGeneratorInterface): # Futur pass ``` ### 3. **L** - Liskov Substitution Principle (LSP) Les sous-classes peuvent remplacer leurs classes parentes : ```python # N'importe quelle implรฉmentation de DocumentGeneratorInterface # peut รชtre utilisรฉe de maniรจre interchangeable def create_cv(generator: DocumentGeneratorInterface, data: CVData): return generator.generate(data, "output.docx") # Fonctionne avec DocxGenerator ou toute autre implรฉmentation create_cv(DocxGenerator(), cv_data) ``` ### 4. **I** - Interface Segregation Principle (ISP) Des interfaces spรฉcifiques plutรดt qu'une interface monolithique : ```python # Interfaces sรฉparรฉes pour chaque fonctionnalitรฉ class DocumentGeneratorInterface(ABC): @abstractmethod def generate(self, cv_data, output_path) -> str: pass class AIServiceInterface(ABC): @abstractmethod def generate_summary(self, data) -> str: pass @abstractmethod def enhance_experience(self, description) -> str: pass ``` ### 5. **D** - Dependency Inversion Principle (DIP) Les modules de haut niveau dรฉpendent d'abstractions : ```python # Le service dรฉpend d'abstractions, pas d'implรฉmentations concrรจtes class CVGeneratorService: def __init__(self, docx_generator: DocxGenerator, # Injection pdf_converter: PDFConverter): # de dรฉpendances self.docx_generator = docx_generator self.pdf_converter = pdf_converter ``` --- ## ๐Ÿ”„ Flux de Donnรฉes ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ FRONTEND โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ ร‰tape 1 โ”‚โ”€โ”€โ”€โ–ถโ”‚ ร‰tape 2 โ”‚โ”€โ”€โ”€โ–ถโ”‚ ร‰tape 3 โ”‚โ”€โ”€โ”€โ–ถโ”‚ ร‰tape 4 โ”‚ โ”‚ โ”‚ โ”‚ Infos โ”‚ โ”‚Formation โ”‚ โ”‚Expรฉrienceโ”‚ โ”‚Compรฉtencesโ”‚ โ”‚ โ”‚ โ”‚Personnelsโ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚& Langues โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ ร‰tape 5 โ”‚ โ”‚ โ”‚ โ”‚ Aperรงu & โ”‚ โ”‚ โ”‚ โ”‚ Gรฉnรฉration โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ API FASTAPI โ”‚ โ”‚ โ”‚ โ”‚ POST /api/cv/generate โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ 1. Validation des donnรฉes (Pydantic) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”‚ โ”‚ 2. Gรฉnรฉration rรฉsumรฉ IA (GeminiService) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”‚ โ”‚ 3. Crรฉation DOCX (DocxGenerator) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”‚ โ”‚ 4. Conversion PDF (PDFConverter) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”‚ โ”‚ 5. Retour URLs de tรฉlรฉchargement โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐Ÿค– Intรฉgration de l'IA (Gemini) ### Fonctionnalitรฉs IA 1. **Gรฉnรฉration automatique de rรฉsumรฉ professionnel** - Analyse des expรฉriences et compรฉtences - Crรฉation d'un profil percutant 2. **Amรฉlioration des descriptions d'expรฉrience** - Reformulation professionnelle - Ajout de verbes d'action ### Gestion des Erreurs et Fallback ```python class GeminiService: FALLBACK_MODELS = [ "gemini-2.0-flash", "gemini-1.5-flash", "gemini-1.0-pro" ] def _call_with_retry(self, prompt: str) -> str: """Essaie plusieurs modรจles en cas d'รฉchec""" for model_name in self.FALLBACK_MODELS: try: model = genai.GenerativeModel(model_name) response = model.generate_content(prompt) return response.text except Exception: continue return self._generate_fallback_summary() ``` ### Gestion des Quotas En cas de dรฉpassement de quota API, l'application gรฉnรจre automatiquement un rรฉsumรฉ basรฉ sur les donnรฉes fournies : ```python def _generate_fallback_summary(self, cv_data: CVData) -> str: """Gรฉnรจre un rรฉsumรฉ sans IA en cas de quota dรฉpassรฉ""" skills = ", ".join([s.name for s in cv_data.skills[:5]]) return f"Professionnel expรฉrimentรฉ avec des compรฉtences en {skills}..." ``` --- ## ๐Ÿ“„ Gรฉnรฉration de Documents ATS-Friendly ### Principes de Design ATS Les systรจmes ATS (Applicant Tracking System) analysent automatiquement les CV. Notre gรฉnรฉrateur respecte ces rรจgles : | โœ… Bonnes Pratiques | โŒ ร€ ร‰viter | |---------------------|-------------| | Structure linรฉaire | Colonnes multiples | | Police standard (Calibri) | Polices dรฉcoratives | | Titres en majuscules | Graphiques/Images | | Format simple | Tableaux complexes | | Texte pur | En-tรชtes/Pieds de page | ### Structure du CV Gรฉnรฉrรฉ ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ NOM COMPLET โ”‚ โ† Centrรฉ, 24pt, Gras โ”‚ โœ‰ email | โ˜Ž tรฉlรฉphone | ๐Ÿ“ ville โ”‚ โ† Infos contact โ”‚ LinkedIn | Portfolio โ”‚ โ† Liens โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ PROFIL PROFESSIONNEL โ”‚ โ† Section titre โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ† Ligne bleue โ”‚ Rรฉsumรฉ gรฉnรฉrรฉ par IA... โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ EXPร‰RIENCE PROFESSIONNELLE โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Poste | Jan 2020 - Prรฉsent โ”‚ โ† Titre + dates โ”‚ Entreprise โ”‚ โ† Italique โ”‚ โ–ธ Rรฉalisation 1 โ”‚ โ† Bullet points โ”‚ โ–ธ Rรฉalisation 2 โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ FORMATION โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Diplรดme | 2015 - 2018 โ”‚ โ”‚ ร‰cole โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ COMPร‰TENCES โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Expert: Python โ€ข JavaScript โ€ข React โ”‚ โ† Groupรฉes par niveau โ”‚ Intermรฉdiaire: Docker โ€ข AWS โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ LANGUES โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ โ–ธ Franรงais: Natif โ”‚ โ”‚ โ–ธ Anglais: Courant โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ CENTRES D'INTร‰RรŠT โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ โ”‚ Lecture โ€ข Sport โ€ข Voyages โ”‚ โ† Sur une ligne โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐ŸŽจ Design Frontend Responsive ### Breakpoints CSS ```css /* Desktop */ @media (min-width: 1200px) { ... } /* Tablette */ @media (max-width: 768px) { ... } /* Mobile */ @media (max-width: 480px) { ... } /* Trรจs petit รฉcran */ @media (max-width: 360px) { ... } ``` ### Fonctionnalitรฉs Responsive - **Formulaires adaptatifs** : Colonnes โ†’ Lignes sur mobile - **Navigation tactile** : Boutons agrandis - **Typographie fluide** : `clamp()` pour tailles de police - **Labels masquรฉs** : Sur trรจs petits รฉcrans --- ## ๐Ÿš€ Dรฉploiement ### Architecture de Dรฉploiement (Hugging Face Spaces) ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Hugging Face Spaces โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Docker Container โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ Python 3.10-slim โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ FastAPI โ”‚ โ”‚ LibreOffice โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ (app.py) โ”‚ โ”‚ (PDF Conv.) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ Frontend โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ (static) โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ Port 7860 โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ Internet ``` ### Variables d'Environnement | Variable | Description | Requis | |----------|-------------|--------| | `GEMINI_API_KEY` | Clรฉ API Google Gemini | โœ… | | `PORT` | Port du serveur (dรฉfaut: 7860) | โŒ | --- ## ๐Ÿงช Tests et Validation ### Points de Test API ```bash # Health Check curl http://localhost:8000/api/cv/health # Gรฉnรฉration de CV curl -X POST http://localhost:8000/api/cv/generate \ -H "Content-Type: application/json" \ -d '{ "personal_info": {...}, "education": [...], "experiences": [...], "skills": [...], "languages": [...] }' ``` ### Validation des Donnรฉes Toutes les donnรฉes sont validรฉes par **Pydantic** : ```python class PersonalInfo(BaseModel): full_name: str = Field(..., min_length=2, max_length=100) email: EmailStr phone: str address: str linkedin: Optional[str] = None portfolio: Optional[str] = None summary: Optional[str] = None ``` --- ## ๐Ÿ“ˆ Amรฉliorations Futures ### Roadmap - [ ] **Templates multiples** : Diffรฉrents designs de CV - [ ] **Export LaTeX** : Pour les CV acadรฉmiques - [ ] **Analyse ATS** : Score de compatibilitรฉ - [ ] **Multi-langues** : Interface en plusieurs langues - [ ] **Stockage cloud** : Sauvegarde des CV - [ ] **Authentification** : Comptes utilisateurs --- ## ๐Ÿ‘ฅ Contribution ### Standards de Code - **Python** : PEP 8, type hints - **JavaScript** : ES6+, async/await - **CSS** : BEM methodology, variables CSS - **Commits** : Conventional Commits ### Structure des Commits ``` feat: ajout de la gรฉnรฉration PDF fix: correction du bug de conversion docs: mise ร  jour de la documentation style: formatage du code refactor: restructuration du service Gemini ``` --- ## ๐Ÿ“ Licence Ce projet est dรฉveloppรฉ dans un cadre รฉducatif. --- *Documentation gรฉnรฉrรฉe le 31 dรฉcembre 2025* --- # ๐ŸŽฏ Approche Technique : Gรฉnรฉration de CV avec Template et Ajustement Automatique ## ๐Ÿ“‹ Vue d'ensemble de l'Approche Notre systรจme de gรฉnรฉration de CV utilise une approche hybride innovante combinant : 1. **Template Word (docx)** comme base de design 2. **Remplissage dynamique** avec Jinja2/docxtpl 3. **Ajustement automatique** des tailles et espacements selon le volume de contenu Cette approche garantit que **le CV tient toujours sur une seule page**, quelle que soit la quantitรฉ d'informations. --- ## ๐Ÿ—๏ธ Architecture de la Solution ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ PROCESSUS DE Gร‰Nร‰RATION โ”‚ โ”‚ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Donnรฉes โ”‚โ”€โ”€โ”€โ–ถโ”‚ Calcul โ”‚โ”€โ”€โ”€โ–ถโ”‚ Sรฉlection โ”‚ โ”‚ โ”‚ โ”‚ CV (JSON) โ”‚ โ”‚ Volume โ”‚ โ”‚ Preset โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ Template โ”‚โ”€โ”€โ”€โ–ถโ”‚ Remplissage โ”‚โ”€โ”€โ”€โ–ถโ”‚ Ajustement โ”‚ โ”‚ โ”‚ โ”‚ .docx โ”‚ โ”‚ Jinja2 โ”‚ โ”‚ Tailles โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ–ผ โ”‚ โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ CV Final โ”‚ โ”‚ โ”‚ โ”‚ (1 page) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐Ÿ”ง Composants Principaux ### 1. Template Word (template.docx) Le template est un fichier Word avec un design 2 colonnes contenant des **placeholders Jinja2** : ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ COLONNE GAUCHE โ”‚ COLONNE DROITE โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ CONTACT โ”‚ {{ full_name }} โ”‚ โ”‚ {{ phone }} โ”‚ โ”‚ โ”‚ {{ email }} โ”‚ PROFIL โ”‚ โ”‚ {{ address }} โ”‚ {{ summary }} โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ COMPร‰TENCES โ”‚ FORMATION โ”‚ โ”‚ {% for skill โ”‚ {% for edu in education %} โ”‚ โ”‚ in skills %} โ”‚ {{ edu.degree }} โ”‚ โ”‚ โ€ข {{ skill. โ”‚ ({{ edu.period }}) โ”‚ โ”‚ display }} โ”‚ {% endfor %} โ”‚ โ”‚ {% endfor %} โ”‚ โ”‚ โ”‚ โ”‚ EXPร‰RIENCES โ”‚ โ”‚ LANGUES โ”‚ {% for exp in experiences %} โ”‚ โ”‚ {% for lang %} โ”‚ {{ exp.job_title }} โ”‚ โ”‚ โ€ข {{ lang. โ”‚ {{ exp.company }} โ”‚ โ”‚ display }} โ”‚ {% endfor %} โ”‚ โ”‚ {% endfor %} โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ### 2. Calcul du Volume de Contenu L'algorithme calcule un **score de volume** basรฉ sur tous les รฉlรฉments du CV : ```python def _calculate_content_volume(self, cv_data): volume = 0 # Expรฉriences : 2 points + lignes de description for exp in cv_data.experiences: volume += 2 # Titre + entreprise if exp.description: lines = exp.description.split('\n') volume += len([l for l in lines if l.strip()]) # Formations : 2 points chacune for edu in cv_data.education: volume += 2 if edu.description: volume += 1 # Autres รฉlรฉments : 1 point chacun volume += len(cv_data.skills) volume += len(cv_data.languages) volume += len(cv_data.hobbies) # Rรฉsumรฉ : 1 point par 100 caractรจres if cv_data.personal_info.summary: volume += len(cv_data.personal_info.summary) // 100 + 1 return volume ``` ### 3. Systรจme de Presets (Paliers) Selon le volume calculรฉ, un **preset** est sรฉlectionnรฉ : | Preset | Volume | Police Nom | Police Section | Police Normale | Police Petite | |--------|--------|------------|----------------|----------------|---------------| | `light` | < 18 | 22pt | 11pt | 10pt | 9pt | | `medium` | 18-25 | 20pt | 10pt | 9pt | 8pt | | `dense` | 25-35 | 18pt | 9pt | 8pt | 7pt | | `very_dense` | > 35 | 16pt | 8pt | 7pt | 6pt | ### 4. Espacements Adaptatifs Les espacements entre paragraphes varient รฉgalement : | Preset | Espace Avant | Espace Aprรจs | Interligne | |--------|--------------|--------------|------------| | `light` | 3pt | 1pt | 0.9 | | `medium` | 2pt | 1pt | 0.9 | | `dense` | 1pt | 0pt | 0.9 | | `very_dense` | 0pt | 0pt | 0.9 | --- ## ๐Ÿ“Š Diagramme du Flux de Donnรฉes ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ CVData JSON โ”‚ โ”‚ โ”‚ โ”‚ โ€ข personal_info โ”‚ โ”‚ โ€ข experiences โ”‚ โ”‚ โ€ข education โ”‚ โ”‚ โ€ข skills โ”‚ โ”‚ โ€ข languages โ”‚ โ”‚ โ€ข hobbies โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ _calculate_content_volume โ”‚ โ”‚ โ”‚ โ”‚ Volume = ฮฃ(รฉlรฉments) โ”‚ โ”‚ โ”‚ โ”‚ Ex: 3 exp + 2 edu + 5 skillsโ”‚ โ”‚ + 2 lang + 3 hobbies โ”‚ โ”‚ = ~25 points โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ _get_size_preset โ”‚ โ”‚ โ”‚ โ”‚ if volume > 35: very_dense โ”‚ โ”‚ elif volume > 25: dense โ”‚ โ”‚ elif volume > 18: medium โ”‚ โ”‚ else: light โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ _prepare_context โ”‚ โ”‚ โ”‚ โ”‚ Transforme CVData en dict โ”‚ โ”‚ compatible Jinja2 โ”‚ โ”‚ โ”‚ โ”‚ โ€ข description_lines โ”‚ โ”‚ โ€ข period formatรฉ โ”‚ โ”‚ โ€ข display strings โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ DocxTemplate.render() โ”‚ โ”‚ โ”‚ โ”‚ Remplit les placeholders โ”‚ โ”‚ {{ variable }} โ”‚ โ”‚ {% for %} ... {% endfor %} โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ _adjust_document_sizes โ”‚ โ”‚ โ”‚ โ”‚ Parcourt tous les รฉlรฉments โ”‚ โ”‚ โ€ข Paragraphes โ”‚ โ”‚ โ€ข Cellules de tableau โ”‚ โ”‚ โ”‚ โ”‚ Applique : โ”‚ โ”‚ โ€ข Tailles de police โ”‚ โ”‚ โ€ข Espacements โ”‚ โ”‚ โ€ข Interligne โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ CV Final .docx โ”‚ โ”‚ โ”‚ โ”‚ โœ… Tient sur 1 page โ”‚ โ”‚ โœ… Design prรฉservรฉ โ”‚ โ”‚ โœ… Lisible โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` --- ## ๐ŸŽจ Avantages de l'Approche Template ### โœ… Points Forts | Avantage | Description | |----------|-------------| | **Design prรฉservรฉ** | Le template Word garde toutes les mises en forme (couleurs, polices, bordures) | | **Facilement modifiable** | Un designer peut modifier le template sans toucher au code | | **Sรฉparation des responsabilitรฉs** | Design (template) vs Logique (Python) | | **Rรฉutilisable** | Plusieurs templates possibles pour diffรฉrents styles | | **Ajustement intelligent** | Le CV s'adapte automatiquement au contenu | ### โš ๏ธ Limitations | Limitation | Solution | |------------|----------| | Template doit exister | Guide de crรฉation fourni | | Syntaxe Jinja2 requise | Documentation des placeholders | | Ajustement post-rendu | Peut lรฉgรจrement modifier le design | --- ## ๐Ÿ”„ Algorithme d'Ajustement Dรฉtaillรฉ ```python def _adjust_document_sizes(self, doc, preset_name): """ Parcourt le document et ajuste dynamiquement : 1. Les tailles de police selon leur taille actuelle 2. Les espacements avant/aprรจs paragraphes 3. L'interligne (line_spacing) """ preset = self.SIZE_PRESETS[preset_name] spacing = self.SPACING_PRESETS[preset_name] # Rรจgle de mapping des tailles # โ‰ฅ 20pt โ†’ taille 'name' (titre principal) # โ‰ฅ 11pt โ†’ taille 'section' (titres de section) # โ‰ฅ 9pt โ†’ taille 'normal' (texte courant) # < 9pt โ†’ taille 'small' (dรฉtails, dates) for paragraph in doc.paragraphs: paragraph.space_before = spacing['before'] paragraph.space_after = spacing['after'] paragraph.line_spacing = 0.9 # Compact for run in paragraph.runs: if run.font.size >= Pt(20): run.font.size = preset['name'] elif run.font.size >= Pt(11): run.font.size = preset['section'] # ... etc ``` --- ## ๐Ÿ“ˆ Exemples de Rรฉsultats ### Cas 1 : CV Lรฉger (Volume < 18) - 1 expรฉrience - 1 formation - 3 compรฉtences - 2 langues **Rรฉsultat** : Preset `light`, grandes polices, espacement confortable ### Cas 2 : CV Moyen (Volume 18-25) - 2 expรฉriences - 2 formations - 5 compรฉtences - 3 langues - 3 hobbies **Rรฉsultat** : Preset `medium`, polices lรฉgรจrement rรฉduites ### Cas 3 : CV Dense (Volume 25-35) - 3 expรฉriences avec descriptions dรฉtaillรฉes - 3 formations - 8 compรฉtences - 3 langues - 5 hobbies **Rรฉsultat** : Preset `dense`, polices compactes, espacements minimaux ### Cas 4 : CV Trรจs Dense (Volume > 35) - 5+ expรฉriences - 4+ formations - 10+ compรฉtences **Rรฉsultat** : Preset `very_dense`, tout est compressรฉ pour tenir sur 1 page --- ## ๐Ÿ› ๏ธ Technologies Utilisรฉes | Technologie | Rรดle | |-------------|------| | **docxtpl** | Moteur de template Jinja2 pour Word | | **python-docx** | Manipulation programmatique des documents Word | | **LibreOffice** | Conversion DOCX โ†’ PDF (headless) | | **Pydantic** | Validation des donnรฉes d'entrรฉe | | **FastAPI** | API REST pour le service | --- ## ๐Ÿ“ Guide de Crรฉation de Template Pour crรฉer un nouveau template : 1. **Ouvrir Word/LibreOffice** 2. **Designer votre CV** avec le style souhaitรฉ 3. **Remplacer les donnรฉes** par les placeholders Jinja2 : - `{{ full_name }}` pour le nom - `{% for exp in experiences %}...{% endfor %}` pour les boucles 4. **Sauvegarder** en `.docx` dans `backend/app/templates/` ### Placeholders Disponibles ```jinja2 {# Informations personnelles #} {{ full_name }} {{ email }} {{ phone }} {{ address }} {{ summary }} {# Expรฉriences #} {% for exp in experiences %} {{ exp.job_title }} {{ exp.company }} {{ exp.period }} {% for line in exp.description_lines %} {{ line }} {% endfor %} {% endfor %} {# Formation #} {% for edu in education %} {{ edu.degree }} {{ edu.institution }} {{ edu.period }} {% endfor %} {# Compรฉtences #} {% for skill in skills %} {{ skill.display }} {% endfor %} {# Langues #} {% for lang in languages %} {{ lang.display }} {% endfor %} {# Hobbies #} {% for hobby in hobbies %} {{ hobby }} {% endfor %} ``` --- ## ๐ŸŽฏ Conclusion Cette approche **Template + Ajustement Automatique** offre le meilleur des deux mondes : - **Flexibilitรฉ du design** : Le template Word permet n'importe quel style visuel - **Garantie de pagination** : L'ajustement automatique assure toujours 1 page - **Maintenabilitรฉ** : Sรฉparation claire entre design et logique - **ร‰volutivitรฉ** : Facile d'ajouter de nouveaux templates ou presets --- *Documentation technique - Janvier 2026*