Files
home_hub/Consignes de Développement App Self-hosted.md
T
2026-05-25 21:27:13 +02:00

275 lines
16 KiB
Markdown

# **Cahier des Charges & Instructions de Développement : "HomeHub"**
Ce document sert de spécification technique de référence et de fichier d'instructions (prompt system) pour le développement de **HomeHub**, une application d'organisation personnelle auto-hébergée (PWA) conçue pour être déployée sur Proxmox 9 (Debian 13\) et intégrée à un écosystème local (Gitea, Home Assistant, Agent Hermes via MCP).
## **1\. Brainstorming & Choix Technologiques**
### **1.1. Architecture Globale**
L'application doit être légère, extrêmement réactive sur mobile, et facile à maintenir/sauvegarder sur un serveur Proxmox.
| Brique | Option A : Monolithe Go \+ Svelte (SvelteKit) | Option B : Backend FastAPI (Python) \+ Frontend React/Vite (PWA) | Option C : Full TypeScript (Node.js/NestJS \+ React/Vite) |
| :---- | :---- | :---- | :---- |
| **Avantages** | \- Très faible empreinte RAM. \- Binaire unique facile à déployer. \- Rapidité de Svelte sur mobile. | \- **Idéal pour l'IA (Hermes/Ollama via Python)**. \- API auto-documentée (Swagger). \- Écosystème de traitement d'image robuste. | \- Partage de types TypeScript (DRY). \- SDK MCP officiel disponible en TS. \- Écosystème PWA extrêmement mature. |
| **Inconvénients** | \- Écosystème de librairies d'IA/MCP plus limité en Go. | \- Deux services à orchestrer (Backend/Frontend). | \- Consommation RAM légèrement plus élevée que Go. |
| **Décision** | | **Retenue** (avec Docker Compose pour Proxmox) | |
*Pourquoi l'Option B ?* L'intégration d'un agent **Hermes** pour l'analyse de photos (via Vision LLM) et l'implémentation de serveurs MCP (Model Context Protocol) s'alignent parfaitement avec l'écosystème Python (FastAPI).
### **1.2. Base de Données**
Le besoin mentionne "plusieurs bases SQL" pour séparer les domaines.
* **Option retenue** : Une seule instance de **PostgreSQL** (hébergée en conteneur) avec une séparation logique par **Schémas** (schema users, todos, shopping, notes, calendar, kanban). Cela simplifie grandement les sauvegardes (un seul pg\_dump), permet des requêtes de jointure complexes si nécessaire (ex: lier un Todo à une Note), tout en garantissant une isolation stricte.
### **1.3. Synchronisation Calendrier (Google / Apple)**
* **Apple Calendar (iOS)** : Utilisation d'un serveur **CalDAV** minimal intégré au backend pour que iOS puisse s'y abonner nativement, ou synchronisation bidirectionnelle via l'API iCloud.
* **Google Calendar** : Flux d'authentification OAuth2 standardisé avec un worker asynchrone pour la synchronisation des modifications.
## **2\. Architecture Technique de l'Application**
\[ Smartphone / Laptop \] \<--- HTTPS \---\> \[ Traefik / OPNsense \]
(Réseau local 10.0.0.0/22)
┌─────────────────────────────────┐
│ Proxmox 9 VM / LXC │
│ ┌───────────────────────────┐ │
│ │ Docker Compose │ │
│ │ │ │
│ │ \[Frontend React/PWA\] │ │
│ │ \[Backend FastAPI\] │ │
│ │ \[PostgreSQL\] │ │
│ │ \[Redis \- Queue/Cache\] │ │
│ └───────────────────────────┘ │
└─────────────────────────────────┘
## **3\. Schéma de Base de Données (PostgreSQL \- Schémas Multiples)**
Voici la structure relationnelle cible pour guider le générateur de code :
\-- SCHEMA: auth (Gestion Utilisateurs)
CREATE SCHEMA IF NOT EXISTS auth;
CREATE TABLE auth.users (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
password\_hash VARCHAR(255) NOT NULL,
display\_name VARCHAR(100),
created\_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT\_TIMESTAMP
);
\-- SCHEMA: todos (Gestion des tâches)
CREATE SCHEMA IF NOT EXISTS todos;
CREATE TABLE todos.lists (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
user\_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
title VARCHAR(100) NOT NULL,
color VARCHAR(7) DEFAULT '\#3B82F6',
is\_shared BOOLEAN DEFAULT FALSE
);
CREATE TABLE todos.items (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
list\_id UUID REFERENCES todos.lists(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
due\_date TIMESTAMP WITH TIME ZONE,
postponed\_count INT DEFAULT 0, \-- Permet de suivre le nombre de décalages
status VARCHAR(20) DEFAULT 'pending', \-- pending, completed, cancelled
priority VARCHAR(10) DEFAULT 'medium', \-- low, medium, high
created\_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT\_TIMESTAMP,
updated\_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT\_TIMESTAMP
);
\-- SCHEMA: shopping (Liste de courses)
CREATE SCHEMA IF NOT EXISTS shopping;
CREATE TABLE shopping.lists (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
user\_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
is\_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE shopping.items (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
list\_id UUID REFERENCES shopping.lists(id) ON DELETE CASCADE,
product\_name VARCHAR(150) NOT NULL,
quantity VARCHAR(50) DEFAULT '1',
category VARCHAR(50), \-- Épicerie, Fruits, etc. (pour tri en magasin)
is\_checked BOOLEAN DEFAULT FALSE,
frequency\_score INT DEFAULT 0, \-- Pour l'auto-complétion intelligente
last\_purchased\_at TIMESTAMP WITH TIME ZONE
);
\-- SCHEMA: notes (Pense-bête & Références)
CREATE SCHEMA IF NOT EXISTS notes;
CREATE TABLE notes.items (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
user\_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
tags VARCHAR(50)\[\], \-- Array de tags pour recherche ultra-rapide
metadata JSONB, \-- Ex: {"store": "Brico Depot", "reference": "X12-34"}
created\_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT\_TIMESTAMP,
updated\_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT\_TIMESTAMP
);
CREATE INDEX idx\_notes\_tags ON notes.items USING gin(tags);
CREATE INDEX idx\_notes\_fts ON notes.items USING gin(to\_tsvector('french', title || ' ' || content));
\-- SCHEMA: kanban (Moins urgent)
CREATE SCHEMA IF NOT EXISTS kanban;
CREATE TABLE kanban.boards (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
user\_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
title VARCHAR(100) NOT NULL
);
CREATE TABLE kanban.columns (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
board\_id UUID REFERENCES kanban.boards(id) ON DELETE CASCADE,
title VARCHAR(100) NOT NULL,
position INT NOT NULL
);
CREATE TABLE kanban.cards (
id UUID PRIMARY KEY DEFAULT gen\_random\_uuid(),
column\_id UUID REFERENCES kanban.columns(id) ON DELETE CASCADE,
title VARCHAR(255) NOT NULL,
description TEXT,
position INT NOT NULL,
todo\_item\_id UUID REFERENCES todos.items(id) ON DELETE SET NULL \-- Lien optionnel
);
## **4\. Spécifications Fonctionnelles détaillées (Briques Applicatives)**
### **Brique 1 : Calendrier & Synchronisation Bidirectionnelle**
* **Interne** : Calendrier natif stocké en base de données.
* **Externe** :
* **CalDAV** : Exposer un endpoint CalDAV (/api/caldav/) pour permettre l'abonnement direct depuis iOS (sans passer par un tiers).
* **Google Calendar API** : Intégrer un mécanisme d'OAuth2 par utilisateur pour synchroniser un calendrier Google spécifique vers HomeHub, et inversement.
* **API** : Endpoints REST (GET /api/calendar/events, POST /api/calendar/events) utilisables par des scripts tiers.
### **Brique 2 : Gestion des Todos (Focus Mobile-First)**
* **Saisie Rapide** : Formulaire d'ajout rapide accessible en 1 clic sur mobile avec autocomplétion intelligente (ex: écrire "Rendez-vous dentiste demain 14h" doit parser automatiquement la date et l'heure via NLP léger côté backend).
* **Visualisation et Edition Mobile** :
* Vue liste épurée avec boutons d'action rapide : "Reporter de 1 jour", "Reporter à la semaine prochaine", "Marquer en retard".
* Actions par glissement (Swipe left to postpone, Swipe right to complete).
### **Brique 3 : Liste de Courses (Focus Grande Surface)**
* **Mode Magasin** :
* Affichage optimisé avec grands composants tactiles (facile à cocher d'une seule main).
* Tri automatique des articles par rayon/catégorie (ex: mettre tous les légumes ensemble) pour optimiser le parcours en magasin.
* Écran de veille désactivé lors de l'affichage de la liste de courses active (via la *Wake Lock API* du navigateur).
* **IA & Analyse Prédictive (Hermes / Vision)** :
* **Auto-remplissage Hebdo** : Algorithme basé sur la fréquence d'achat historique. Si le "Lait" est coché toutes les semaines, il apparaît pré-rempli dans la suggestion de la semaine.
* **Analyse de Photo (Hermes)** : Endpoint POST /api/shopping/analyze-fridge qui prend une image du réfrigérateur/placard, l'envoie à l'agent Hermes (ou LLM Vision local comme Llama-3-Vision) et renvoie la liste des ingrédients manquants détectés sous forme de suggestions de liste de courses.
### **Brique 4 : Notes de Référence (Pense-bête)**
* **Recherche Puissante** : Recherche Full-Text (FTS) PostgreSQL sur le titre, le contenu et les métadonnées (ex: chercher "courroie" ou "motoculteur" doit sortir la note instantanément).
* **Structure Métadonnées** : Possibilité de lier des paires clé/valeur spécifiques (Magasin d'achat, Référence, Lien) à chaque note.
## **5\. Intégrations Spécifiques (Hermes, Gitea, MCP, Home Assistant)**
### **5.1. Serveur MCP (Model Context Protocol) intégré**
Le backend FastAPI doit embarquer un serveur MCP. Ce serveur expose des "outils" (tools) réutilisables par des agents IA externes (comme votre agent Hermes ou Claude) :
* get\_todos() : Liste les tâches urgentes.
* add\_todo(title, due\_date) : Crée un todo.
* add\_shopping\_item(product\_name) : Ajoute un élément à la liste de courses.
* search\_notes(query) : Recherche dans les pense-bêtes.
### **5.2. Connecteur Gitea (https://gitea.maison43.duckdns.org/)**
* Permettre de lier un tableau Kanban ou une liste de Todos à un dépôt Gitea.
* **Webhooks** : Endpoint /api/webhooks/gitea pour recevoir les notifications de tickets (issues) Gitea créés ou fermés et les synchroniser automatiquement avec le Kanban ou la liste de tâches HomeHub.
### **5.3. Skill Agent Hermes**
* Exposer une API REST documentée en OpenAPI v3 (/api/openapi.json) permettant à Hermes d'appeler l'application pour ajouter des tâches à la voix ou par commande textuelle.
### **5.4. Home Assistant (10.0.0.2:8123)**
* Exposer des capteurs via des webhooks Home Assistant.
* Exemple : Notifier Home Assistant du nombre de tâches en retard pour l'afficher sur un dashboard mural (via REST API ou MQTT).
## **6\. Consignes de Code et d'Implémentation (Pour l'Assistant IA)**
**IMPORTANT : Respecte scrupuleusement ces règles lors de la génération du code de l'application.**
### **6.1. Backend : FastAPI (Python)**
* **Structure du projet** :
backend/
├── app/
│ ├── api/ \# Endpoints divisés par domaines (auth, todos, shopping, notes, calendar, mcp)
│ ├── core/ \# Configuration, sécurité, base de données (SQLAlchemy)
│ ├── models/ \# Modèles SQLAlchemy (utilisant les schémas PostgreSQL spécifiés)
│ ├── schemas/ \# Schémas Pydantic pour la validation
│ ├── services/ \# Logique métier (synchro calendrier, intégration Hermes Vision)
│ └── main.py \# Point d'entrée de l'application
├── Dockerfile
└── requirements.txt
* **Base de données** : Utiliser SQLAlchemy 2.0 (async) \+ Alembic pour les migrations. Respecter scrupuleusement la séparation en schémas Postgres (auth, todos, etc.).
* **Sécurité** : JWT pour l'authentification. CORS configuré pour autoriser les requêtes du réseau local 10.0.0.0/22.
### **6.2. Frontend : React \+ Vite \+ Tailwind CSS \+ TypeScript**
* **PWA Obligatoire** :
* Configurer @vite-pwa/plugin dans Vite pour la gestion du Service Worker (mise en cache agressive des assets pour l'utilisation offline).
* Créer un manifest.json propre avec icônes adaptées pour iOS et Android.
* Gérer un état "Offline" propre dans l'UI (avertir l'utilisateur si les modifications sont stockées localement en attente de synchronisation).
* **UX Mobile-First** :
* Utiliser des composants tactiles adaptés (hauteur minimale de clic : 48px).
* Transitions fluides (Framermotion ou CSS transitions).
* Support du Swipe (glissement de doigt) pour les listes d'items (Todos, Courses).
* **Thème Visuel** :
* Interface moderne, épurée, avec un mode sombre automatique (détection système).
* Palette de couleurs : Tons neutres et élégants (Ardoise/Slate, Bleu Cobalt pour les actions).
### **6.3. Docker Compose (Prêt pour Proxmox 9\)**
Créer un fichier docker-compose.yml complet à la racine contenant :
1. Le service db (PostgreSQL 16\) avec persistance des données dans un volume.
2. Le service redis (pour les tâches asynchrones de synchronisation de calendrier).
3. Le service backend (FastAPI).
4. Le service frontend (Nginx servant le build React).
## **7\. Plan de Développement Itératif**
Pour guider la création de l'application étape par étape :
### **Phase 1 : Socle technique & Authentification**
1. Mise en place de l'environnement Docker, configuration de la base de données PostgreSQL avec ses schémas.
2. Création du backend FastAPI avec authentification utilisateur (multi-utilisateurs et gestion du partage optionnel).
3. Initialisation du frontend React PWA avec routage et configuration du Service Worker.
### **Phase 2 : Brique "Todos" & "Notes" (Focus Mobile)**
1. Développement des endpoints CRUD pour les Todos et Notes.
2. Création de l'interface mobile-first pour l'ajout et l'édition rapide de Todos (avec gestion des reports de date simplifiés).
3. Développement de la recherche Full-Text pour les notes avec filtres par tags.
### **Phase 3 : Brique "Liste de courses" & IA**
1. Implémentation de la vue "Magasin" interactive (mode d'écran actif permanent via Wake Lock).
2. Développement du service d'analyse de fréquences pour l'auto-remplissage hebdomadaire.
3. Création de l'intégration avec Hermes/LLM Vision pour l'analyse d'image (upload de photo de frigo).
### **Phase 4 : Calendrier & Synchronisation Apple/Google**
1. Développement du serveur CalDAV interne (ou abonnement webcal).
2. Mise en place du flux OAuth2 Google Calendar et du worker de synchronisation en arrière-plan.
### **Phase 5 : Intégration Écosystème (MCP, Gitea)**
1. Création du serveur MCP pour exposer les outils d'organisation à l'agent Hermes.
2. Mise en place des webhooks Gitea pour l'intégration Kanban.