diff --git a/README.md b/README.md
index abc859f..c50968b 100644
--- a/README.md
+++ b/README.md
@@ -133,12 +133,25 @@ Le cron tourne chaque minute et envoie une notification Discord à l'heure exact
---
+## 🔄 Mises à jour & Migrations SQL (Multi-Tenant)
+
+L'architecture de HouseHub isole chaque foyer dans sa propre base de données (`househub_f1`, `househub_f2`, etc.). Lors de l'ajout de nouvelles fonctionnalités impliquant des changements de structure SQL, il faut suivre une double procédure :
+
+1. **Pour les futures familles (Initialisation) :**
+ Mettre à jour le fichier `docker/schema_family.sql`. Ce fichier est lu par `register.php` à la création d'un nouvel espace.
+2. **Pour les familles existantes (Migration) :**
+ Créer ou mettre à jour le script `migrate.php` à la racine du projet. Ce script boucle sur toutes les bases existantes référencées dans `househub_meta.families` pour y injecter les requêtes `ALTER TABLE` ou `CREATE TABLE`.
+ - **Exécution** : Accéder à `https://votre-domaine.com/migrate.php` avec un navigateur.
+ - ⚠️ **Sécurité** : Pensez à supprimer ou sécuriser l'accès à ce fichier après exécution en production.
+
+---
+
## 🗺️ Roadmap de Variabilisation (Migration Multi-Tenant)
Afin de transformer complètement l'application héritée de Pacha Family en un produit générique et autonome pour chaque espace familial, les chantiers suivants doivent être menés.
🟢 Niveau 1 : Facile (Constantes et configurations globales)
-[ ] Configuration de base : Extraire la devise (CURRENCY) et la zone de vacances scolaires (ZONE_SCOLAIRE) du fichier config.php pour les stocker dans les paramètres d'espace en BDD.
+[x] Configuration de base : Extraire la devise (CURRENCY) et la zone de vacances scolaires (ZONE_SCOLAIRE) du fichier config.php pour les stocker dans les paramètres d'espace en BDD.
[ ] Filtres API Éducation Nationale : Rendre dynamique la zone de l'API (zones LIKE '%Zone C%' dans family-calendar.js) pour s'adapter à la région de chaque foyer.
[ ] Identifiant Planka : Variabiliser le project_id Planka par défaut écrit en dur dans planka/api.php.
[ ] Suppression des IDs statiques : Supprimer les IDs parents fixes (ID_ALEX = 2, ID_LAIA = 3) dans config.php au profit d'une lecture dynamique basée sur les utilisateurs réels de la famille connectée.
@@ -163,6 +176,7 @@ Afin de transformer complètement l'application héritée de Pacha Family en un
| Version | Changements |
| ------- | ------------------------------------------------------------------------------------------ |
+| v2.2.0 | Multi-tenant (p.1) : Paramètres dynamiques du foyer (€, Zone) via BDD + script migration |
| v2.1.0 | Module Planka : Kanban natif connecté à Planka via API proxy PHP |
| v2.0.0 | Module PrintVault : viewer 3D STL/3MF/GCode, stockage local, trajectoires GCode illimitées |
| v1.5.0 | Modules Todo (rappels Discord), Mémo, Courses (liste partagée) |
diff --git a/docker/schema_family.sql b/docker/schema_family.sql
index 7ef1d44..1b3bf9e 100644
--- a/docker/schema_family.sql
+++ b/docker/schema_family.sql
@@ -12,6 +12,17 @@ CREATE TABLE IF NOT EXISTS pf_users (
display_name VARCHAR(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+-- ─── Familles ─────────────────────────────────────────────────────────────
+CREATE TABLE IF NOT EXISTS pf_foyer_settings (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ currency VARCHAR(10) NOT NULL DEFAULT '€',
+ zone_scolaire VARCHAR(5) NOT NULL DEFAULT 'C',
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+-- Initialisation de la ligne unique par défaut
+INSERT IGNORE INTO pf_foyer_settings (id, currency, zone_scolaire) VALUES (1, '€', 'C');
+
-- ─── Personnes ────────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS pf_people (
id INT AUTO_INCREMENT PRIMARY KEY,
diff --git a/includes/config.php b/includes/config.php
index b22d89b..2d1c73b 100644
--- a/includes/config.php
+++ b/includes/config.php
@@ -1,8 +1,7 @@
exec("SET collation_connection = utf8mb4_general_ci");
+
+ try {
+ $foyer = $pdo->query("SELECT currency, zone_scolaire FROM pf_foyer_settings WHERE id = 1")->fetch();
+ if (!defined('CURRENCY')) {
+ define('CURRENCY', $foyer['currency'] ?? '€');
+ }
+ if (!defined('ZONE_SCOLAIRE')) {
+ define('ZONE_SCOLAIRE', $foyer['zone_scolaire'] ?? 'C');
+ }
+ } catch (\PDOException $e) {
+ if (!defined('CURRENCY')) define('CURRENCY', '€');
+ if (!defined('ZONE_SCOLAIRE')) define('ZONE_SCOLAIRE', 'C');
+ }
+ // ------------------------------------------------
+
} catch (\PDOException $e) {
if (!headers_sent()) { header('Content-Type: application/json'); http_response_code(500); }
die(json_encode(['ok' => false, 'error' => 'Erreur BDD : ' . $e->getMessage()]));
diff --git a/migrate.php b/migrate.php
new file mode 100644
index 0000000..3e3eb96
--- /dev/null
+++ b/migrate.php
@@ -0,0 +1,46 @@
+🚀 Début de la migration...";
+
+// 1. Récupérer toutes les bases de données des familles
+$stmt = $meta_pdo->query("SELECT name, db_name FROM families WHERE db_name != ''");
+$families = $stmt->fetchAll();
+
+$host = getenv('DB_HOST') ?: 'househub-db';
+$user = getenv('DB_USER') ?: 'househub';
+$pass = getenv('DB_PASS') ?: 'changeme';
+
+// 2. Boucler sur chaque famille
+foreach ($families as $f) {
+ $db_name = $f['db_name'];
+ echo "Mise à jour de la famille {$f['name']} (Base : $db_name) ... ";
+
+ try {
+ $fam_pdo = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8mb4", $user, $pass, [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
+ ]);
+
+ // 3. Injecter la nouvelle table
+ $sql = "
+ CREATE TABLE IF NOT EXISTS pf_foyer_settings (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ currency VARCHAR(10) NOT NULL DEFAULT '€',
+ zone_scolaire VARCHAR(5) NOT NULL DEFAULT 'C',
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+ INSERT IGNORE INTO pf_foyer_settings (id, currency, zone_scolaire) VALUES (1, '€', 'C');
+ ";
+
+ $fam_pdo->exec($sql);
+ echo "✅ OK
";
+
+ } catch (\PDOException $e) {
+ echo "❌ Erreur : " . $e->getMessage() . "
";
+ }
+}
+
+echo "
Configurez les informations partagées par l'ensemble de votre foyer.
+ + +