# Livraisons par mois — xamxam ## Janvier 2026 (8 commits) ### Structure initiale - Schéma SQLite : tables theses, auteurs, formats, langues, tags, fichiers - Monorepo : organisation en dossiers (formulaire, templates, src, admin) - Justfile, .gitignore, documentation (READMEs) - Nginx config + déploiement fonctionnel - Système de recherche sécurisé ## Février 2026 (29 commits) ### Formulaire & soumission - Formulaire admin (ajout/édition TFE) - Formulaire étudiant via liens de partage (share links) - Structure formulaire : champs obligatoires, validation - Uploads de fichiers (stockage, affichage) ### Visibilité & accès - Système à 3 niveaux : Libre / Interne / Interdit - Protection par mot de passe des fichiers « Interne » - Authentification admin (login / session PHP) ### Pages statiques (début CMS) - Pages éditables : À propos (Markdown → HTML) - Templates header/footer, mise en page responsive - Cards en grille sur la page d'accueil ### Admin - Index admin : liste des TFE, pagination, stats - Export / import CSV - Navigation admin dynamique - CSS admin : composants réutilisables ### Sécurité - Auth guard pour le panneau admin - Correction des failles HIGH et LOW (TODO.SECURITY.md) ## Mars 2026 (74 commits) ### Contrôleurs & architecture - ThesisCreateController, ThesisEditController : extraction depuis add.php/edit.php (530 lignes → contrôleurs dédiés) - TfeController, SearchController, HomeController : extraction depuis les pages publiques - SystemController : unifie status + logs en un onglet système - App.php : classe fondation + flash messages unifiés ### Répertoire & recherche - Répertoire en 6 colonnes : années, orientations, AP, mots-clés, noms, compte - Filtres combinables (AP + mot-clé + orientation simultanément) - Filtres HTMX sans rechargement de page, URL partageable - Tri matched-first dans les colonnes de filtre - Popover étudiant·e (pré-rendu serveur, lazy load) ### Page TFE publique - Layout complet : auteur > titre > meta + synopsis > fichiers > jury - Jury interne / externe affiché séparément - Liens hypertextes vers le répertoire sur les métadonnées - Open Graph / Twitter Card meta tags ### Base de données - Migrations : superviseurs multi-rôles, tags renommés depuis keywords - Vues SQL (v_theses_full, v_smtp_active) - WAL mode pour SQLite - Index composites (is_published, year) pour la perf - Auto-migration au démarrage du serveur ### Sémantique HTML & accessibilité - Refactor sémantique complet de toutes les pages publiques - Head partagé, nav sémantique, aria-current, skip links - Status badges non dépendants de la couleur (WCAG 1.4.1) - Autofocus premier champ invalide (WCAG 3.3.1) - Sous-titres WebVTT pour vidéos (WCAG 4.1.2) - Cibles tactiles 44×44px (WCAG 2.5.5) ### CSS & design - Suppression de tous les assets externes (self-hosting) - Polices : Combined (titres) → Ductus, corps en BBBDMSans - Variables de couleur standardisées - Dark mode prefers-color-scheme - Header plus dense, recherche pleine largeur - Remplacement EasyMDE (333KB) → OverType (118KB) - Cache-busting par filemtime ### Admin - Pagination serveur (25/page) - Tri des colonnes dans l'index - Merge status + logs → system.php avec onglets fetch() - Paramètres : maintenance + compte - Dialogue d'import CSV inline - Gestion des fichiers dans l'édition TFE (couverture, TFE, etc.) ### Formulaire - Partials de champs de formulaire réutilisables (fieldset-academic, fieldset-metadata, etc.) - Jury fieldset partagé add/edit - Aide contextuelle Markdown dans le formulaire - Mode étudiant simulé dans l'admin (?mode=student) ### Email & SMTP - SmtpRelay : client SMTP natif (socket), AUTH PLAIN, TLS - Test SMTP, vérification des credentials à la sauvegarde - Champs from_name, notify_email - Email de notification admin après soumission ### Ops - Déploiement : scripts unifiés, justfile - Renommage Posterg → XAMXAM (code, nginx, docs) - Rate limiting sur les endpoints partage - Exclusion du fichier DB et des uploads du rsync ## Avril 2026 (207 commits) ### Uploads & fichiers - **FilePond** remplace les queues custom (495 lignes de JS supprimées) - Architecture upload asynchrone : process / revert / load / remove - Pool unique TFE (tous formats : PDF, vidéo, audio) - Barre de progression d'upload - Intégration **PeerTube** : upload API, OAuth2, embed iframe - Vidéos/audio auto-upload vers PeerTube quand activé - Chiffrement credentials PeerTube + SMTP (AES-256-GCM) ### Fragments HTMX - Fragments partagés admin / partage : formats + fichiers, licence, langue-autre - Fragments conditionnels selon les formats cochés (Site web → URL, Vidéo → upload ou PeerTube) - Aide contextuelle Markdown via HTMX - Fragments admin wrappés avec auth guard ### Formulaire - Partials de champs unifiés : text-field, select-field, checkbox-list - Jury : promoteurices multiples avec ajout/suppression dynamique - Jury ULB conditionnel (finalité Approfondi) - Annexes : checkbox + fichier conditionnel - Contact visible / contact interne découplés - CC4r → CC2r renommé - Identifiant TFE régénéré automatiquement au changement d'année - Validation inline des fichiers (MIME, taille) via HTMX ### Pages statiques CMS - À propos, Charte, Licence : Markdown → HTML, édition admin - TOC sticky dans la sidebar - Contenus-edit : OverType, auto-save, liens sidebar dynamiques - Contacts admin : grille 3 colonnes, ajout/suppression ### Accessibilité - aria-errormessage, aria-invalid, aria-describedby sur tout le formulaire - Cibles tactiles 44×44px minimum (WCAG 2.5.5) - Formulaire responsive mobile (colonnes empilées) ### Gestion des données - Mots-clés : recherche, rename, merge, delete dans l'admin - Langues : recherche, rename, merge bulk, dédoublonnage - Tri des colonnes Auteur et Accès dans l'index admin - Liens de partage : nom éditable, expiration, dialogue d'édition ### Sécurité - Obfuscation des emails en entités HTML (EmailObfuscator) - Content-Security-Policy, HSTS, SameSite cookies, COOP/CORP - Script de scan passif de sécurité - Rate limiting, flash messages sur partage - Corrections non-constant-time (hash_equals) ### CSS & refactoring - Architecture CSS en couches : reset → colors → typography → base → components - Suppression de toutes les classes BEM au profit de sélecteurs sémantiques - Tokens de design unifiés (couleurs, typographie, espacement) - Échelle fluide utopia pour typographie et espacement - Suppression du dark mode, unification des thèmes - Extraction de tous les styles inline vers CSS ### Logs & monitoring - Logging structuré pour les soumissions admin/partage - AdminLogger : JSON-lines ### Ops & déploiement - Déploiement automatisé (justfile) : code, dépendances, migrations - Vérification des permissions post-déploiement - Backups SQLite cron (horaire + quotidien) - Merge de toutes les migrations dans schema.sql ### Architecture code - Extraction des contrôleurs (create, edit, search, TFE, system) - Partials de formulaire réutilisables - Dispatcher + front controller (index.php) - Configuration externalisée (config/apropos.php → SQLite) ## Mai 2026 (156 commits) ### FilePond — corrections & hardening - Correction crash « can't access property main, n.status is undefined » - Tailles de fichiers en bytes (plus de confusion toInt('1GB') = 1) - Fichiers temporaires survivent au rechargement de page (session-track) - Guard no-JS : filepond_mode désactivé par défaut, fallback serveur - Relink fichiers orphelins (file browser + intégration FilePond) - Trash policy : suppression → tmp/_trash avec traçabilité DB - Storage prefix : theses/ → documents/ ### Autosave & brouillons - Brouillon automatique formulaire partage (HTMX POST/GET session) - Auto-save admin checkboxes avec toasts de feedback - Nettoyage périodique des brouillons orphelins (cron) - Contenus-edit : auto-save avec debounce, toolbar OverType ### Build & assets - **Biome** : linting + formatting CSS/JS - **Rolldown** : bundling JS par entrée - **LightningCSS** : résolution @import, minification CSS - Pipeline build orchestré (build.mjs) - Dev-watch avec chokidar-cli (reconstruction ~200ms) - dist/ pour les assets minifiés, .gitignore ### Gzip & extraction JS - Gzip activé dans nginx - ~730 lignes de JS inline → 15 fichiers externes - Modules : admin-logs, clipboard, pill-search, access-request ### Tests - PHPUnit setup : 228 tests, couverture 21,27% - Tests unitaires : Crypto, EmailObfuscator, SystemController, StudentEmail, TfeController - Tests intégration : Database, ShareLink, RateLimit - Tests validation : ThesisCreate, ThesisEdit, AutofocusField - PHPStan + PHP-CS-Fixer + Biome pour le linting ### Dépendances & modernisation - Composer.json avec autoloader - Parsedown → league/commonmark - Client HTTP custom → Guzzle - SMTP socket → PHPMailer ### Logging - **Monolog** : 4 canaux PSR-3 (app, admin, error, audit) - Rotation 30 jours, format JSON préservé - Remplace 4 systèmes de log distincts - LOG_LEVEL par variable d'environnement ### CSS — refactor architecture - Split en couches nommées (reset, colors, typography, base, components, utilities) - Un fichier par composant (links, focus, forms, tables, dialog, etc.) - Compatibilité backward (variables.css, common.css wrappers) ### UI / UX - SVG icons inline via helper PHP (icon()) — plus aucun pour les icônes - Build pipeline CSS/JS - Dev-watch avec reconstruction live - Scroll-position memory sur swaps HTMX (répertoire) - Transition + swap fluide sur le répertoire - Correctifs sécurité (open redirect, CSRF partage, gate session) ### Divers - Recap admin : sections → fieldsets, fichiers en table - FormBootstrap : DRY entre add/edit - Colonne thesis_status (two-phase commit lifecycle) - Déploiement : split deploy-code/deploy-deps/deploy-migrate, lockfile checksum - Export fichiers ZIP avec LINK.txt (URLs PeerTube) - Correctifs : identifier year-prefix mismatch, author name casing, contact découplage v2 - CSV import : AP aliases, OUI/NON sanitization - Rate limits relevés (30→300/min sur certains endpoints) ## Juin 2026 (82 commits) ### Icônes SVG - Migration complète → SVG inline via icon() helper PHP - 26 templates modifiés - 12 icônes SVG corrigées (fill="#000000" → fill="currentColor") - Icône recherche remplacée (Phosphor fill-based magnifying glass) ### Pages statiques & TOC - Refonte À propos / Charte / Licence : layout partagé en grille - TOC sticky → details/summary responsive (collapsible sur mobile) - Ancres de titres stables (CommonMark HeadingPermalinkExtension) - Styles liens standardisés ### Répertoire — polissage UX - Accordéon mobile pour les colonnes de filtre (≤640px) - Toggle, chevron, badge compteur de filtres actifs - Tri des colonnes : matched first, puis unmatched, puis alphabétique - Mots-clés : résultats viables en haut - Suppression de la chip bar mobile - Correction re-init accordéon après swap HTMX (bug DOM détaché) - Scroll colonnes répertoire : min-height: 0, overflow-y: auto - Scroll-position memory sur swaps HTMX ### Formulaire — accessibilité & robustesse - aria-errormessage, aria-invalid, aria-describedby sur tous les champs - Layout mobile responsive (champs empilés, 44×44px touch targets) - Autosave brouillon formulaire partage (session persistence) - Guard no-JS (filepond_mode désactivé par défaut) - Preserve fichiers temporaires FilePond après redirection validation ### Uploads & fichiers - PHP upload limits → 8GB (vidéos) - Nettoyage dialog : suppression doublons, hx-confirm sur delete - Type hint adminOld corrigé (string → string|array) ### Build & performance - Pipeline build CSS/JS (biome + rolldown + lightningcss) - Dev-watch chokidar-cli - Gzip nginx + extraction JS inline (730 lignes → 15 fichiers) - Biome lint fixes (CSS duplicate properties, JS arrow functions) ### Contenus & CMS - Auto-save avec OverType toolbar sur contenus-edit - Liens sidebar dynamiques (site ERG, code source) - Markdown cheatsheet : rendu réel dans la colonne d'exemple - Page Charte ajoutée (publique + admin) ### TFE — métadonnées - Durée : colonnes DB, champs formulaire, affichage XhYm - Finalité master affichée sur la page publique - Identifiant régénéré si mismatch année - Author name casing corrigé (COLLATE NOCASE, idHint lookup) - Suppression vidéos PeerTube lors de la suppression d'un TFE ### Sécurité - Open redirect fix : rejet des URLs protocol-relative (//evil.com) - CSRF sur retry-email POST - Gate partage fragments sur session share_active - Suppression App::verifyCsrf() mort ### Divers - Index SQLite pour requêtes langues/tags (contenus page) - Correctif logs capturés - Nettoyage .gitignore, vendor/ - Cleanup dialog - TFE page : CC2r + licence, formatage contact court - Recherche : filtres finalité + format, bouton Réinitialiser neutre