Files
xamxam/TODO.md
2026-05-07 12:35:31 +02:00

8.8 KiB

XAMXAM TODO

Duplicate TFE submission prevention (fixes)

  • DuplicateThesisException — typed exception carrying existing thesis metadata
  • Database::findDuplicateThesis() — year + author + normalised-title matching (exact, prefix, Levenshtein ≤10%)
  • ThesisCreateController::submit() — calls duplicate check before any DB write, throws DuplicateThesisException
  • AppLogger::logDuplicate() — dedicated log action (status: duplicate) for audit trail
  • App::flash/consumeFlash — extended to support warning type alongside error/success
  • admin/actions/formulaire.php — catches DuplicateThesisException separately; logs it; flashes HTML warning with link to existing thesis; repopulates form
  • partage/index.php — same catch block; plain-text warning (no admin link) surfaced on the student form via flash-warning banner; form repopulated
  • toast.php — renders toast--warning block
  • admin.css.toast--warning style + link colour
  • form.css.flash-warning style (partage form)

Admin audit logging

  • AdminLogger class — JSON-lines to /var/log/xamxam.log (prod) or storage/logs/admin.log (dev), mirrors to admin_audit_log DB table
  • admin_audit_log DB table — created in schema + migrated
  • share_links.is_archived column — archive replaces delete; stats preserved
  • ShareLink::archive() — new method; toggleActive returns new state; listActive() / listArchived() split; validateLink blocks archived slugs
  • actions/acces-etudiante.php — delete→archive, all actions logged (create, toggle, set_password, archive)
  • actions/publish.php — publish/unpublish logged
  • actions/delete.php — delete / bulk-delete / delete-all logged
  • actions/visibility.php — visibility changes logged
  • actions/export-csv.php — CSV export logged
  • actions/export-db.php — DB export logged
  • actions/edit.php — TFE edit logged
  • actions/formulaire.php — TFE add from admin logged
  • actions/tag.php — rename/merge/delete logged
  • actions/page.php — static page edits logged
  • actions/apropos.php — à-propos edits logged
  • actions/form-help.php — form structure edits logged
  • actions/access-request.php — approve/reject logged
  • actions/maintenance.php — maintenance on/off logged
  • actions/settings.php — formulaire toggles, objet types, SMTP update logged
  • actions/smtp-test.php — SMTP test logged
  • templates/admin/acces.php — archive button, archived links collapsible section
  • scripts/setup-server.sh — provision /var/log/xamxam.log with correct ownership

Multi-author support

  • ThesisCreateController::validateAndSanitise() — comma-split auteurice, sort alphabetically, build author entries array
  • Database::createThesis() — removed hardcoded author_id insert; authors linked via setThesisAuthors() instead
  • ThesisEditController::save() — authors sorted alphabetically before setThesisAuthors()
  • Database::findDuplicateThesis() — accepts array of author names, matches any shared author via IN + DISTINCT
  • File folder naming — slug generated from all authors alphabetically sorted (both create and edit)
  • v_theses_full GROUP_CONCAT — ORDER BY a.name ASC for deterministic alphabetical display
  • Migration 012_author_view_order.sql — rebuilds view with alphabetical author ordering

Fix remote 500s and broken TFE pages (post-deploy)

  • migrations/pending/008_share_links_is_archived.sqlALTER TABLE share_links ADD COLUMN is_archived (missing on remote; breaks acces.php)
  • migrations/pending/009_admin_audit_log.sqlCREATE TABLE admin_audit_log (missing on remote)
  • migrations/pending/010_smtp_notify_email.sqlALTER TABLE smtp_settings ADD COLUMN notify_email (missing on remote; breaks parametres.php via SmtpRelay::getSettings())
  • migrations/pending/011_thesis_files_sort_and_label.sqlALTER TABLE thesis_files ADD COLUMN sort_order / display_label (missing on remote; breaks every public TFE detail page)
  • justfile — added deploy-migrate recipe: SSHes to remote and runs php migrations/run.php

