From 16bab06b71fc99f926f12aa75ed551cd5b5d739f Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Tue, 19 May 2026 19:15:38 +0200 Subject: [PATCH] Multi-tenant (p.1) --- README.md | 16 +++++++++++++- docker/schema_family.sql | 11 ++++++++++ includes/config.php | 5 ++--- includes/db.php | 15 +++++++++++++ migrate.php | 46 ++++++++++++++++++++++++++++++++++++++++ settings.php | 45 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 migrate.php 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 "

🎉 Migration terminée ! Tu peux supprimer ce fichier.

"; +?> \ No newline at end of file diff --git a/settings.php b/settings.php index 9e2f38b..5bda503 100644 --- a/settings.php +++ b/settings.php @@ -35,6 +35,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } else { $action = $_POST['action'] ?? ''; + if ($action === 'update_family_info') { + require_once __DIR__ . '/includes/db.php'; + $currency = trim($_POST['currency'] ?? '€'); + $zone = trim($_POST['zone_scolaire'] ?? 'C'); + + $stmtSave = $pdo->prepare("UPDATE pf_foyer_settings SET currency = ?, zone_scolaire = ? WHERE id = 1"); + $stmtSave->execute([$currency, $zone]); + $success = "Paramètres du foyer mis à jour avec succès."; + } + if ($action === 'set_modules' && $family_id) { $all = ['calendar', 'budget', 'holidays', 'gifts', 'garage', 'memo', 'todo', 'groceries', 'calendar_ios', 'printvault', 'planka']; $enabled = array_values(array_filter($all, fn($m) => isset($_POST['mod_' . $m]))); @@ -440,6 +450,41 @@ require __DIR__ . '/header.php'; + + + +
+

👪 Configuration du foyer

+

Configurez les informations partagées par l'ensemble de votre foyer.

+ +
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ +

👤 Mon profil