commit 513251f00459a1d560769d58d156ff44955a9f21 Author: Fabien ZARIFIAN Date: Mon Apr 13 12:35:59 2026 +0200 feat: ajouter le PROMPT.md — spécification complète du projet CVP Définition de la vision, stack technique, architecture, conventions, fonctionnalités par phase et stratégie de fiabilité. diff --git a/PROMPT.md b/PROMPT.md new file mode 100644 index 0000000..175d858 --- /dev/null +++ b/PROMPT.md @@ -0,0 +1,367 @@ +# CVP — CV Personnalisé + +## Vision du projet + +CVP est une application web locale de recherche d'emploi intelligente. +Elle agrège automatiquement les offres d'emploi depuis des APIs gratuites (France Travail, Adzuna), analyse la compatibilité entre le profil de l'utilisateur et chaque offre via un LLM local (Phi-3 mini sur Ollama), puis génère un CV adapté et optimisé pour chaque candidature. L'objectif est d'automatiser et personnaliser la démarche de candidature pour maximiser les chances de retour. + +--- + +## Stack technique + +| Couche | Technologie | Version | Confiance | Notes | +|--------|-------------|---------|-----------|-------| +| **Frontend** | Next.js (App Router) | 14.x | 🟢 Élevée | SSR, routing, API routes | +| **UI Framework** | React | 18.x | 🟢 Élevée | | +| **Styling** | Tailwind CSS | 3.x | 🟢 Élevée | Utility-first, dark mode natif | +| **Composants UI** | shadcn/ui | latest | 🟢 Élevée | Composants accessibles, personnalisables | +| **Backend API** | Python FastAPI | 0.110+ | 🟢 Élevée | Async, typage fort, docs auto | +| **ORM** | SQLAlchemy | 2.x | 🟢 Élevée | Async support | +| **Migrations** | Alembic | latest | 🟢 Élevée | | +| **Base de données** | PostgreSQL | 16.x | 🟢 Élevée | Full-text search pour les offres | +| **LLM local** | Ollama + Phi-3 mini (3.8B) | latest | 🟡 Moyen | Quantifié Q4, tourne sur RTX 1050 Ti 4 Go | +| **API Offres** | France Travail API | v2 | 🟢 Élevée | Gratuite, officielle, ~500k offres | +| **API Offres** | Adzuna API | v1 | 🟡 Moyen | Gratuite (limite quotidienne), multi-sources | +| **Génération PDF** | WeasyPrint | latest | 🟢 Élevée | HTML → PDF fidèle | +| **Génération DOCX** | python-docx | latest | 🟢 Élevée | | +| **i18n** | next-intl | latest | 🟢 Élevée | FR par défaut, extensible | +| **Scheduler** | APScheduler | 3.x | 🟢 Élevée | Cron jobs pour scraping quotidien | +| **Validation** | Pydantic | 2.x | 🟢 Élevée | Validation des données côté backend | + +### Légende confiance + +- 🟢 **Élevée** : je produis du code correct et idiomatique du premier coup +- 🟡 **Moyen** : fonctionnel mais peut nécessiter des ajustements, tester en conditions réelles +- 🔵 **Via Context7** : documentation à vérifier systématiquement avant implémentation + +--- + +## Architecture + +### Vue d'ensemble + +``` +┌─────────────────────────────────────────┐ +│ Frontend (Next.js) │ +│ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Dashboard│ │ Offres │ │ CV Gen │ │ +│ │ │ │ Explorer │ │ Builder │ │ +│ └─────────┘ └──────────┘ └──────────┘ │ +└──────────────────┬──────────────────────┘ + │ REST API +┌──────────────────▼──────────────────────┐ +│ Backend (FastAPI) │ +│ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Jobs │ │ Matching │ │ CV │ │ +│ │ Fetcher │ │ Engine │ │ Generator│ │ +│ └────┬────┘ └────┬─────┘ └────┬─────┘ │ +│ │ │ │ │ +│ ┌────▼────┐ ┌────▼─────┐ ┌───▼──────┐ │ +│ │ France │ │ Ollama │ │WeasyPrint│ │ +│ │ Travail │ │ Phi-3 │ │python-doc│ │ +│ │ Adzuna │ │ mini │ │ │ │ +│ └─────────┘ └──────────┘ └──────────┘ │ +└──────────────────┬──────────────────────┘ + │ + ┌────────▼────────┐ + │ PostgreSQL │ + └─────────────────┘ +``` + +### Structure des dossiers + +``` +cvp/ +├── frontend/ # Application Next.js +│ ├── src/ +│ │ ├── app/ # App Router (pages, layouts) +│ │ │ ├── [locale]/ # Routes i18n +│ │ │ │ ├── dashboard/ +│ │ │ │ ├── offres/ +│ │ │ │ ├── profil/ +│ │ │ │ ├── cv/ +│ │ │ │ ├── candidatures/ +│ │ │ │ └── parametres/ +│ │ │ └── api/ # API routes Next.js (proxy si besoin) +│ │ ├── components/ +│ │ │ ├── ui/ # Composants shadcn/ui +│ │ │ ├── layout/ # Header, Sidebar, Footer +│ │ │ ├── offres/ # Composants liés aux offres +│ │ │ ├── cv/ # Composants liés au CV +│ │ │ └── profil/ # Composants liés au profil +│ │ ├── lib/ # Utilitaires, API client, helpers +│ │ ├── hooks/ # Custom React hooks +│ │ ├── types/ # Types TypeScript partagés +│ │ ├── messages/ # Fichiers de traduction (fr.json, en.json) +│ │ └── styles/ # Styles globaux +│ ├── public/ +│ ├── next.config.js +│ ├── tailwind.config.ts +│ ├── tsconfig.json +│ └── package.json +│ +├── backend/ # Application FastAPI +│ ├── app/ +│ │ ├── main.py # Point d'entrée FastAPI +│ │ ├── config.py # Configuration (env vars, settings) +│ │ ├── api/ +│ │ │ ├── routes/ # Endpoints groupés par domaine +│ │ │ │ ├── offres.py +│ │ │ │ ├── profil.py +│ │ │ │ ├── cv.py +│ │ │ │ ├── candidatures.py +│ │ │ │ └── parametres.py +│ │ │ └── deps.py # Dépendances injectées (DB session, etc.) +│ │ ├── models/ # Modèles SQLAlchemy +│ │ │ ├── offre.py +│ │ │ ├── profil.py +│ │ │ ├── competence.py +│ │ │ ├── experience.py +│ │ │ ├── formation.py +│ │ │ ├── candidature.py +│ │ │ └── cv_genere.py +│ │ ├── schemas/ # Schémas Pydantic (request/response) +│ │ ├── services/ # Logique métier +│ │ │ ├── job_fetcher.py # Agrégation offres (France Travail + Adzuna) +│ │ │ ├── matching.py # Matching profil/offre via LLM +│ │ │ ├── cv_generator.py # Génération CV (PDF, DOCX, HTML) +│ │ │ ├── llm_client.py # Interface Ollama +│ │ │ └── scheduler.py # Tâches planifiées (APScheduler) +│ │ ├── templates/ # Templates HTML pour CV +│ │ │ └── cv_pro.html +│ │ └── db/ +│ │ ├── database.py # Connexion PostgreSQL +│ │ └── migrations/ # Alembic +│ ├── tests/ +│ ├── requirements.txt +│ └── pyproject.toml +│ +├── docker-compose.yml # PostgreSQL + Ollama (optionnel) +├── .env.example +├── PROMPT.md # Ce fichier +└── CLAUDE.md # Directives Claude Code +``` + +--- + +## Conventions de codage + +### TypeScript / Frontend + +- **Langage** : TypeScript strict (`strict: true` dans tsconfig) +- **Nommage** : + - Composants : PascalCase (`OffreCard.tsx`) + - Hooks : camelCase préfixé `use` (`useOffres.ts`) + - Utilitaires : camelCase (`formatDate.ts`) + - Types/Interfaces : PascalCase, pas de préfixe `I` (`Offre`, pas `IOffre`) + - Constantes : UPPER_SNAKE_CASE +- **Composants** : fonctionnels uniquement, pas de classes +- **State management** : React hooks (`useState`, `useContext`) — pas de Redux +- **Imports** : alias `@/` pour `src/` +- **Fichiers** : un composant par fichier, co-localiser les types avec le composant s'ils sont spécifiques + +### Python / Backend + +- **Version** : Python 3.11+ +- **Nommage** : + - Modules et variables : snake_case + - Classes : PascalCase + - Constantes : UPPER_SNAKE_CASE +- **Typage** : annotations de type sur toutes les fonctions publiques +- **Async** : utiliser `async def` pour tous les endpoints et les accès DB +- **Imports** : absolus depuis `app.` (`from app.services.matching import ...`) +- **Docstrings** : uniquement sur les fonctions publiques de services, format Google style +- **Pas de `print()`** : utiliser `logging` systématiquement + +### Git + +- **Commits** : Conventional Commits en français + - `feat: ajouter le matching LLM profil/offre` + - `fix: corriger l'export PDF des CV` + - `chore: mettre à jour les dépendances` +- **Branches** : `feature/nom-court`, `fix/description`, `chore/description` +- **Ne jamais ajouter de ligne `Co-Authored-By` dans les messages de commit** +- **Trunk-based** : branches courtes, merge fréquent vers `main` + +--- + +## Outils et plugins Claude Code + +### Superpowers + +- **Brainstorming** : invoquer `/superpowers:brainstorming` avant toute nouvelle feature ou décision d'architecture +- **TDD** : invoquer `/superpowers:test-driven-development` pour chaque feature — écrire les tests avant l'implémentation +- **Debugging** : invoquer `/superpowers:systematic-debugging` face à tout bug ou comportement inattendu +- **Code Review** : invoquer `/superpowers:requesting-code-review` après chaque feature complétée +- **Vérification** : invoquer `/superpowers:verification-before-completion` avant de déclarer un travail terminé +- **Plans** : invoquer `/superpowers:writing-plans` pour toute tâche multi-étapes + +### Context7 + +- **Quand utiliser** : TOUJOURS vérifier la documentation via Context7 avant d'implémenter une intégration avec : + - France Travail API + - Adzuna API + - Ollama API + - WeasyPrint + - python-docx + - next-intl + - shadcn/ui (si doute sur un composant) +- **Directive** : ne jamais deviner une API — vérifier la signature exacte via Context7 + +### Frontend Design + +- Invoquer le skill `frontend-design` pour toute création de page ou composant UI +- Respecter la direction esthétique définie (moderne, coloré, light/dark toggle) + +### Commit + +- Utiliser `/commit` pour créer les commits +- Ne jamais ajouter `Co-Authored-By` dans les messages + +--- + +## Fonctionnalités par phase + +### Phase 1 — Fondations (MVP) + +- [ ] **Profil utilisateur** : formulaire de saisie du profil + - Informations personnelles (nom, email, téléphone, localisation) + - Compétences techniques (nom, niveau : débutant/intermédiaire/expert) + - Soft skills + - Expériences professionnelles (poste, entreprise, dates, description) + - Formations (diplôme, établissement, année) + - Langues parlées (langue, niveau) +- [ ] **Intégration France Travail API** : recherche et import d'offres + - Configuration des critères de recherche (métier, localisation, type contrat, mots-clés) + - Stockage des offres en base avec déduplication + - Affichage liste + détail d'une offre +- [ ] **Intégration Adzuna API** : second source d'offres + - Même logique que France Travail, adaptée à leur API + - Déduplication cross-source +- [ ] **Scheduler quotidien** : récupération automatique des nouvelles offres +- [ ] **Base de données** : modèles, migrations, seed initial + +### Phase 2 — Intelligence (Matching + Génération) + +- [ ] **Intégration Ollama / Phi-3 mini** : client LLM local + - Vérification que Ollama est actif, fallback gracieux si non disponible + - Gestion du timeout (le LLM local peut être lent) +- [ ] **Matching profil/offre** : analyse de compatibilité + - Score global de matching (0-100%) + - Scores détaillés : compétences techniques, soft skills, expérience, formation + - Affichage visuel des scores sur chaque offre + - Tri et filtre des offres par score +- [ ] **Génération de CV** : création du CV adapté + - Mode réorganisation : réordonne les rubriques selon la pertinence pour l'offre + - Mode reformulation : le LLM reformule les descriptions pour coller au vocabulaire de l'offre + - Choix du mode par l'utilisateur avant génération + - Preview du CV dans le navigateur (HTML) + - Export PDF (WeasyPrint) + - Export DOCX (python-docx) + - Export HTML + - Un template professionnel unique + +### Phase 3 — Suivi et Polish + +- [ ] **Suivi des candidatures** : mini CRM + - Statuts : intéressé → postulé → entretien → accepté / refusé + - Date de candidature + - Notes libres par candidature + - Vue tableau / kanban des candidatures +- [ ] **Dashboard** : vue d'ensemble + - Nombre d'offres récupérées (aujourd'hui, cette semaine) + - Offres avec meilleur matching + - Statistiques candidatures (postulé, en attente, refusé) +- [ ] **i18n** : internationalisation + - Interface en français par défaut + - Anglais comme seconde langue + - Architecture extensible pour d'autres langues +- [ ] **Dark/Light mode** : toggle thème + +### Phase 4 — Extensions futures + +- [ ] Génération de lettres de motivation +- [ ] Multi-utilisateurs avec authentification +- [ ] Notifications (nouvelles offres matching > seuil) +- [ ] Historique des CV générés +- [ ] Import de CV existant (PDF parsing) + +--- + +## Design & UX + +### Direction esthétique + +- **Style** : moderne et coloré, inspiré de Stripe / Raycast +- **Couleurs** : palette vibrante avec accents de couleur forts sur fond neutre + - Primaire : bleu-violet (#6366F1 — indigo) + - Secondaire : cyan (#06B6D4) + - Accent : orange (#F59E0B) pour les scores et indicateurs + - Succès : vert (#10B981) + - Danger : rouge (#EF4444) + - Fond light : blanc (#FFFFFF) avec gris très clair (#F8FAFC) + - Fond dark : gris foncé (#0F172A) avec gris moyen (#1E293B) +- **Typographie** : Inter (UI) + JetBrains Mono (code/données) +- **Coins arrondis** : `rounded-xl` par défaut +- **Ombres** : subtiles, style glassmorphism léger +- **Animations** : transitions douces (300ms), micro-interactions sur hover +- **Dark/Light mode** : toggle avec Tailwind `dark:` classes + +### Principes UX + +- Dashboard comme page d'accueil +- Navigation par sidebar (desktop) / bottom nav (mobile) +- Les scores de matching sont visuellement proéminents (barres de progression colorées) +- Le workflow principal est : voir offre → consulter matching → générer CV → postuler +- Feedback visuel immédiat sur toutes les actions (loading states, toasts) + +--- + +## Règles impératives + +1. **Ne jamais ajouter `Co-Authored-By` dans les messages de commit** +2. **Ne jamais hardcoder de clés API** — utiliser des variables d'environnement via `.env` +3. **Ne jamais commit le fichier `.env`** — uniquement `.env.example` +4. **Toujours vérifier via Context7** avant d'implémenter une intégration API externe +5. **Toujours utiliser les types** — pas de `any` en TypeScript, pas de `# type: ignore` en Python +6. **Toujours gérer les erreurs des APIs externes** — France Travail, Adzuna, Ollama peuvent être indisponibles +7. **Le LLM local est optionnel** — l'app doit fonctionner sans Ollama (mode dégradé : pas de matching IA, pas de reformulation) +8. **Mono-utilisateur** — pas d'auth pour le moment, mais ne pas coupler l'architecture à un seul utilisateur (prévoir l'extensibilité) +9. **Français par défaut** — toute l'interface, les messages d'erreur, et les labels en français +10. **Responsive** — l'app doit être utilisable sur mobile même si optimisée desktop + +--- + +## Stratégie de fiabilité + +### Technologies 🟡 (confiance moyenne) + +#### Ollama + Phi-3 mini + +- **Risque** : performances insuffisantes sur RTX 1050 Ti 4 Go, réponses lentes ou de mauvaise qualité en français +- **Vérification** : tester la vitesse d'inférence et la qualité des réponses en français dès le début du développement +- **Fallback** : si Phi-3 mini est insuffisant en français, tester Mistral 7B Q4_K_S (plus compacte) ou Gemma 2B +- **Mode dégradé** : si Ollama n'est pas disponible, l'app fonctionne sans matching IA — afficher un message clair à l'utilisateur +- **Timeout** : fixer un timeout de 30s sur les appels Ollama, avec message explicite si dépassé + +#### Adzuna API + +- **Risque** : limites de requêtes quotidiennes sur le tier gratuit, format de réponse qui change +- **Vérification** : consulter la documentation via Context7 avant implémentation +- **Fallback** : si Adzuna est down ou limite atteinte, continuer avec France Travail seul +- **Monitoring** : logger les erreurs API et les limites atteintes + +### Comportement quand un pattern échoue + +1. **Ne pas paniquer** — activer le skill `superpowers:systematic-debugging` +2. **Isoler le problème** — tester le composant défaillant en isolation +3. **Vérifier Context7** — la documentation a peut-être changé +4. **Chercher une alternative** — si un package ne fonctionne pas, chercher une alternative mature avant de bricoler +5. **Communiquer** — dire clairement ce qui ne fonctionne pas et pourquoi + +### Vérification systématique + +- Avant chaque commit : les tests passent, le linter est clean, l'app build +- Avant de déclarer une feature terminée : tester le workflow complet manuellement +- Avant d'intégrer une nouvelle API : lire la doc via Context7, tester un appel simple en isolation +- Avant de pousser du code LLM : vérifier la qualité des prompts avec au moins 3 exemples variés