Files
budget-tracker/.specify/memory/research.md
T

101 lines
5.1 KiB
Markdown

# Recherche & Décisions Techniques — Budget Tracker
## Authentification
- **Décision** : JWT (tokens access 15min + refresh 7j) via `python-jose` + `passlib[bcrypt]`
- **Rationale** : stateless, compatible SPA React, aucune session serveur à gérer, facile à dockeriser
- **Alternatives** :
- Session cookies (plus simple mais couplé au serveur, complexe en CORS)
- OAuth2 externe / Keycloak (overkill pour usage personnel)
- FastAPI-Users (bibliothèque haut niveau — ajoute de la magie, préférence pour la transparence)
## Base de données
- **Décision** : PostgreSQL 16
- **Rationale** : ACID natif (critique pour données financières), types UUID, ENUM, support transactionnel, standard de l'industrie
- **Alternatives** :
- SQLite (suffisant en dev, mais limité en concurrence et types)
- MySQL (moins bon support UUID/ENUM natif)
## ORM & Migrations
- **Décision** : SQLAlchemy 2.0 (mode async) + Alembic
- **Rationale** : async natif pour FastAPI, migrations versionées et réversibles, mature et bien documenté
- **Alternatives** :
- Tortoise ORM (async natif mais moins mature, moins d'intégrations)
- SQLModel (wrapper SQLAlchemy+Pydantic — moins de contrôle sur les modèles)
- Prisma (Node.js uniquement)
## Framework Backend
- **Décision** : FastAPI 0.111+
- **Rationale** : OpenAPI/Swagger auto-généré (conforme principe I de la Constitution), validation Pydantic intégrée, async natif, typage strict
- **Alternatives** :
- Django REST Framework (sync-first, plus lourd)
- Flask (pas d'async natif, validation manuelle)
## Framework Frontend
- **Décision** : React 18 + TypeScript + Vite
- **Rationale** : écosystème riche, SPA adaptée à une app de gestion, typage fort réduit les erreurs sur les montants financiers
- **Alternatives** :
- Next.js (SSR inutile pour usage authentifié perso)
- Vue 3 (viable mais écosystème plus réduit)
## Styling Frontend
- **Décision** : Tailwind CSS 3 + shadcn/ui
- **Rationale** : utilitaires CSS rapides, shadcn/ui fournit composants accessibles (formulaires, modales, tableaux) sans dépendance lourde
- **Alternatives** :
- MUI / Ant Design (plus lourds, style moins personnalisable)
- CSS Modules (trop verbeux pour une SPA)
## Graphiques Frontend
- **Décision** : Recharts
- **Rationale** : composants React purs (pas de D3 direct), bon support responsive, Tailwind-compatible, léger (~180 ko gzip)
- **Alternatives** :
- Chart.js + react-chartjs-2 (moins idiomatic React, state management externe)
- Nivo (très complet mais plus lourd, over-engineering pour 2 types de graphiques)
- Victory (moins maintenu)
## Gestion d'état Frontend
- **Décision** : TanStack Query (React Query) v5
- **Rationale** : cache serveur, invalidation automatique après mutations (soldes recalculés), gestion loading/error intégrée — évite un store global Redux pour des données essentiellement serveur
- **Alternatives** :
- Redux Toolkit (overkill, état global inutile si les données viennent de l'API)
- SWR (moins de fonctionnalités sur les mutations)
- Zustand (utile pour état local UI uniquement, complémentaire)
## Export CSV
- **Décision** : module `csv` Python stdlib
- **Rationale** : aucune dépendance additionnelle, suffisant pour colonnes tabulaires de transactions, streaming possible via `StreamingResponse` FastAPI
- **Alternatives** :
- pandas (overkill, dépendance lourde)
## Export PDF
- **Décision** : WeasyPrint
- **Rationale** : rendu HTML→PDF côté serveur, templates Jinja2 réutilisables, CSS support correct, rendu fidèle
- **Alternatives** :
- ReportLab (API bas niveau, verbeux pour des tableaux)
- pdfkit (dépendance système wkhtmltopdf, difficile à dockeriser)
- Reportlab + xhtml2pdf (moins stable)
## Stockage des montants
- **Décision** : entiers en centimes (`amount_cents INTEGER`)
- **Rationale** : conforme au principe II de la Constitution — élimine toute erreur d'arrondi IEEE 754 sur les opérations financières (ex : 0.1 + 0.2 ≠ 0.3 en float)
- **Règle** : la conversion euros↔centimes se fait uniquement aux frontières (serialisation Pydantic et affichage React)
## Soft Delete
- **Décision** : champ `deleted_at TIMESTAMP NULL` sur `Transaction` et `Category`
- **Rationale** : conforme au principe II (tracabilité historique), permet l'audit et la restauration éventuelle
- **Implémentation** : filtre `WHERE deleted_at IS NULL` systématique dans les requêtes ; index partiel recommandé
## Conteneurisation
- **Décision** : Docker Compose (backend + frontend + PostgreSQL)
- **Rationale** : conforme au principe V de la Constitution, reproductibilité dev/prod, un seul `docker compose up`
- **Structure** :
- `backend/` — image Python 3.12-slim
- `frontend/` — build Vite servi par Nginx
- `db/` — PostgreSQL 16 officiel
## Tests Backend
- **Décision** : pytest + httpx (client async) + pytest-asyncio + base de données de test dédiée
- **Rationale** : conforme au principe III (80% coverage services/), tests d'intégration sur vraie BDD (pas de mock SQLAlchemy)
- **Alternatives** :
- unittest (moins expressif)
- mocks SQLAlchemy (rejeté — risque de divergence mock/prod)