Files

266 lines
11 KiB
Markdown

# 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