11 KiB
11 KiB
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
- Init repo Git :
.gitignore,README.md, structure dossiers (backend/,frontend/,docker/) - 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
- Service
- 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.txtavec versions pinned
- FastAPI app factory (
- Frontend scaffold :
npm create vite@latestavec template React + TypeScript- Tailwind CSS setup
- Prettier config
- Structure dossiers (
src/components/,src/pages/,src/api/,src/hooks/)
.env.exampleavec toutes les variables documentées- Smoke test :
docker compose up→ backend répondGET /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 upfonctionne sans erreurGET /healthretourne{"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
- Modèles SQLAlchemy :
User,Category,Transaction,Budget,RefreshToken- UUIDs,
created_at/updated_atauto,deleted_atpour soft-delete amount_centsINTEGER, contrainte CHECK > 0
- UUIDs,
- Migrations Alembic :
alembic revision --autogenerate -m "initial models" - 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_userpour les routes protégées
- Endpoint
- Seed catégories par défaut : Alimentation, Transport, Logement, Santé, Loisirs, Divers (dépenses) + Salaire, Freelance, Remboursement (revenus)
Jour 2 : CRUD Transactions & Catégories
- Transactions :
GET /transactions: pagination, filtres (mois, catégorie, type), tri par date descPOST /transactions: validation Pydantic, isolation par user_idPUT /transactions/{id}: vérification ownershipDELETE /transactions/{id}: soft-delete (setdeleted_at)
- Catégories :
GET /categories: catégories user + catégories système (is_default)POST /categories: personnalisées uniquementPUT /categories/{id}: pas de modif des catégories systèmeDELETE /categories/{id}: refus 409 si transactions liées actives
- Services layer : séparer la logique métier des routes (pas de requêtes SQL dans les endpoints)
Jour 3 : Tests Backend
- Fixtures pytest : base de test PostgreSQL (ou SQLite async pour la vitesse), factory pour User/Transaction/Category
- 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é)
- 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
- 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
- Client API : module
src/api/client.tsavec intercepteur Axios/fetch, gestion auto du refresh token - Auth store : Context React ou Zustand léger (user, tokens, login/logout)
- Pages auth : Login, Register avec validation côté client
- Layout principal : Sidebar navigation (Dashboard, Transactions, Budgets, Historique), header avec nom user + logout
- Route guard : redirect vers login si non authentifié
Jour 5 : Liste & Formulaire Transactions
- 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
- 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
- TanStack Query : cache serveur, invalidation après mutation
Jour 6 : Catégories & Polish
- Gestion catégories : page settings ou modal, CRUD catégories personnalisées avec couleur et icône
- Feedback UI : toasts de confirmation (ajout, suppression), skeleton loading, états vides
- Responsive : mobile-first, sidebar collapsible sur mobile
- 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
- Endpoints backend :
GET /dashboard?month=YYYY-MM: solde, totaux, répartition par catégorie, tendance 6 mois, alertes budget
- 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)
- Navigation mensuelle : boutons mois précédent/suivant sur le dashboard
Jour 8 : Budgets (Enveloppes)
- Endpoints backend :
GET /budgets?month=YYYY-MM: budgets avec calculspent_centsetremaining_centsPOST /budgets: création avec contrainte unicité (user, category, month)PUT /budgets/{id},DELETE /budgets/{id}
- 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")
- Tests : calcul consommation budget, reconduction, alertes seuil
Jour 9 : Historique Mensuel
- Endpoint backend :
GET /history?year=YYYY→ résumé par mois - 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
- Graphique annuel : courbe revenus/dépenses sur 12 mois (Recharts LineChart)
Jour 10 : Export CSV & PDF
- Endpoint CSV :
GET /export/csv?month=YYYY-MM→ streaming CSV avec headers - 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
- Boutons export dans la page Transactions et le Dashboard
- 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
- Dockerfile backend : multi-stage (build deps → runtime slim)
- Dockerfile frontend : multi-stage (build Vite → nginx:alpine)
- 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
- Entrypoint backend : exécute
alembic upgrade headau démarrage - Sécurité : CORS restrictif, rate limiting (slowapi), HTTPS-ready headers
Jour 12 : Documentation & Qualité
- 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)
- OpenAPI : vérifier que la doc auto est complète et lisible
- Tests e2e légers : script Bash qui lance le stack, crée un user, ajoute une transaction, vérifie le dashboard
- 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
/speckit.tasks— Découper ce plan en tâches atomiques assignables/speckit.implement— Lancer l'implémentation phase par phase