À la demande de Fabrice, j'utilise l'IA pour tenter de créer un nouveau module. Je vais appliquer la technique SDD (Spec-Driven Development ou d'eveloppement orienté par les spécifications). Cette technique consiste à élaborer des fichiers texte (généralement du markdown) dans lesquels on va spécifier tous les éléments contextuels nécessaires au développement d'un application. Ces spécifications doivent être rigoureuses et vont servir à guide l'IA dans la génération du code.
Création d'un nouveau module
Je vais tester le SDD sur la création d'un nouveau module Vrai/Faux todd_vf très simple : une question est posée à l'observateur à laquelle on peut répondre "vrai" ou "faux". Il peut cliquer sur vrai ou faux pour répondre. L'observateur pourra aussi avoir accès au statistiques courantes de ce mini sondage.
Organisation
Nous allons utiliser deux fichiers :
- un fichier
sdd_architecture.mdde spécifications générales qui servira de maître dans le guidage de l'IA. Nous y mettons :- un descriptif du contexte ;
- le découpage du développement avec les différentes phases (qu'est-ce qui est de la responsabilité du l'agent IA et qu'est-ce qui relève de de celle du développeur) ;
- une description générale de l'architecture à respecter ;
- certains standards spécifiques concernant l'utilisation de certains composant. Nous y enjoignons aussi une documentaiton minimal sur le noyau de l'environnement dans lequel va évoluer l'extebsion TODD.
- un fichier
sdd_module_vf.mddédié aux spécifications du module. Il contiendra :- les métadonnées du module pour l'intégraiton à l'extension ;
- un descriptif rigoureux des fonctionnalités désirées ;
- le schéma de la base de donnée avec les propriétés sur lesquelles va reposer le fonctionnement du module ;
- un descriptif de l'interface d'administration ;
- un cas d'utilisation ;
- une liste de tâches à l'attention de l'agent IA ;
- une liste de critères d'acceptation ;
- une liste de contraintes à respecter
- des spécifications particulière liées au fonctionnement du modules (valeurs par défaut de certaines variables par exemple).
Comme on peut le voir, la rédaction de ces documents demande du temps, de la préparation et une certaine rigueur pour ne rien oublier.
Fichier maître sdd_architecture.md
Ce document définit les règles architecturales strictes pour la création de modules au sein de l'écosystème TODD (basé sur le framework MMI v3). Ce fichier sert de "langage de programmation Markdown" : un Agent IA (Gemini, Copilot, etc.) doit lire ce fichier et s'y conformer rigoureusement lors de la génération de code pour un nouveau module.
1. Contexte & Environnement Technique
- Framework Core : Framework PHP maison "MMI" v3.
- UI Admin et Vues publiques : Limitless 4.0 (Bootstrap 5).
- Icônes : Phosphor Icons (
ph-prefix). - Frontend Core : jQuery est massivement utilisé côté admin.
- Database : MySQL. Les tables doivent obligatoirement utiliser le préfixe
{DBPFX}(ex:SELECT * FROM {DBPFX}todd_contents). - Standard de référence : Le module
todd_informationest l'étalon-or MVC de l'écosystème.
2. Workflow Feature-First (SDD)
Le développement se fait en deux phases distinctes :
- Phase 1 (Agent IA) : L'Agent lit la spécification markdown du module (ex:
sdd_weather.md). Il génère toute la plomberie MVC : Modèle de données, Contrôleurs, Assets externes, UI d'Administration (formulaire + comportement de la modale). Le rendu public (view.php) reste basique (fil de fer). - Phase 2 (Développeur / Design) : Une fois la logique et les données accessibles, le développeur ou l'intégrateur se concentre exclusivement sur l'esthétique finale de la vue publique (
view.phpetview.css).
3. Architecture MVC Obligatoire
Chaque module todd_[nom] doit respecter l'arborescence suivante (exemple pris sur todd_information) :
plugins/todd/modules/todd_[nom]/
├── admin.php # Vue de l'UI d'administration (Formulaire + Conteneur Preview)
├── handler.php # Point d'entrée pour la validation et l'enregistrement
├── view.php # Vue publique (affichage sur la borne)
├── install.php # Transfert des éléments nécessaires au fonctionnement du module dans la base de données
├── controllers/
│ ├── admin.inc.php # Contrôleur d'admin (chargement CSS/JS, hydratation)
│ ├── payload.inc.php # Parsing du payload JSON et valeurs par défaut
│ └── view.inc.php # Contrôleur public (récupération DB, chargement CSS)
├── models/
│ └── Todd[Nom]Model.php # Classes PHP pour interagir avec la DB (séparation DB stricte)
└── assets/
├── css/
│ ├── admin.css # Styles purement spécifiques au formulaire métier
│ └── view.css # Styles de l'affichage public
└── js/
├── admin.js # Écouteurs d'événements jQuery pour l'UI d'admin du module
└── script.js # Logique front-end publique (si nécessaire)4. Règles d'Implémentation Spécifiques
4.1 Modèle (Model)
Toutes les requêtes SQL propres au module doivent être encapsulées dans la classe Modèle (ex: models/ToddInformationModel.php). Le handler.php et le view.inc.php ne font qu'appeler ces méthodes statiques.
4.2 L'Aperçu en Direct (Live Preview)
Ne réinventez pas la roue pour la mise à l'échelle de l'aperçu ! Utilisez les composants Core existants de TODD, notamment le composant global ToddPreview (plugins/todd/assets/js/pages/components/preview.js).
Mise en place HTML dans admin.php :
<!-- Côté Droit : Aperçu -->
<div class="col-md-7">
<div class="todd-preview-container" id="preview_bg_layer">
<div class="todd-preview-overlay"></div>
<div id="preview_scale_wrapper" class="todd-preview-scaler">
<!-- Contenu spécifique au module ici (ex: logo, textes) -->
<div class="todd-preview-content">
<div id="preview_message_text"></div>
</div>
</div>
</div>
</div>Le composant Core ToddPreview détectera ces classes et s'occupera de la mathématique (calcul du ratio 1920x1080 et de la propriété transform: scale()). Le fichier admin.js du module ne s'occupe QUE d'écouter les inputs (ex: keyup sur un champ texte) pour injecter la valeur dans le #preview_message_text.
4.3 Valeurs par défaut et Initialisation
Le contrôleur d'administration (admin.php via admin.inc.php) DOIT injecter les valeurs par défaut officielles du module dans un attribut data-defaults encodé en JSON sur la div racine :
<div
class="module-editor hidden"
data-module="todd_[nom]"
data-defaults="<?= htmlspecialchars(json_encode($default_payload)); ?>"
></div>Lors de la création d'un nouveau contenu, admin.js lira cet attribut pour simuler un payload vierge parfait via l'événement local :
$("#form_edit_content").trigger("todd:module:load", [defaultData, "todd_[nom]"]);4.4 Séparation des Assets
INTERDICTION FORMELLE d'écrire des balises <style> ou <script> en ligne dans view.php ou admin.php.
- Utilisez le gestionnaire d'assets Core dans les contrôleurs (
admin.inc.phpouview.inc.php) avec un cache-buster :
$css_v = filemtime(__DIR__ . '/../assets/css/view.css');
App::registerCSS('todd_[nom]_view', SITE_URL . 'plugins/todd/modules/todd_[nom]/assets/css/view.css?v=' . $css_v, false, false);
App::enqueueCSS('todd_[nom]_view');4.5 Installation
Le fichier install.php est exécuté lors de l'activation du module pour l'enregistrer dans la base de données. L'Agent IA doit générer ce fichier en respectant le pattern d'idempotence suivant. Il doit dynamiquement récupérer les variables de nom, label et icône depuis la section "Méta-données" de la spécification du module courant (ex: sdd_module_vf.md).
Modèle de code obligatoire pour install.php :
<?php
// Ces valeurs doivent être injectées dynamiquement par l'Agent selon la spécification du module
$module_code = 'todd_[nom]';
$module_label = 'Titre du module';
$module_icon = 'ph-icone-specifiee';
// 1. Vérification de l'existence du module pour éviter les doublons
$check = $db->get1x1("SELECT id
FROM {DBPFX}todd_modules
WHERE code = :code",
[':code' => $module_code]
);
// 2. Insertion si le module n'existe pas
if (!$check) {
// Calcul automatique du prochain ordre d'affichage
$maxOrder = $db->get1x1("SELECT MAX(sort_order) FROM {DBPFX}todd_modules") + 10;
$sql = "INSERT INTO {DBPFX}todd_modules (code, label, icon, sort_order, is_active, requires_moderation)
VALUES (:code, :label, :icon, :order, 1, 0)";
$db->dml($sql, [
':code' => $module_code,
':label' => $module_label,
':icon' => $module_icon,
':order' => $maxOrder
]);
}4.6 Gestion des Dates et Heures (Pickers)
Pour les modules nécessitant la sélection de dates ou d'heures (ex: todd_vf), il est impératif d'utiliser les composants natifs de la librairie Limitless 4.0 (Daterangepicker).
Règles d'implémentation :
- Dépendances : Enregistrez et enfilez
momentetdaterangepickerdans le contrôleur (admin.inc.php). - UI HTML : Utilisez un seul champ de type
textavec une icôneph-calendarpour l'interaction utilisateur. - Payload natif : Maintenez les champs cachés (
<input type="hidden">) séparés pour la date (YYYY-MM-DD) et l'heure (HH:mm). C'est ce que lira le modèle MVC natif. - Synchronisation JS : Dans
admin.js, écoutez l'événementapply.daterangepickerpour mettre à jour les champs cachés. Écoutezcancel.daterangepickerpour vider les champs.
Exemple de code dans admin.php :
<div class="col-md-12 form-group">
<label>Date et heure de révélation</label>
<div class="input-group">
<span class="input-group-text"> </span>
<input
type="text"
class="form-control daterange-time"
id="input_vf_reveal_datetime"
placeholder="Sélectionner une date et heure..."
/>
</div>
<!-- Payload natif pour le modèle MVC -->
<input
type="hidden"
name="vf_reveal_date"
id="payload_vf_reveal_date"
value="<?php echo htmlspecialchars($vf_reveal_date); ?>"
/>
<input
type="hidden"
name="vf_reveal_time"
id="payload_vf_reveal_time"
value="<?php echo htmlspecialchars($vf_reveal_time); ?>"
/>
</div>5 ANNEXE : Documentation Technique MMI (Tiria Cpanel v3)
Cette partie regroupe les règles essentielles, l'architecture et le fonctionnement du noyau MMI.
5.1 Standards de Code
Conventions de Nommage
- Classes :
PascalCase(ex:class MaClasse {}). - Fichiers de Classe :
camelCaseavec préfixeclass.(ex:class.maClasse.php). - Fonctions :
camelCase(ex:function maFonction() {}). - Variables :
camelCaseousnake_case(cohérence requise). - Droits (Constantes) :
PascalCaseavec verbe descriptif (ex:'ViewUsers','DoAction'). - Templates :
snake_case(ex:nom_de_page.php). - Contrôleurs :
snake_caseavec extension.inc.php(ex:nom_de_page.inc.php). - Scripts/Webservices :
snake_caseavec extension.ws.php(ex:nom_de_page.ws.php). - Javascript :
snake_caseavec extension.js(ex:nom_de_page.js).
Structures de Classe
- Nouveaux Objets : Toute nouvelle classe d'objet doit respecter la structure définie dans
class.example.php.sample.
Règles d'Écriture
- Indentation : Utiliser des tabulations, pas des espaces.
- Accolades : Ouvrantes sur la même ligne (
if($i == 1){). - Structure de contrôle :
caseetbreakau même niveau d'indentation.else/catchpeuvent être à la ligne.
- Espaces :
- Facultatifs après mots-clés/parenthèses (
if($i==1)ok). - Facultatifs autour des comparateurs (
$i==1ok). - Recommandés après les virgules dans les arguments (
func($a, $b)).
- Facultatifs après mots-clés/parenthèses (
- Tags PHP : Toujours utiliser
<?php, jamais<?(short tags désactivés). - Opérateurs Logiques : Utiliser
||et&&, jamaisORniAND. - Icônes : Toujours utiliser le format SVG
<svg class="icon"><use href="#ph-icon-name" /></svg>(pas de balises<i>).
5.2 Architecture & Pattern Override
Arborescence du Projet
Liste des dossiers à la racine du projet et leur rôle :
api/: Points d'entrée de l'API (génération de token, endpoints REST).assets/: Ressources statiques publiques (CSS, JS, images, polices).controllers/: Logique PHP des pages (appelés avant le rendu).includes/: Fichiers de configuration et d'initialisation du noyau (init.php,config.php).languages/: Fichiers de traduction (.po,.mo).libraries/: Classes PHP et bibliothèques tierces.logs/: Fichiers de log de l'application.plugins/: Modules d'extension (contiennent leur propre MVC).scripts/: Scripts autonomes, tâches CRON et WebServices (.ws.php).templates/: Vues et gabarits HTML/PHP.tmp/: Fichiers temporaires (cache, uploads en cours).uploads/: Stockage des fichiers persistants uploadés par les utilisateurs.
Pattern Override
MMI utilise un pattern "Core vs Override" pour permettre les mises à jour du noyau sans écraser les modifications projet.
Structure des Dossiers
core/: Contient les fichiers originaux du framework.- Racine ou dossier parent : Contient les surcharges (overrides) du projet.
Logique de Fallback (Cascade)
Le système charge les fichiers dans cet ordre de priorité :
- Projet (
templates/pages/ma_page.php) - Plugin (
plugins/mon_plugin/templates/pages/ma_page.php) - Core (
templates/core/pages/ma_page.php)
Cela s'applique aux :
- Contrôleurs (
controllers/) - Templates (
templates/) - Assets JS (
assets/js/) - Scripts/Webservices (
scripts/via.htaccess) - Librairies (
libraries/via checksfile_exists)
5.3 Fonctionnement du Noyau (Kernel)
Cycle de Vie d'une Requête
- Init :
includes/init.phpinitialise l'app, la DB, la session user. - Routing : Basé sur les paramètres URL :
?page=: Charge le contrôleur et le template correspondants.?param=: Paramètre secondaire (ex:edit,add).?option=: Paramètre tertiaire (ex: ID d'un item).
- Dispatch :
index.phpcharge le contrôleur (controllers/...).- Puis charge le header, le menu, la page (
templates/...), et le footer.
Routing des Scripts (AJAX/WS)
- Les scripts
.ws.phpdansscripts/sont appelés directement. - Si un script n'existe pas à la racine, le
.htaccessredirige versscripts/router.php. - Le routeur cherche alors dans les Plugins puis dans le Core.
Menu
- Tri : Les éléments de menu peuvent être ordonnés via la clé
order. - Administration : Tout élément avec un
order > 100sera automatiquement placé dans la section administration.
5.4 Système de Plugins
Les plugins sont situés dans plugins/{id_plugin}/ et étendent les fonctionnalités sans toucher au core.
Structure d'un Plugin
plugin.json: Métadonnées et dépendances.autoload.php: Chargé globalement si le plugin est actif (pour CSS/JS global, modifs menu).install.php,activate.php, etc. : Scripts de cycle de vie.controllers/,templates/,assets/: Surchargent ou ajoutent des pages/composants.
Intégration
- Pages : Un plugin peut déclarer être le "propriétaire" d'une page via la BDD.
- Menu : Le fichier
autoload.phppeut injecter des entrées dans le tableau global$sidebarMenu. - Composants :
App::loadComponent()cherche automatiquement dans les plugins actifs, ils doivent être nommésplugin_id.component_namepour êtres pris en charge.
5.5 Référence des Utilitaires (Classe App)
La classe App regroupe l'ensemble des méthodes utilitaires. Toute nouvelle fonction globale doit être ajoutée en étendant cette classe (dans libraries/client/class.app.php par exemple) et non plus dans des fichiers fnc.*.php.
Affichage & Traduction
App::__($s): Alias degettext.App::_e($s): Affiche une chaîne traduite.App::_a($s, $arg, $echo=false): Traduction avec arguments (sprintf).App::_ae($s, $arg): Affiche tradition avec arguments.App::_n($sin, $plu, $nb, $echo=false): Gestion des pluriels.App::my_strftime($format, $timestamp): Formatage de date (remplacestrftimedéprécié PHP 8.1+).App::localDate($timestamp, $format, $custom): Formate une date selon la locale du user.App::accentsToHTMLEntities($str): Convertit les caractères accentués en entités HTML.App::getTranslation($name, $lng): Récupère une traduction depuis un fichier JSON.App::getLogo($context, $mode): Récupère l'URL du logo approprié (SVG/PNG) selon le contexte.
Assets & Composants
App::registerCSS($name, $url, $path, $dep): Enregistre une feuille de style.App::registerJS($name, $url, $path, $dep): Enregistre un script JS.App::enqueueCSS($name): Ajoute le CSS à la file d'attente de chargement.App::enqueueJS($name, $place): Ajoute le JS à la file d'attente (header/footer).App::loadCSS($name)/App::loadJS($name): Charge directement un asset enregistré.App::registerJsVariable($name, $val)/App::registerJsVariables($arr): Passe des variables PHP vers le JS.App::minimize_css($css): Minifie une chaîne CSS.App::getExcerpt($text, $len): Tronque un texte proprement.App::buildCustomIconsSet(): Génère le sprite SVG des icônes demandées.App::loadComponent($name): Charge le contrôleur et les assets d'un composant.App::displayComponent($name, $params): Affiche le template d'un composant.App::enqueueIcons($name...): Ajoute des icônes à charger dans le set SVG de la page.
Templates & Rendu
App::getTemplate($tpl, $type, $subpath, $lng): Récupère le contenu d'un fichier template.App::getMailTemplate($tpl, $type, $lng): Récupère un template d'email.App::getPdfTemplate($tpl, $type, $lng): Récupère un template PDF.App::tplReplace($replace, $html): Remplace des variables{{var}}dans une chaîne.App::displayMenu($menu): Affiche un menu récursivement (supporte triorderet classes).
Système & Config
App::getOption($name, $default): Récupère une option (désérialisation JSON auto).App::setOption($name, $value): Définit une option (sérialisation JSON auto).App::writeLog($file, $msg, $level): Écrit dans les logs (avec rotation auto).App::getVariable($name): Récupère une variable globale (ou via Webservice).App::getPage($page): Récupère les infos d'une page (DB) et gère les métadonnées.App::printCode($var): Affiche un dump de variable pour débug (sauf en prod/si force).App::getArrayVariable($arr, $key)/App::setArrayVariable(...): Accès tableau via notation par point (dot notation).App::compareValues($v1, $op, $v2): Compare deux valeurs avec opérateur string (>, <, =, etc.).App::getSSEVariable($file, $var)/App::setSSEVariable(...): Échange de données pour Server-Side Events.
Sécurité & Utilisateurs
App::checkLogin($login): Vérifie si un login existe.App::checkPswd($login, $pass): Vérifie le mot de passe.App::checkRights($type, $right, $mask): Vérifie un droit spécifique dans un masque binaire.App::combineRightsStr($s1, $s2): Fusionne deux chaînes de droits binaires.App::getGravatar($email): Récupère l'URL Gravatar.App::tiriaCrypt($data, $key)/App::tiriaDecrypt($data, $key): Chiffrement AES-256-GCM.App::pswdgen($len, $specialchars): Génère un mot de passe aléatoire.App::pswdcreate($pswd): Crée un hash de mot de passe.
Divers
App::sendMail($title, $html, $txt, $dest...): Envoi d'email via PHPMailer.App::redirectResponse($res, $page, $type): Redirection avec message (AlertBox).App::exitRedirection($page, $param, $option): Redirection et arrêt du script.App::createSlug($text): Nettoie une chaîne pour URL.App::evalMath($formula): Évalue une expression mathématique.App::my_date_diff($h1, $h2): Calcule la différence entre deux dates.App::secondsToLisible($sec)/App::bytesToLisible($bytes): Formatage humain.App::imageFixOrientation($img, $file): Corrige l'orientation d'une image selon EXIF.
5.6 Règles de Développement Spécifiques
Plugins
- ID Plugin : Le nom de dossier (ID) d'un plugin doit impérativement respecter le pattern
^[a-z0-9_-]+$. - Nommage : Les composants d'un plugin doivent être appelés via
plugin_id.nom_composant.
Fonctions
- Dépréciation : Les fichiers
fnc.*.phpne doivent plus être créés. - Extension : Pour ajouter une fonction globale, surchargez la classe
Appdanslibraries/client/class.app.phpet ajoutez-y votre méthode statiquepublic static function myFunc(). Cela permet d'appelerApp::myFunc()partout.
5.7 Resources Externes
- Template Admin : Limitless 4 (Documentation)
- Framework CSS : Bootstrap 5 (Documentation)
Fichier pour le module sdd_module_vf.md
Ce document est une spécification destinée à guider un Agent IA (Gemini) dans la création formelle d'un module TODD. Lisez le fichier sdd_architecture.md pour les règles d'architecture applicables.
1. Méta-données du Module
- Code du Module :
todd_vf - Titre (label) : Vrai/Faux
- Icône Globale :
ph-question
2. Objectifs et Fonctionnalités
Ce module permet la réalisation de quiz à réponse unique (Vrai/Faux). Une image peut-être associée à la question.
- Interactivité :
- Un clic/touch sur les boutons
vraioufauxdans la vue publique permet de répondre à une unique question. L'utilisateur
- Un clic/touch sur les boutons
Lorsque la période du vote est terminée (basée sur une date et une heure décidée lors de la création du contenu de type Vrai/Faux), les statistiques sont affichées.
3. Schéma de Données (Modèle)
Le champ payload_json dans {DBPFX}todd_contents devra stocker les clés suivantes :
vf_question(string) : La question posée.vf_answer(string) : La réponse (vrai ou faux).vf_image_question(string) : L'image associée à la question.vf_image_bg(string) : L'image associée à la question.vf_color_text(string) : valeur HEX de la couleur du texte.vf_color_bg(string) : valeur HEX de la couleur du fond.vf_stats_true(int) : Nombre de réponses vraies.vf_stats_total(int) : Nombre total de réponses.vf_reveal_date(datetime) : Date de révélation.vf_reveal_time(time) : Heure de révélation.
Créez la classe models/ToddVfModel.php avec des méthodes statiques comme getPayloadById($db, $id) pour extraire spécifiquement le JSON.
4. Interface d'Administration (admin.php & admin.js)
L'interface de création/modification (colonne de gauche) comprendra :
- Des champs texte pour écrire la question et la réponse.
- Des boutons pour éventuellement uploader une image de question et une image de fond avec rappel du nom du fichier à côté du label (mettre
Aucunsi aucune image n'est sélectionnée). - Des color pickers pour décider des couleurs du texte et du fond.
- Un date picker et un time picker pour décider de la date et l'heure de révélation.
L'Aperçu en Direct (Live Preview)
L'aperçu situé dans la colonne de droite utilisera obligatoirement le composant ToddPreview.
<div class="col-md-7">
<div class="todd-preview-container" id="preview_vf_bg">
<div class="todd-preview-overlay"></div>
<div id="preview_vf_scale" class="todd-preview-scaler">
<div class="todd-preview-content">
<!-- Squelette statique pour la Phase Question -->
<div class="vf-question-container">
<h1 id="preview_vf_question">Question</h1>
<img id="preview_vf_image_question" src="" alt="" />
</div>
<!-- Squelette statique pour la Phase Révéler laRéponse -->
<div class="vf-answer-container">
<h2 id="preview_vf_answer">Réponse</h2>
<img id="preview_vf_image" src="" alt="" />
</div>
<!-- Squelette statique pour la Phase Statistiques -->
<div class="vf-stats-container">
<h2 id="preview_vf_stats">Statistiques</h2>
<div class="vf-stats-true">
<h3 id="preview_vf_stats_true">Vrais</h3>
<p id="preview_vf_stats_true_count">0</p>
</div>
<div class="vf-stats-false">
<h3 id="preview_vf_stats_false">Faux</h3>
<p id="preview_vf_stats_false_count">0</p>
</div>
<!-- graphique en barres -->
<div class="vf-stats-graph">
<div class="vf-stats-graph-true">
<div class="vf-stats-graph-true-count">0</div>
</div>
<div class="vf-stats-graph-false">
<div class="vf-stats-graph-false-count">0</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>Le Javascript (assets/js/admin.js) écoutera le changement de phase (Question, Réponse, Statistiques) et mettra à jour l'aperçu en conséquence.
Trois boutons sous le preview permettront de basculer entre les phases.
5. Cas d'utilisation
L'utilisateur voit à l'écran une question et deux boutons : Vrai et Faux. Il clique sur l'un des deux boutons. Le système enregistre la réponse et affiche les statistiques.
6. Instructions pour l'Agent IA
- Crée les 3 dossiers de base (
assets,controllers,models) et leurs sous-fichiers selon le standard MVC. - Dans
admin.php, utilise des classes Bootstrap 5 (Limitless). Construit le formulaire à gauche et l'aperçu dynamique à droite avectodd-preview-container. - Gère les requêtes jQuery dans
assets/js/admin.jspour hydrater l'aperçu et populer le payload lors de l'enregistrement. - Dans les contrôleurs, utilise absolument
App::enqueueCSS()et cache-buster. - Génère un rendu sommaire dans
view.php(Phase 2 viendra plus tard pour le CSS immersif). - Crée les fichiers CSS et JS nécessaires pour l'affichage public.
- Utilise les classes Bootstrap 5 (Limitless) pour l'affichage public.
Ne générez aucun CSS complexe pour le moment, concentrez-vous sur la connexion des données et la validité du payload.
7. Crittères d'acceptation
- Le module est fonctionnel.
- Le module est conforme à l'architecture MVC.
- Le preview dans l'admin est fonctionnel et correspond à la description.
- Étant donné qu'un utilisateur clique sur 'Vrai', le contrôleur public doit appeler le modèle et faire un UPDATE en base de données pour incrémenter
vf_stats_trueetvf_stats_total. - Étant donné qu'un utilisateur clique sur 'Faux', le contrôleur public doit appeler le modèle et faire un UPDATE en base de données pour incrémenter UNIQUEMENT
vf_stats_total. - Étant donné que l'utilisateur vient de voter, le contrôleur public doit afficher les statistiques (sans la réponse).
- Étant donné que la date et l'heure de révélation sont atteintes, le contrôleur public doit afficher la question, la réponse et les statistiques.
8. Contraintes
- Le module doit être conforme à l'architecture MVC.
- Le module doit être conforme aux règles d'architecture de TODD.
- Le module doit être conforme aux règles d'architecture de MMI v3.
- Le module doit utiliser les composants de Limitless 4.0.
- Le module doit utiliser les icônes de Phosphor Icons.
- Le module doit vérifier la validité de la date et de l'heure de révélation (postérieures à la date et l'heure de création du contenu).
9. Addendum
Utiliser ce payload pour l'initialisation du module :
{
"vf_question": "Posez votre question ici ?",
"vf_answer": "vrai",
"vf_image_question": "",
"vf_image_bg": "",
"vf_color_text": "#FFFFFF",
"vf_color_bg": "#333333",
"vf_stats_true": 0,
"vf_stats_total": 0,
"vf_reveal_date": "",
"vf_reveal_time": ""
}