Files
xamxam/TODO.md
Pontoporeia 8f4f9d00b4 Refactor: Form improvements and cleanup: note contextuel, annexes, fichiers
1. fix: form improvements — multiple promoteurices, asterisks, contact dedup, bentopdf

- Multiple promoteurice (interne + ULB): both fieldsets now support dynamic
  add/remove rows (same pattern as lecteurs). field names changed to arrays
  (jury_promoteur[], jury_promoteur_ulb_name[]). Controllers accept both
  scalar and array forms for backwards compat.
- ULB promoteurice: when finality=Approfondi, asterisk appears on legend
  and first ULB input is marked required (JS toggle). Non-Approfondi hides
  the fieldset and clears values.
- Contact visibility duplication: removed redundant contact_public checkbox
  from admin add/edit forms (showContact=false). The 'mail' field in
  fieldset-tfe-info already serves this purpose.
- Asterisk fixes: website URL field now has asterisk+required when Site web
  format selected. Video/audio already had correct required handling.
- bentopdf link: clearer full URL 'https://bentopdf.com/' in both
  fichiers-fragment.php and form.php (edit mode)

2. refactor: merge Note contextuelle into Backoffice, add Lien BAIU, reorder fields

Backoffice fieldset now contains in order:
1. Note contextuelle (was standalone fieldset)
2. Points du jury
3. Remarques
4. Lien BAIU (moved from Métadonnées complémentaires)
5. Exemplaire physique BAIU
6. Exemplaire physique ERG
7. Contact interne


Métadonnées complémentaires now only has: pages, minutes, annexes checkbox.
Removed dead showContextNote variable from form.php, add.php, edit.php.
Controller baiu_link still mapped to input name "lien" (no migration needed).

3. refactor: move annexes checkbox from Métadonnées into Fichiers fieldset

- Removed 'Ce TFE comporte des annexes' checkbox from
  fieldset-metadata.php.
- Added annexes checkbox + conditional file input to
  fichiers-fragment.php. When checked, an HTMX swap reveals
  the 'annexes' file input (multiple, PDF or ZIP/TAR, max 500 MB).
- form.php seeds ['has_annexes'] for initial fragment render.
- Métadonnées complémentaires now only contains pages + minutes.
2026-05-13 17:59:13 +02:00

9.2 KiB
Raw Blame History

XAMXAM TODO