Replace browser dialogs with <dialog> modals

  • admin/index.phpalert() (no selection) → <dialog id="no-selection-dialog">; confirm() bulk publish/unpublish → <dialog id="bulk-confirm-dialog">; confirm() bulk delete → <dialog id="bulk-delete-dialog">; confirm() single delete → <dialog id="delete-thesis-dialog">; inline confirm() on Dépublier button removed (no confirmation needed for reversible action)
  • admin/tags.phpconfirm() merge → <dialog id="merge-tag-dialog">; confirm() delete → <dialog id="delete-tag-dialog">
  • admin/acces-etudiante.phpconfirm() delete link → <dialog id="delete-link-dialog">
  • admin/acces.phpconfirm() archive link → <dialog id="archive-link-dialog">
  • admin/parametres.phpconfirm() enable maintenance → <dialog id="enable-maintenance-dialog">; confirm() delete all TFE → <dialog id="delete-all-tfe-dialog">; admin password confirm() kept with TODO comment
  • admin/account.php — admin password confirm() kept with TODO comment
  • admin.css — added .admin-dialog--sm, .admin-dialog__alert, .admin-dialog__footer styles

Fix 403 on HTMX tab requests in parametres.php

  • AdminAuth::requireLogin() — now sets $_SESSION[SESSION_KEY] when accepting nginx Basic Auth credentials (was returning early without marking the session)
  • AdminAuth::isAuthenticated() — now falls back to PHP_AUTH_PW verification (same logic as requireLogin) so HTMX requests to system-fragment.php authenticate even before a session exists

Duplicate warning display fixes

  • toast-fragment.php — 204 guard now also checks warning; warning was silently discarded before
  • partage/index.php — warning stored as plain text (no pre-escaping); htmlspecialchars() applied once at render; was double-encoded before
  • partage/index.phpflash-warning div gets id + tabindex=-1; inline JS scrolls and focuses it on load
  • admin/footer.phphtmx:afterSettle listener focuses .toast--warning after HTMX injects the toast fragment

Sticky save/cancel buttons on edit page

  • templates/admin/edit.php — moved .admin-form-footer from bottom to top-right, right after <h1>
  • admin.css — added .admin-form-footer--sticky variant with position:sticky; top:0; justify-content:flex-end

Fix CSV importer column shift and data repair

  • Pad rows to expected column count to avoid offset warnings from short rows
  • Distinguish $yearRaw !== '' before intval() to handle empty-year rows correctly
  • Improve missing-field error message: lists which fields are missing, includes identifier/title snippet
  • Derive year from identifier when year column is empty
  • Auto-detect column-shifted CSV: when orientation/finality columns are empty but synopsis/context match known orientation/finality names, remap on import
  • Migration 013_fix_csv_column_shift.sql: move orientation from synopsis→orientation_id, finality from context_note→finality_id for already-imported theses
  • Migration 013_fix_remarks_keywords.php: move keywords from remarks→tags+thesis_tags for already-imported theses

Standardise répertoire filter column rendering

  • Centralise filter column rendering into a shared repFilterEntry() function
  • Define $filterColumns config array as single source of truth for the 5 filter columns
  • All columns (years, ap, or, fi, kw) now share identical fade/select/HTMX logic via the same code path
  • Fix single-valued FK columns (years, ap, or, fi): matched entries now use full intersection so clicking one entry correctly fades others with zero results
  • Fix column ordering: students between finalité and mots-clés

Standardise buttons with .btn base class

  • Create .btn base class in common.css: border-radius: 10px; padding: var(--space-xs) + background + cursor
  • Add .btn--primary (accent bg), .btn--secondary (--bg bg + border), .btn--sm, .btn--lg, .btn--danger, .btn--warning, .btn--success, .btn--ghost, .btn--muted, .btn--blue, .btn--yellow, .btn--green, .btn--red modifiers
  • Replace old button definitions in admin.css, form.css, tfe.css, file-access.css, system.css with empty alias comments
  • Update all PHP templates to use new .btn classes (btn btn--primary, btn btn--secondary, btn btn--danger, etc.)
  • Update border-radius on pagination buttons to 10px for consistency
  • Exclude storage/maintenance.flag from rsync deploy and git