# Plan d'Implémentation — Budget Tracker **Feature** : `003-budget-tracker-core` **Date** : 2026-03-15 **Durée estimée** : 13 jours de travail **Stack** : FastAPI + SQLAlchemy 2.0 async + Alembic / React 18 + Vite + Tailwind + Recharts / PostgreSQL 16 / Docker Compose --- ## Vérification Constitution | Principe | Conformité | Notes | |----------|-----------|-------| | I. API-First | ✅ | Endpoints définis dans `contracts/api.md`, Pydantic pour la validation | | II. Data Integrity | ✅ | Montants en centimes (int), soft-delete, transactions ACID | | III. Test Coverage | ✅ | pytest backend, Vitest frontend, ≥80% logique métier | | IV. Simplicity | ✅ | Monolithe, pas de microservices, librairies standard | | V. Docker-First | ✅ | docker-compose.yml, migrations auto au démarrage, build statique nginx | --- ## Phase 0 — Setup & Infrastructure (1 jour) ### Objectif Disposer d'un environnement de développement fonctionnel avec hot-reload. ### Tâches 1. **Init repo Git** : `.gitignore`, `README.md`, structure dossiers (`backend/`, `frontend/`, `docker/`) 2. **Docker Compose dev** : - Service `db` : PostgreSQL 16, volume persistant, init script - Service `backend` : Python 3.12, hot-reload uvicorn, montage code source - Service `frontend` : Node 22, Vite dev server, montage code source 3. **Backend scaffold** : - FastAPI app factory (`backend/app/main.py`) - Config via Pydantic Settings (`.env` → `backend/app/config.py`) - SQLAlchemy 2.0 async engine + session factory - Alembic init (`backend/alembic/`) - Ruff config (`pyproject.toml`) - `requirements.txt` avec versions pinned 4. **Frontend scaffold** : - `npm create vite@latest` avec template React + TypeScript - Tailwind CSS setup - Prettier config - Structure dossiers (`src/components/`, `src/pages/`, `src/api/`, `src/hooks/`) 5. **`.env.example`** avec toutes les variables documentées 6. **Smoke test** : `docker compose up` → backend répond `GET /health`, frontend affiche une page ### Livrables - `docker-compose.yml` + `docker-compose.override.yml` (dev) - Backend qui démarre, frontend qui affiche, PostgreSQL qui tourne - Premier commit : `chore: initial project setup` ### Critères de validation - [ ] `docker compose up` fonctionne sans erreur - [ ] `GET /health` retourne `{"status": "ok"}` - [ ] Frontend accessible sur `localhost:5173` - [ ] Ruff et Prettier passent sans erreur --- ## Phase 1 — Backend Core (3 jours) ### Objectif API REST fonctionnelle avec auth, transactions et catégories. ### Jour 1 : Modèles & Auth 1. **Modèles SQLAlchemy** : `User`, `Category`, `Transaction`, `Budget`, `RefreshToken` - UUIDs, `created_at`/`updated_at` auto, `deleted_at` pour soft-delete - `amount_cents` INTEGER, contrainte CHECK > 0 2. **Migrations Alembic** : `alembic revision --autogenerate -m "initial models"` 3. **Auth JWT** : - Endpoint `POST /auth/register` (hash bcrypt, validation email unique) - Endpoint `POST /auth/login` (access token 15min + refresh token 7j) - Endpoint `POST /auth/refresh` - Endpoint `POST /auth/logout` (invalidation refresh token) - Middleware `get_current_user` pour les routes protégées 4. **Seed catégories par défaut** : Alimentation, Transport, Logement, Santé, Loisirs, Divers (dépenses) + Salaire, Freelance, Remboursement (revenus) ### Jour 2 : CRUD Transactions & Catégories 1. **Transactions** : - `GET /transactions` : pagination, filtres (mois, catégorie, type), tri par date desc - `POST /transactions` : validation Pydantic, isolation par user_id - `PUT /transactions/{id}` : vérification ownership - `DELETE /transactions/{id}` : soft-delete (set `deleted_at`) 2. **Catégories** : - `GET /categories` : catégories user + catégories système (`is_default`) - `POST /categories` : personnalisées uniquement - `PUT /categories/{id}` : pas de modif des catégories système - `DELETE /categories/{id}` : refus 409 si transactions liées actives 3. **Services layer** : séparer la logique métier des routes (pas de requêtes SQL dans les endpoints) ### Jour 3 : Tests Backend 1. **Fixtures pytest** : base de test PostgreSQL (ou SQLite async pour la vitesse), factory pour User/Transaction/Category 2. **Tests unitaires** : - Calcul de solde (revenu - dépense, centimes) - Soft-delete : la transaction n'apparaît plus mais existe en base - Validation montant > 0, date pas dans le futur (si décidé) 3. **Tests d'intégration** : - Auth : register → login → token valide → accès protégé - CRUD transactions : create → list → update → delete → list vérifie absence - Filtrage par mois et catégorie - Isolation multi-user : user A ne voit pas les transactions de user B 4. **CI** : `pytest --cov=app/services --cov-fail-under=80` ### Livrables - API complète (auth + transactions + catégories) - Suite de tests avec coverage ≥80% services - Documentation OpenAPI auto (`/docs`) --- ## Phase 2 — Frontend Core (3 jours) ### Objectif SPA React fonctionnelle avec auth et gestion des transactions. ### Jour 4 : Auth & Layout 1. **Client API** : module `src/api/client.ts` avec intercepteur Axios/fetch, gestion auto du refresh token 2. **Auth store** : Context React ou Zustand léger (user, tokens, login/logout) 3. **Pages auth** : Login, Register avec validation côté client 4. **Layout principal** : Sidebar navigation (Dashboard, Transactions, Budgets, Historique), header avec nom user + logout 5. **Route guard** : redirect vers login si non authentifié ### Jour 5 : Liste & Formulaire Transactions 1. **Page Transactions** : - Tableau avec colonnes : date, description, catégorie (badge couleur), montant, type (icône revenu/dépense) - Pagination - Filtres : mois (date picker), catégorie (select), type (toggle) - Bouton supprimer avec confirmation 2. **Formulaire Transaction** (modal ou page) : - Champs : montant (€, converti en centimes), date, type (toggle revenu/dépense), catégorie (select), description - Validation temps réel - Mode création et édition 3. **TanStack Query** : cache serveur, invalidation après mutation ### Jour 6 : Catégories & Polish 1. **Gestion catégories** : page settings ou modal, CRUD catégories personnalisées avec couleur et icône 2. **Feedback UI** : toasts de confirmation (ajout, suppression), skeleton loading, états vides 3. **Responsive** : mobile-first, sidebar collapsible sur mobile 4. **Tests Vitest** : composants critiques (formulaire transaction, affichage montant centimes→euros) ### Livrables - SPA complète : auth + transactions + catégories - Responsive mobile/desktop - Tests composants critiques --- ## Phase 3 — Features Avancées (4 jours) ### Jour 7 : Dashboard & Graphiques 1. **Endpoints backend** : - `GET /dashboard?month=YYYY-MM` : solde, totaux, répartition par catégorie, tendance 6 mois, alertes budget 2. **Page Dashboard** : - Cards KPI : solde courant, revenus du mois, dépenses du mois, solde net - Graphique camembert : répartition dépenses par catégorie (Recharts PieChart) - Graphique barres : tendance revenus/dépenses sur 6 mois (Recharts BarChart) - Alertes budgets dépassés (badges warning/danger) 3. **Navigation mensuelle** : boutons mois précédent/suivant sur le dashboard ### Jour 8 : Budgets (Enveloppes) 1. **Endpoints backend** : - `GET /budgets?month=YYYY-MM` : budgets avec calcul `spent_cents` et `remaining_cents` - `POST /budgets` : création avec contrainte unicité (user, category, month) - `PUT /budgets/{id}`, `DELETE /budgets/{id}` 2. **Page Budgets** : - Liste des enveloppes du mois avec barre de progression (vert/orange/rouge) - Formulaire ajout/édition budget (catégorie, limite en €) - Copie des budgets du mois précédent (bouton "Reconduire") 3. **Tests** : calcul consommation budget, reconduction, alertes seuil ### Jour 9 : Historique Mensuel 1. **Endpoint backend** : `GET /history?year=YYYY` → résumé par mois 2. **Page Historique** : - Tableau annuel : mois, revenus, dépenses, solde, nb transactions - Clic sur un mois → redirige vers Dashboard du mois sélectionné - Sélecteur d'année 3. **Graphique annuel** : courbe revenus/dépenses sur 12 mois (Recharts LineChart) ### Jour 10 : Export CSV & PDF 1. **Endpoint CSV** : `GET /export/csv?month=YYYY-MM` → streaming CSV avec headers 2. **Endpoint PDF** : `GET /export/pdf?month=YYYY-MM` → WeasyPrint, template Jinja2 rapport mensuel - En-tête avec titre + mois + date d'export - Tableau des transactions - Résumé par catégorie - Solde 3. **Boutons export** dans la page Transactions et le Dashboard 4. **Tests** : validité CSV (parsable), PDF non vide ### Livrables - Dashboard avec graphiques interactifs - Budgets enveloppes avec alertes - Historique annuel navigable - Export CSV + PDF fonctionnels --- ## Phase 4 — Finalisation & Production (2 jours) ### Jour 11 : Docker Production 1. **Dockerfile backend** : multi-stage (build deps → runtime slim) 2. **Dockerfile frontend** : multi-stage (build Vite → nginx:alpine) 3. **docker-compose.prod.yml** : - Backend : gunicorn + uvicorn workers - Frontend : nginx avec compression gzip, cache headers - PostgreSQL avec backup volume - Health checks sur tous les services 4. **Entrypoint backend** : exécute `alembic upgrade head` au démarrage 5. **Sécurité** : CORS restrictif, rate limiting (slowapi), HTTPS-ready headers ### Jour 12 : Documentation & Qualité 1. **README.md** complet : - Description du projet - Prérequis (Docker, Docker Compose) - Quick start : `cp .env.example .env && docker compose up` - Architecture (schéma simplifié) - Endpoints API (lien vers `/docs`) 2. **OpenAPI** : vérifier que la doc auto est complète et lisible 3. **Tests e2e légers** : script Bash qui lance le stack, crée un user, ajoute une transaction, vérifie le dashboard 4. **Cleanup** : supprimer code mort, vérifier tous les TODO, linting final ### Livrables - Docker Compose production-ready - README complet - Suite complète de tests (unit + integ + e2e) - Projet prêt à déployer --- ## Artefacts générés | Fichier | Description | |---------|-------------| | `spec.md` | Spécification fonctionnelle (7 user stories, 20 exigences) | | `research.md` | Décisions techniques avec rationale | | `data-model.md` | 5 entités, index, contraintes | | `contracts/api.md` | Contrats API REST (21 endpoints) | | `plan.md` | Ce plan d'implémentation | ## Risques identifiés | Risque | Impact | Mitigation | |--------|--------|-----------| | WeasyPrint lourd en Docker | Image backend volumineuse | Multi-stage build, layer caching | | Performances dashboard sur gros volume | Requêtes lentes >10k transactions | Index dédiés (voir `data-model.md`), pagination | | Complexité auth JWT refresh | Bugs de déconnexion intempestive | Tests d'intégration auth exhaustifs | | Recharts bundle size | Frontend lourd | Tree-shaking Vite, lazy loading des pages graphiques | ## Prochaines étapes 1. **`/speckit.tasks`** — Découper ce plan en tâches atomiques assignables 2. **`/speckit.implement`** — Lancer l'implémentation phase par phase