# HomeHub — Plan de développement > Approche itérative : chaque phase livre quelque chose d'utilisable. > Stack : FastAPI · React/Vite/TS · PostgreSQL 16 · Docker Compose --- ## Phase 1 — Socle technique ✅ **Objectif** : environnement opérationnel, rien de métier, mais tout tourne. ### Backend - [x] Structure projet FastAPI (`app/api/`, `app/core/`, `app/models/`, `app/schemas/`, `app/services/`) - [x] Configuration SQLAlchemy 2.0 async + pool de connexions - [x] Création des schémas PostgreSQL (`todos`, `shopping`, `notes`) via Alembic - [x] Migration initiale : toutes les tables (voir spec section 3) - [x] Endpoint santé : `GET /api/health` - [x] Module media (`app/services/media.py`) : - [x] Validation des formats acceptés (JPG, PNG, SVG, WebP, WebM, M4A) - [x] Génération miniature Pillow : 150×150 (shopping), 300×300 (notes), 400×300 (inline) - [x] Sauvegarde `originals/` + `thumbnails/` sur le volume - [x] Endpoint `POST /api/media/upload` → retourne `{ file_path, thumbnail_path }` - [x] Endpoint `DELETE /api/media/{uuid}` → supprime original + miniature - [x] Middleware CORS pour réseau local `10.0.0.0/22` - [x] Configuration via variables d'environnement (`.env`) - [x] Dockerfile backend (Python 3.12 slim) ### Frontend - [x] Scaffold Vite + React 18 + TypeScript - [x] Tailwind CSS configuré avec les tokens Gruvbox (via `tokens.json`) - [x] Intégration `design_system/components/ui-kit.jsx` - [x] `@vite-pwa/plugin` configuré (Service Worker + manifest) - [x] `manifest.json` avec icônes iOS + Android - [x] Routage React Router v6 - [x] Layout de base : navigation mobile (bottom bar) + navigation laptop (sidebar) - [x] Dockerfile frontend (Nginx + proxy `/api/` → backend) - [x] Favicon maison (SVG Gruvbox orange) ### Infra - [x] `docker-compose.yml` avec 3 services (frontend, backend, db) - [x] Volume PostgreSQL persistant - [x] Volume uploads persistant (`/uploads/`) - [x] Fichier `.env.example` - [x] Script de seed (`backend/app/data/seed.py`) : 113 produits + 9 magasins --- ## Phase 2 — Module Todos ✅ **Objectif** : créer, lister, modifier, terminer et reporter des tâches depuis mobile et laptop. ### Backend - [x] `GET /api/todos` — liste avec filtres (domaine, statut, priorité, tags, période) - [x] `POST /api/todos` — création - [x] `PATCH /api/todos/{id}` — mise à jour partielle - [x] `DELETE /api/todos/{id}` — suppression - [x] `POST /api/todos/{id}/postpone` — incrémente postponed_count + décale due_date - [x] Schémas Pydantic : TodoCreate, TodoUpdate, TodoResponse - [x] Tests d'intégration (9 tests) ### Frontend Mobile - [x] Page Todos : liste des tâches en cours, groupées par domaine - [x] Bouton "+ Tâche" flottant → Modal création (titre + domaine + date + priorité + tags) - [x] Double-tap → Modal édition pré-rempli - [x] Swipe droite → marquer done - [x] Swipe gauche → actions (reporter 1j / reporter 1 semaine / supprimer) - [x] Badge compteur par domaine ### Frontend Laptop - [x] Vue tableau avec filtres : domaine, statut, priorité, période - [x] Formulaire complet (tous les champs) via Modal - [x] Double-clic sur titre → Modal édition - [x] Actions inline : ✓ done / +1j / +1S / ✕ supprimer --- ## 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) - [x] Champ `tags TEXT[]` sur les produits du catalogue (migration 006) ### 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) - [x] Bottom sheet multi-select pour l'ajout d'articles depuis le catalogue - [x] Stats d'achat dans le catalogue : dernier achat + intervalle moyen par produit - [x] Swipe gauche → modal édition (TodoPage + ShoppingPage) - [x] Tags sur les produits : chip-input dans CatalogueModal, recherche étendue aux tags - [x] Recherche article : `type="search"` supprime la suggestion URL iOS, `autoFocus` automatique - [x] Upload photo produit : support HEIC/HEIF, redimensionnement 500×500 max (ratio conservé), miniature auto - [x] Collage Ctrl+V photo dans CatalogueModal et TodoForm --- ## Phase 4 — Module Notes ✅ **Objectif** : saisie rapide de notes avec photo, audio et GPS depuis smartphone. ### Backend - [x] `GET /api/notes` — liste avec search full-text + filtres tags/catégorie - [x] `POST /api/notes` — création - [x] `PATCH /api/notes/{id}` — mise à jour - [x] `DELETE /api/notes/{id}` — suppression - [x] `POST /api/notes/{id}/attachments` — upload fichier (image/audio) - [x] `DELETE /api/notes/{id}/attachments/{att_id}` — suppression pièce jointe - [x] Compression image Pillow → WebP (service media partagé) - [x] Recherche FTS PostgreSQL français ### Frontend Mobile - [x] Page Notes : liste chronologique avec aperçu - [x] Bouton "+ Note" → formulaire rapide (contenu + tags) via Modal - [x] Bouton 📷 → Camera API (capture directe ou import galerie) - [x] Bouton 🎤 → MediaRecorder (enregistrement audio inline) - [x] Bouton 📍 → Geolocation API → affichage coordonnées - [x] Visionneuse photo inline + lecteur audio inline - [ ] Compression WebP côté client (Canvas API) — différé Phase 5+ - [ ] Waveform visuel enregistrement — différé Phase 5+ ### Frontend Laptop - [x] Grille notes avec vignettes photo - [x] Recherche full-text - [x] Filtres rapides : avec photo, avec audio, avec GPS - [ ] Vue carte pour les notes avec GPS (Leaflet.js) — différé Phase 5+ --- ## Phase 4c — Notes v2 : états de tuile + médias ✅ **Objectif** : refonte de l'interface Notes avec tuiles à 3 états, support vidéo, transcodage audio universel. ### Backend - [x] `ffmpeg` dans le Dockerfile backend — transcodage audio et vidéo - [x] `save_audio()` : transcode toute entrée (webm/ogg/m4a) → AAC `.m4a` — lecture Safari iOS garantie - [x] `save_video()` : stockage mp4/quicktime direct, webm → H.264/mp4 via ffmpeg - [x] `ALLOWED_VIDEO_TYPES` : mp4, webm, quicktime, m4v, 3gpp - [x] `GET /api/notes` : filtre `has_video` ajouté - [x] `POST /api/notes/{id}/attachments` : gère `file_type = "video"` - [x] `GET /api/admin/stats` : section `media.video` (count + size_bytes) - [x] Schémas Pydantic notes : `gps_lat/gps_lon` passés en `float | None` (fix `Decimal` sérialisé en string → TypeError JS) ### Frontend - [x] NoteCard à 3 états : **semi** (défaut, 3 lignes + actions) / **expanded** (markdown complet + médias) / **collapsed** (titre + date) - [x] Bouton toggle `fa-chevron-down / fa-minus / fa-chevron-right` dans le coin haut-droit de chaque tuile - [x] Renderer pseudo-markdown : `# ## ###`, `- * 1.` listes, `> citations`, `---`, `` **gras** *italique* `code` ``, ` ``` ` blocs - [x] Icônes méta sur la tuile : `fa-image` / `fa-microphone` / `fa-video` / `fa-location-dot` - [x] Bouton vidéo `fa-video` dans les actions de chaque note - [x] Lecteur `