Completed

  • PeerTube integration — two parallel systems (backup direct upload + PeerTube API)

    • PeerTubeService.php — credentials CRUD + OAuth2 password grant + multipart upload to /api/v1/videos/upload
    • Migration 021_peertube_settings.sqlpeertube_settings table (singleton) + peertube_upload_enabled feature flag (default 0 = disabled)
    • actions/settings.phppeertube section handler (toggle + credential save)
    • admin/parametres.php — PeerTube section UI (instance URL, username, password, channel ID, privacy)
    • templates/admin/parametres.php — PeerTube settings form between SMTP and admin account sections
    • admin/partage/fichiers-fragment.php — shows <input type="file"> for video/audio when enabled, keeps TODO notice when disabled
    • ThesisCreateControllerhandlePeerTubeUpload() uploads video/audio to PeerTube, stores watch URL as thesis_files row
    • ThesisEditController — same handlePeerTubeUpload() method for edit workflow
    • templates/public/tfe.php — renders PeerTube iframe embed for files whose path contains /videos/watch/
    • AdminLoggerlogPeerTubeUpdate() audit method
    • Direct file upload fallback: when peertube_upload_enabled = 0, standard <input type="file"> + local storage works unchanged
  • Backoffice fieldset reorder — Note contextuelle merged in, Lien BAIU added, removed from Métadonnées

    • Backoffice order: Note contextuelle → Points du jury → Remarques → Lien BAIU → Exemplaire BAIU → Exemplaire ERG → Contact interne
    • Removed standalone "Note contextuelle" fieldset (now inside Backoffice)
    • Lien BAIU moved from Métadonnées complémentaires into Backoffice
    • Métadonnées fieldset now: pages, minutes, annexes only
  • Form fixes batch

    • bentopdf link clearer: "PDFs trop lourds ? https://bentopdf.com/" (full URL visible)
    • Multiple promoteurices: interne and ULB fields now dynamic (add/remove rows, same as lecteurs)
    • Contact visibility duplication removed from admin forms (showContact = false; mail field in fieldset-tfe-info covers it)
    • Asterisk corrections in files section: note_intention, website URL, video, audio all show red asterisk + required when non-admin
    • ULB promoteurice asterisk + required when finality=Approfondi (JS toggles <span class="asterisk">*</span> + required on first ULB input)
    • Controllers handle jury_promoteur and jury_promoteur_ulb_name as both scalar and array (backwards compat)
  • Fix just serve — justfile shebang recipes (deploy-env, reencrypt-password) used space indentation instead of tabs, causing "extra leading whitespace" parse error

  • PDF 100 MB limit + bentopdf mention

    • ThesisCreateController: MAX_PDF_SIZE = 100 MB; PDFs checked against it, other files still 500 MB
    • ThesisEditController: same per-PDF limit applied
    • fichiers-fragment.php: note d'intention and TFE hints mention 100 MB PDF limit + bentopdf.com link
    • form.php edit-mode new-files hint updated
    • file-field.php: added $hintRaw flag to allow HTML in hints
  • Format types: reorder, rename, add Image/Écriture

    • Migration 019: add Écriture
    • Migration 020: add sort_order column, rename Autre → Etc. / Autre, add Image, set display order (Écriture · Image · Audio · Vidéo · Site web · Performance · Objet éditorial · Installation · Etc. / Autre)
    • Database.php format_types query uses ORDER BY sort_order, id
    • fichiers-fragment.php uses ORDER BY sort_order, id; Image/Vidéo/Audio IDs resolved via name map
    • TODO: Vidéo + Audio — PeerTube API upload (notice shown in form for now)
  • Combined Format + Fichiers into HTMX-swappable block

    • partage/fichiers-fragment.php — new combined fragment: format checkboxes + fichiers fieldset that adapts based on selected formats (upload inputs / URL fields / both)
    • Route /partage/fichiers-fragment added to partage/index.php
    • admin/fichiers-fragment.php — admin-gated wrapper for the same fragment (sets admin_mode=1)
    • admin/format-website-fragment.php — admin-gated fragment for edit-mode website URL fieldset toggle
    • form.php — add/partage mode: replaced separate Format + Fichiers + website-url-fieldset with single #format-fichiers-block server-rendered via shared fragment
    • form.php — edit mode: Format checkboxes wire to admin/format-website-fragment.php#edit-website-url-fieldset (existing-file management untouched)
    • checkbox-list.php — added $hxInclude variable (defaults to 'this, #website-url-fieldset') so callers can customise included fields
  • TDD analysis + new test suites

    • Bug fixed: SearchController::handleSearch()$coverMap undefined variable + never populated for search results
    • ShareLinkTest (13 tests) — generateSlug, all validateLink branches, verifyPassword, incrementUsage, objet_restriction
    • PureLogicTest (31 tests) — TfeController helpers (meta, OG image, jury split, captions), ThesisCreateController helpers (autofocus, detectFileType, authorSlug), ThesisEditController::buildFileSizeInfo, ExportController CSV column consistency, SearchController coverMap regression
    • Private helpers promoted to protected in TfeController, ThesisCreateController, ThesisEditController to enable subclass-based testing without reflection
  • Form save audit + TDD

    • createThesis() missing duration_pages/duration_minutes columns — fixed
    • ThesisCreateController not passing raw page/minute values to createThesis() — fixed (durationPages, durationMinutes extracted and passed)
    • FormSaveTest.php — 14 red-green tests covering create+edit round-trips for all fields
  • Language form improvements

    • Add Néerlandais as default language option (schema + migration 017)
    • language_autre conditionally required via HTMX fragment (replaced custom JS)
    • language_autre saved via getOrCreateLanguage() in both create and edit controllers
    • formData['languages'] wired in edit.php so checkboxes are pre-checked
    • duration_pages/duration_minutes saved in updateThesis() and read back in getThesisRawFields()
    • beforeunload-guard applied to add and partage forms too
  • Audit + fix direct PHP URL references blocked by nginx catch-all deny all

    • /request-access.php fetch in tfe.php/request-access
    • /media.php?path= in form.php (×2) and admin/recapitulatif.php/media?path=
  • Fix 403 on /language-autre-fragment.php from edit.php

    • Root cause: standalone root-level PHP file blocked by nginx catch-all deny all
    • Moved logic to partage/language-autre-fragment.php (shared include)
    • Added route /partage/language-autre-fragment in partage/index.php
    • Added admin/language-autre-fragment.php (AdminAuth gated, includes shared logic)
    • form.php picks URL based on $mode (partage vs admin)
    • Deleted public/language-autre-fragment.php; nginx unchanged
  • Merge banner images into cover images

    • Migration 016: copy storage/banners/*storage/covers/, insert thesis_files cover records, clear banner_path, remove banners dir
    • Remove banner fieldset from edit form (form.php)
    • Remove banner fieldset from student submission form (fieldset-files.php: rename to couverture)
    • Update ThesisEditController::save() — remove banner upload/removal logic
    • Update ThesisCreateController::submit() — remove handleBannerUpload call
    • Update Database::handleCoverUpload() — add webp support, raise limit to 20 MB
    • Remove Database::setBannerPath(), handleBannerUpload(), getThesisBannerPath()
    • Update Database::deleteThesis() / bulkDeleteTheses() — remove banner file cleanup
    • HomeController: batch-load covers for all items, remove banner_path fallback
    • SearchController::handleSearch(): batch-load covers, pass $coverMap to view
    • SearchController::handleStudentPreview(): load covers, pass $coverMap to partial
    • TfeController::resolveOgImage(): use cover file_type instead of banner_path
    • home.php: use only $coverMap (no banner_path fallback)
    • search.php: show cover thumbnail on result cards
    • student-preview.php: use $coverMap instead of banner_path
    • Migration applied and file moved to applied/
  • Remove required from all form inputs in admin add/edit

    • Introduced $adminMode flag in form.php (true when $mode is 'add' or 'edit')
    • Hidden "champs obligatoires" note in admin mode
    • All $required = true callers in form.php, fieldset-tfe-info.php, fieldset-academic.php, fieldset-licence-explanation.php, fieldset-files.php changed to !$adminMode
    • Hardcoded required HTML attributes in fieldset-tfe-info.php (synopsis, objet radios), fieldset-licence-explanation.php (access type radios), jury-fieldset.php (promoteur, lecteurs interne/externe) gated on !$adminMode
    • Dynamic JS ulbInput.required in jury fieldset also gated