# TODO - [x] Fix language-search-fragment: use searchLanguages() like tag fragment, remove broken predefined exclusion logic - [x] Both fragments now follow identical patterns - [x] Fix "Créer" button not appearing on language search: both language and tag inputs used name="q" in the same form, causing HTMX to submit the wrong (empty) value — renamed to unique names (language_search_q / tag_search_q) - [x] Exclude Français, Anglais, Néerlandais from language-search suggestions (handled by the checkbox list) - [x] Refactor file upload naming convention - [x] Create shared ThesisFileHandler trait (src/Controllers/ThesisFileHandler.php) - [x] New pattern: theses/{YYYY}/{YYYY}_{AUTHORS}_{TITLE_SLUG}/ - [x] COUVERTURE: single cover image in thesis folder (covers/ directory deprecated) - [x] NOTE_INTENTION: single PDF in thesis folder - [x] TFE_{XX}: main files, contiguous numbering 01+, hierarchy PDF > video > audio > subtitles > images > other - [x] Subtitles (VTT) placed immediately after their associated video in TFE sequence - [x] ANNEXE_{XX}: annex files, separate numbering 01+ - [x] Two-digit zero-padded numbering (sprintf('%02d', ...)) - [x] Update ThesisCreateController.php: use trait, new file handling - [x] Update ThesisEditController.php: use trait, new file handling - [x] Remove duplicate methods (generateAuthorSlug, sanitizeFilename, etc.) from both controllers - [x] Update Database.php: deprecate handleCoverUpload, remove banner_path from queries - [x] Update SystemController.php: remove banners/ stats - [x] Update schema.sql: remove banner_path column and view field - [x] Create migration 027_drop_banner_path.sql - [x] Update PureLogicTest.php: adapt detectFileType call signature - [x] All pure logic tests pass - [x] Fix license validation: only require license for non-admin when access_type_id=1 (Libre), not for Interne (2) or Interdit (3) — fixes share link submissions failing with "Veuillez sélectionner une licence" - [x] Add xamxam@erg.be mailto link at top of student (partage) form - [x] On validation error, append "envoyez un e-mail à xamxam@erg.be" to flash error message - [x] Preserve uploaded file names across validation redirects: store in session, display as warning on re-render so the student knows which files to re-select - [x] Obfuscate all email addresses and mailto: links as HTML decimal entities site-wide (EmailObfuscator class, applied in templates + Parsedown post-processing) - [x] Fix TFE and annexes files not saved in ThesisCreateController::submit(): call handleAnnexeFiles, fix file input name mapping - [x] Apply ALLOWED_MIME_TYPES/ALLOWED_EXTENSIONS validation in handleAnnexeFiles (same as handleTfeFiles) - [x] Fix handleAnnexeFiles to use correct $_FILES key ('annexes' not 'files') - [x] Add annexe handling in ThesisEditController::save() - [x] Relax 3-keyword minimum: admin mode (create) requires 1+, edit requires 1+, student (partage) requires 3 - [x] Add CSS for file preview items (.fp-item, .fp-thumb, .fp-icon, .fp-meta, .fp-name, .fp-size) so annexes/cover/note-intention previews wrap and display correctly - [x] Fix TFE file input accept attribute to include video/audio/archive extensions