Files
xamxam/TODO.md
Pontoporeia 37111eaac4 fix: add missing remote DB migrations and deploy-migrate recipe
Four ALTER TABLE / CREATE TABLE statements were applied locally but never
deployed to the remote production database, causing:

- acces.php → 500: share_links.is_archived missing (ShareLink::listActive/listArchived)
- parametres.php → 500: smtp_settings.notify_email missing (SmtpRelay::getSettings)
- /tfe?id=N → redirect-to-home: thesis_files.sort_order missing (getThesisFiles ORDER BY)
- admin_audit_log table missing (AdminLogger::insertDb, best-effort but noisy)

Adds four pending migrations (008–011) covering all missing schema changes.
Adds 'deploy-migrate' just recipe to run migrations on the remote after deploy.
2026-05-05 11:04:52 +02:00

5.1 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

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

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