docs: plan.md mis à jour — Phase 3 shopping , renommage phases suivantes

This commit is contained in:
2026-05-24 15:54:45 +02:00
parent e21349511d
commit 134f6ba5f5
+110 -137
View File
@@ -5,75 +5,112 @@
--- ---
## Phase 1 — Socle technique ## Phase 1 — Socle technique
**Objectif** : environnement opérationnel, rien de métier, mais tout tourne. **Objectif** : environnement opérationnel, rien de métier, mais tout tourne.
### Backend ### Backend
- [ ] Structure projet FastAPI (`app/api/`, `app/core/`, `app/models/`, `app/schemas/`, `app/services/`) - [x] Structure projet FastAPI (`app/api/`, `app/core/`, `app/models/`, `app/schemas/`, `app/services/`)
- [ ] Configuration SQLAlchemy 2.0 async + pool de connexions - [x] Configuration SQLAlchemy 2.0 async + pool de connexions
- [ ] Création des schémas PostgreSQL (`todos`, `shopping`, `notes`) via Alembic - [x] Création des schémas PostgreSQL (`todos`, `shopping`, `notes`) via Alembic
- [ ] Migration initiale : toutes les tables (voir spec section 3) - [x] Migration initiale : toutes les tables (voir spec section 3)
- [ ] Endpoint santé : `GET /api/health` - [x] Endpoint santé : `GET /api/health`
- [ ] Module media (`app/services/media.py`) : - [x] Module media (`app/services/media.py`) :
- [ ] Validation des formats acceptés (JPG, PNG, SVG, WebP, WebM, M4A) - [x] Validation des formats acceptés (JPG, PNG, SVG, WebP, WebM, M4A)
- [ ] Génération miniature Pillow : 150×150 (shopping), 300×300 (notes), 400×300 (inline) - [x] Génération miniature Pillow : 150×150 (shopping), 300×300 (notes), 400×300 (inline)
- [ ] Sauvegarde `originals/` + `thumbnails/` sur le volume - [x] Sauvegarde `originals/` + `thumbnails/` sur le volume
- [ ] Endpoint `POST /api/media/upload` → retourne `{ file_path, thumbnail_path }` - [x] Endpoint `POST /api/media/upload` → retourne `{ file_path, thumbnail_path }`
- [ ] Endpoint `DELETE /api/media/{uuid}` → supprime original + miniature - [x] Endpoint `DELETE /api/media/{uuid}` → supprime original + miniature
- [ ] Middleware CORS pour réseau local `10.0.0.0/22` - [x] Middleware CORS pour réseau local `10.0.0.0/22`
- [ ] Configuration via variables d'environnement (`.env`) - [x] Configuration via variables d'environnement (`.env`)
- [ ] Dockerfile backend (Python 3.12 slim) - [x] Dockerfile backend (Python 3.12 slim)
### Frontend ### Frontend
- [ ] Scaffold Vite + React 18 + TypeScript - [x] Scaffold Vite + React 18 + TypeScript
- [ ] Tailwind CSS configuré avec les tokens Gruvbox (via `tokens.json`) - [x] Tailwind CSS configuré avec les tokens Gruvbox (via `tokens.json`)
- [ ] Intégration `design_system/components/ui-kit.jsx` - [x] Intégration `design_system/components/ui-kit.jsx`
- [ ] `@vite-pwa/plugin` configuré (Service Worker + manifest) - [x] `@vite-pwa/plugin` configuré (Service Worker + manifest)
- [ ] `manifest.json` avec icônes iOS + Android - [x] `manifest.json` avec icônes iOS + Android
- [ ] Routage React Router v6 - [x] Routage React Router v6
- [ ] Layout de base : navigation mobile (bottom bar) + navigation laptop (sidebar) - [x] Layout de base : navigation mobile (bottom bar) + navigation laptop (sidebar)
- [ ] Dockerfile frontend (Nginx) - [x] Dockerfile frontend (Nginx + proxy `/api/` → backend)
- [x] Favicon maison (SVG Gruvbox orange)
### Infra ### Infra
- [ ] `docker-compose.yml` avec 3 services (frontend, backend, db) - [x] `docker-compose.yml` avec 3 services (frontend, backend, db)
- [ ] Volume PostgreSQL persistant - [x] Volume PostgreSQL persistant
- [ ] Volume uploads persistant (`/uploads/`) - [x] Volume uploads persistant (`/uploads/`)
- [ ] `docker-compose.dev.yml` avec hot reload (volumes montés) - [x] Fichier `.env.example`
- [ ] Fichier `.env.example` - [x] Script de seed (`backend/app/data/seed.py`) : 113 produits + 9 magasins
- [ ] Script `dev.sh` pour démarrage local rapide
- [ ] Script de seed (`backend/app/data/seed.py`) : charge `seed_products.json` (113 produits) + `seed_stores.json` (9 magasins) en base au premier démarrage
--- ---
## Phase 2 — Module Todos ## Phase 2 — Module Todos
**Objectif** : créer, lister, modifier, terminer et reporter des tâches depuis mobile et laptop. **Objectif** : créer, lister, modifier, terminer et reporter des tâches depuis mobile et laptop.
### Backend ### Backend
- [ ] `GET /api/todos` — liste avec filtres (domaine, statut, priorité, tags) - [x] `GET /api/todos` — liste avec filtres (domaine, statut, priorité, tags, période)
- [ ] `POST /api/todos` — création - [x] `POST /api/todos` — création
- [ ] `PATCH /api/todos/{id}` — mise à jour partielle - [x] `PATCH /api/todos/{id}` — mise à jour partielle
- [ ] `DELETE /api/todos/{id}` — suppression - [x] `DELETE /api/todos/{id}` — suppression
- [ ] `POST /api/todos/{id}/postpone` — incrémente postponed_count + décale due_date - [x] `POST /api/todos/{id}/postpone` — incrémente postponed_count + décale due_date
- [ ] Schémas Pydantic : TodoCreate, TodoUpdate, TodoResponse - [x] Schémas Pydantic : TodoCreate, TodoUpdate, TodoResponse
- [x] Tests d'intégration (9 tests)
### Frontend Mobile ### Frontend Mobile
- [ ] Page Todos : liste des tâches en cours, groupées par domaine - [x] Page Todos : liste des tâches en cours, groupées par domaine
- [ ] Bouton "+ Tâche" flottant → formulaire rapide (titre + domaine + date optionnelle) - [x] Bouton "+ Tâche" flottant → Modal création (titre + domaine + date + priorité + tags)
- [ ] Swipe droite → marquer done - [x] Double-tap → Modal édition pré-rempli
- [ ] Swipe gauche → actions (reporter 1j / reporter 1 semaine / supprimer) - [x] Swipe droite → marquer done
- [ ] Badge compteur par domaine - [x] Swipe gauche → actions (reporter 1j / reporter 1 semaine / supprimer)
- [x] Badge compteur par domaine
### Frontend Laptop ### Frontend Laptop
- [ ] Vue tableau avec filtres : domaine, statut, priorité, tags, période - [x] Vue tableau avec filtres : domaine, statut, priorité, période
- [ ] Formulaire complet (tous les champs) - [x] Formulaire complet (tous les champs) via Modal
- [ ] Tri multi-colonnes - [x] Double-clic sur titre → Modal édition
- [ ] Sélection multiple + actions groupées - [x] Actions inline : ✓ done / +1j / +1S / ✕ supprimer
--- ---
## Phase 3 — Module Notes / Listes diverses ## Phase 3 — Module Shopping (liste de courses) ✅
**Objectif** : liste de courses fonctionnelle en magasin depuis smartphone, avec génération automatique.
### Backend
- [x] `GET /api/shopping/stores` — liste magasins
- [x] `GET /api/shopping/products` — catalogue avec recherche (param `q`)
- [x] `GET /api/shopping/lists` — listes de courses avec compteurs
- [x] `POST /api/shopping/lists` — création liste
- [x] `GET /api/shopping/lists/{id}` — détail liste avec articles
- [x] `PATCH /api/shopping/lists/{id}` — mise à jour liste
- [x] `DELETE /api/shopping/lists/{id}` — suppression
- [x] `POST /api/shopping/lists/{id}/items` — ajout article (produit catalogue ou custom)
- [x] `PATCH /api/shopping/lists/{id}/items/{item_id}` — cocher / modifier
- [x] `DELETE /api/shopping/lists/{id}/items/{item_id}` — suppression article
- [x] `POST /api/shopping/lists/{id}/finish` — terminer les courses (report articles non cochés → nouvelle liste draft avec `carried_over=True`)
- [x] `POST /api/shopping/lists/generate` — liste magique V1 (score = retard / intervalle moyen, articles cochés comme historique)
- [x] Schémas Pydantic complets (listes, articles, produits, magasins)
- [x] Tests d'intégration (10 tests)
### Frontend
- [x] Page Shopping avec 3 vues : liste des listes / détail / mode magasin
- [x] Vue "listes" : cartes par liste (statut, compteur articles), FAB + bouton "Liste magique"
- [x] Bouton "Liste magique" : désactivé si une liste `draft`/`active` existe
- [x] Vue "détail" : articles avec swipe-to-delete, FAB ajout article, bouton ✏️ modal gestion
- [x] Modal ✏️ : ajout rapide d'article + bouton rouge "Supprimer la liste en cours"
- [x] Vue "Mode magasin" : plein écran, grands boutons (48px+), section cochés/non cochés
- [x] Wake Lock API activée automatiquement en mode magasin
- [x] Composant `Modal` générique réutilisable (overlay + Escape + stopPropagation)
- [x] Composant `ItemRow` : checkbox circulaire + swipe-to-delete + mode magasin
- [x] Hook `useWakeLock` avec fallback gracieux (mode économie d'énergie)
- [x] Client API TypeScript typé (`frontend/src/api/shopping.ts`)
- [x] Migration TodoForm vers Modal (plus de panneau inline)
---
## Phase 4 — Module Notes
**Objectif** : saisie rapide de notes avec photo, audio et GPS depuis smartphone. **Objectif** : saisie rapide de notes avec photo, audio et GPS depuis smartphone.
@@ -89,170 +126,106 @@
### Frontend Mobile ### Frontend Mobile
- [ ] Page Notes : liste chronologique avec aperçu - [ ] Page Notes : liste chronologique avec aperçu
- [ ] Bouton "+ Note" → formulaire rapide (contenu + tags) - [ ] Bouton "+ Note" → formulaire rapide (contenu + tags) via Modal
- [ ] Bouton 📷 → Camera API (capture directe ou import galerie) - [ ] Bouton 📷 → Camera API (capture directe ou import galerie)
- [ ] Bouton 🎤 → MediaRecorder (enregistrement audio avec waveform visuel) - [ ] Bouton 🎤 → MediaRecorder (enregistrement audio avec waveform visuel)
- [ ] Bouton 📍 → Geolocation API → affichage coordonnées - [ ] Bouton 📍 → Geolocation API → affichage coordonnées
- [ ] Compression WebP côté client (Canvas API) avant upload - [ ] Compression WebP côté client (Canvas API) avant upload
- [ ] Visionneuse photo inline - [ ] Visionneuse photo inline
- [ ] Lecteur audio inline - [ ] Lecteur audio inline
- [ ] Bouton 📄 → OCR sur photo → texte extrait inséré dans le contenu de la note
### Frontend Laptop ### Frontend Laptop
- [ ] Grille notes avec vignettes photo - [ ] Grille notes avec vignettes photo
- [ ] Recherche full-text avec surlignage - [ ] Recherche full-text avec surlignage
- [ ] Filtres : catégorie, tags, avec photo, avec audio, avec GPS - [ ] Filtres : catégorie, tags, avec photo, avec audio, avec GPS
- [ ] Formulaire étendu avec champs métadonnées libres (clé/valeur)
- [ ] Vue carte pour les notes avec GPS (Leaflet.js) - [ ] Vue carte pour les notes avec GPS (Leaflet.js)
--- ---
## Phase 4Module Shopping (base) ## Phase 5Scan produits + enrichissement catalogue
**Objectif** : liste de courses fonctionnelle en magasin depuis smartphone. **Objectif** : scan code-barres depuis mobile, auto-remplissage depuis OpenFoodFacts.
### Backend
- [ ] `GET /api/shopping/products` — catalogue avec recherche
- [ ] `POST /api/shopping/products` — ajout produit catalogue
- [ ] `PATCH /api/shopping/products/{id}` — modification produit
- [ ] `GET /api/shopping/stores` — liste magasins
- [ ] `POST /api/shopping/stores` — ajout magasin
- [ ] `GET /api/shopping/lists` — listes de courses
- [ ] `POST /api/shopping/lists` — création liste (avec génération auto depuis frequency_score)
- [ ] `GET /api/shopping/lists/{id}/items` — articles de la liste
- [ ] `POST /api/shopping/lists/{id}/items` — ajout article
- [ ] `PATCH /api/shopping/list_items/{id}` — cocher / modifier prix relevé
- [ ] `POST /api/shopping/lists/{id}/finish` — terminer les courses (report automatique articles non cochés → nouvelle liste)
- [ ] Logique de report : créer liste semaine+1 avec `carried_over = true` sur articles non cochés
### Frontend Mobile — Création liste
- [ ] Page accueil shopping : liste des semaines
- [ ] "Nouvelle liste" → picker semaine + suggestions top produits (frequency_score)
- [ ] Recherche produit dans catalogue + ajout 1 tap
- [ ] Ajout rapide produit hors catalogue → création à la volée dans catalogue
### Frontend Mobile — Mode courses
- [ ] Vue liste triée par catégorie/rayon
- [ ] Wake Lock API activée automatiquement à l'ouverture
- [ ] Grand bouton checkbox par article (48px+)
- [ ] Tap sur prix → champ numérique rapide
- [ ] Swipe gauche → retirer de la liste
- [ ] Bouton "Terminer les courses" avec confirmation
### Frontend Laptop — Gestion catalogue
- [ ] Tableau produits avec photo, marque, catégorie, frequency_score
- [ ] CRUD complet produits
- [ ] Gestion magasins
- [ ] Import/export catalogue CSV
---
## Phase 4b — Module scan + enrichissement catalogue produits
**Objectif** : scan code-barres depuis mobile, auto-remplissage depuis OpenFoodFacts, recherche image via SearXNG sur laptop.
### Services Docker ### Services Docker
- [ ] Dockerfile `product-search/` : Python slim + `requests` + client OpenFoodFacts - [ ] Dockerfile `product-search/` : Python slim + `requests` + client OpenFoodFacts
- [ ] `GET /lookup?barcode={code}` → OpenFoodFacts barcode API
- [ ] `GET /search?q={nom}` → OpenFoodFacts text search
- [ ] `GET /image-search?q={nom}` → délègue à SearXNG (images uniquement)
- [ ] Ajout service `product-search` dans `docker-compose.yml` (port 8002) - [ ] Ajout service `product-search` dans `docker-compose.yml` (port 8002)
- [ ] Ajout service `searxng` dans `docker-compose.yml` (image officielle, port 8080 interne) - [ ] Ajout service `searxng` dans `docker-compose.yml` (images uniquement)
- [ ] Configuration SearXNG : désactiver toutes les catégories sauf `images`
### Backend (endpoints proxy) ### Backend (endpoints proxy)
- [ ] `GET /api/products/lookup?barcode=` → proxifie vers product-search - [ ] `GET /api/products/lookup?barcode=` → proxifie vers product-search
- [ ] `GET /api/products/search?q=` → proxifie vers product-search - [ ] `GET /api/products/search?q=` → proxifie vers product-search
- [ ] `GET /api/products/image-search?q=` → proxifie vers product-search (laptop uniquement) - [ ] `POST /api/products/import` → crée produit depuis données OpenFoodFacts
- [ ] `POST /api/products/import` → crée un produit dans le catalogue depuis les données OpenFoodFacts retournées
### Frontend Mobile — scan ### Frontend Mobile — scan
- [ ] Intégration `zxing-js` (BarcodeReader via flux caméra) - [ ] Intégration `zxing-js` (BarcodeReader via flux caméra)
- [ ] Bouton "Scanner" dans le formulaire d'ajout de produit - [ ] Bouton "Scanner" dans le formulaire d'ajout de produit
- [ ] Sur scan réussi → appel `/api/products/lookup` auto-remplissage formulaire - [ ] Sur scan réussi → auto-remplissage formulaire
- [ ] Si barcode inconnu → formulaire vide (saisie manuelle)
### Frontend Laptop — enrichissement catalogue ### Frontend Laptop — enrichissement catalogue
- [ ] Champ de recherche texte → `/api/products/search` → liste de résultats OpenFoodFacts - [ ] CRUD complet produits dans catalogue
- [ ] Bouton "Chercher une image" → `/api/products/image-search` → grille de miniatures SearXNG - [ ] Recherche texte → OpenFoodFacts → import 1 clic
- [ ] Clic sur une image → téléchargement + génération miniature via module media - [ ] Gestion magasins
--- ---
## Phase 5 — Service OCR (conteneur dédié, partagé) ## Phase 6 — Service OCR (conteneur dédié)
**Objectif** : service OCR partagé, prérequis pour le shopping avancé et les notes avancées. **Objectif** : OCR partagé, prérequis pour shopping avancé et notes avancées.
- [ ] Dockerfile `ocr/` : image Python slim + Tesseract 5 + langues (fra, eng) + Pillow - [ ] Dockerfile `ocr/` : Python slim + Tesseract 5 + langues (fra, eng) + Pillow
- [ ] `POST /extract` : reçoit une image (multipart), retourne `{ text, confidence }` - [ ] `POST /extract` : reçoit image (multipart), retourne `{ text, confidence }`
- [ ] Pré-processing Pillow : redimensionnement, niveaux de gris, amélioration contraste - [ ] Endpoint backend `POST /api/ocr/extract` : proxifie vers `ocr:8001`
- [ ] Endpoint backend unifié `POST /api/ocr/extract` : proxifie vers `ocr:8001`
- [ ] Gestion du service inactif : retour d'erreur propre sans bloquer le module appelant
- [ ] Ajout du service `ocr` dans `docker-compose.yml` - [ ] Ajout du service `ocr` dans `docker-compose.yml`
--- ---
## Phase 6 Module Shopping avancé (OCR + suivi prix) ## Phase 7 — Shopping avancé (OCR + suivi prix)
**Objectif** : OCR étiquettes et tickets, graphiques d'évolution des prix.
### Backend ### Backend
- [ ] `POST /api/shopping/ocr/price-tag` — photo étiquette → extraction prix via service OCR - [ ] `POST /api/shopping/ocr/price-tag` — photo étiquette → extraction prix
- [ ] `POST /api/shopping/ocr/receipt` — photo ticket → reconciliation avec liste - [ ] `POST /api/shopping/ocr/receipt` — photo ticket → reconciliation liste
- [ ] `GET /api/shopping/products/{id}/price-history` — historique prix par produit + magasin - [ ] `GET /api/shopping/products/{id}/price-history` — historique prix par produit + magasin
### Frontend Mobile ### Frontend
- [ ] Bouton 📷 sur chaque article → OCR étiquette → pré-remplissage prix - [ ] Bouton 📷 sur chaque article → OCR étiquette → pré-remplissage prix
- [ ] Bouton "Scanner ticket" en fin de courses → OCR receipt → confirmation reconciliation - [ ] Graphique d'évolution du prix par produit (Recharts)
### Frontend Laptop
- [ ] Graphique courbe d'évolution du prix par produit (Recharts ou Chart.js)
- [ ] Comparaison prix par magasin - [ ] Comparaison prix par magasin
- [ ] Export CSV historique des prix
--- ---
## Phase 7 — MCP Server ## Phase 8 — MCP Server
**Objectif** : exposer les outils HomeHub aux agents IA (Hermes, Claude, etc.). **Objectif** : exposer les outils HomeHub aux agents IA (Hermes, Claude, etc.).
- [ ] Intégration SDK MCP Python (`mcp` package) - [ ] Intégration SDK MCP Python (`mcp` package)
- [ ] Endpoint SSE `/mcp` - [ ] Endpoint SSE `/mcp`
- [ ] Implémentation des 6 outils (voir spec section 2.4) - [ ] Implémentation des outils : `get_todos()`, `add_todo()`, `add_shopping_item()`, `search_notes()`
- [ ] Tests avec Claude Code (MCP client)
- [ ] Documentation OpenAPI des outils MCP - [ ] Documentation OpenAPI des outils MCP
--- ---
## Phases futures (hors scope initial) ## Phases futures (hors scope initial)
--- ### Phase 9 — Authentification multi-utilisateurs
## Phases futures (hors scope initial)
### Phase 8 — Authentification multi-utilisateurs
- Auth JWT (login / refresh token) - Auth JWT (login / refresh token)
- Activation de `owner_id` dans toutes les tables - Activation de `owner_id` dans toutes les tables
- Middleware d'authentification FastAPI
- Page connexion React - Page connexion React
### Phase 9 — Calendrier + intégrations ### Phase 10 — Calendrier + intégrations
- Sync Google Calendar (OAuth2 + worker) - Sync Google Calendar (OAuth2 + worker)
- Endpoint CalDAV pour iOS - Endpoint CalDAV pour iOS
- Redis pour la queue de synchronisation - Redis pour la queue de synchronisation
- Webhooks Gitea → Kanban - Webhooks Gitea → Kanban
- Home Assistant : capteur "tâches en retard" - Home Assistant : capteur "tâches en retard"
### Phase 10 — Vision IA ### Phase 11 — Vision IA
- Endpoint analyse frigo (photo → suggestions liste de courses) - Endpoint analyse frigo (photo → suggestions liste de courses)
- Amélioration OCR via modèle Vision local (Ollama) - Amélioration OCR via modèle Vision local (Ollama)
--- ---
## Ordre de développement recommandé ## Ordre de développement
``` ```
Phase 1 → Phase 2 → Phase 4 (shopping base) → Phase 4b (scan + OpenFoodFacts) → Phase 3 (notes) → Phase 5 (OCR) → Phase 6 (shopping avancé) → Phase 7 (MCP) Phase 1 → Phase 2 → Phase 3 ✅ → Phase 4 (Notes) → Phase 5 (Scan) → Phase 6 (OCR) → Phase 7 (Shopping avancé) → Phase 8 (MCP)
``` ```
Rationale : les todos sont les plus simples (validation du socle), le shopping mobile de base est prioritaire pour usage réel, les notes viennent ensuite, le service OCR est posé avant d'en avoir besoin, puis les features avancées.