Files
xamxam/TODO.md
T

84 lines
13 KiB
Markdown

# TODO
> Last updated: 2026-09-18
> Context: CSS waste strategy: run unusedSymbols report-only (10-14) first to get go/no-go reclaimable-byte data; per-page split (u-x) second, reusing template inventory in docs/css-split-analysis.md.
## In Progress
## Pending
- [ ] #test-env-deploy-code-chown-regression test-env deploy-code --chown regression documented in README --context test-env
- [ ] #decide-fate-of-stray [!low] Decide fate of stray tracked commits.txt (6268-line git log dump) — Fate: left tracked; out of scope for history cleanup
- [ ] #history-cleanup-66-commits [!medium] History cleanup: 66 commits squashed to 29 on top of main; pre-squash backup at refs/backup/pre-squash-tip (tree 8649514e) + git bundle /tmp/xamxam-presquash.bundle
## Completed
- [x] #audit-all-docs-and [!high] Audit all docs/ and classify accurate vs stale
- [x] #rewrite-development-md-to-match [!high] Rewrite development.md to match current just dev / app/ layout / PHPUnit
- [x] #rewrite-deployment-md-to-match [!high] Rewrite deployment.md to match just deploy / /var/www/xamxam/ / backup
- [x] #update-database-md-to-current [!high] Update database.md to current schema (tags, share_links, migrations, xamxam.db)
- [x] #update-security-md-to-current [!medium] Update security.md to current state (xamxam paths, resolved items)
- [x] #update-search-md-to-current [!medium] Update search.md to current schema (tags not keywords)
- [x] #verify-fix-import-md-csv-format [!medium] Verify/fix import.md CSV format against current import
- [x] #update-bookmarklet-md-form-field [!medium] Update bookmarklet.md form field names (cc2r, duration_pages/minutes, drop contact_public)
- [x] #consolidate-archive-historical-analysis-docs [!medium] Consolidate/archive historical analysis docs
- [x] #fix-nginx-readme-md-title [!low] Fix nginx README.md title + export.md cross-refs
- [x] #fix-app-storage-readme-md-missing-database-spec-quick-schema [!medium] Fix app/storage/README.md (missing DATABASE_SPEC/QUICK_SCHEMA refs, wrong path)
- [x] #update-css-md-asset-structure Update CSS.md asset structure + build bundling
- [x] #correct-file-uploads-md-limits-banner Correct file-uploads.md limits, banner removal, FilePond transition
- [x] #rewrite-app-public-admin-readme-md-to-current Rewrite app/public/admin/README.md to current structure
- [x] #fix-nginx-docs-security-headers-md-csp-x-frame-options Fix nginx/docs/SECURITY_HEADERS.md CSP/X-Frame-Options
- [x] #create-docs-readme-md-index-classifying Create docs/README.md index classifying all docs
- [x] #standardise-all-log-filenames Standardise all log filenames to xamxam-{service}[-{date}].log convention
- [x] #add-server-side-log-rename Add server-side log rename script + just recipe (migrate-log-names) for pre-existing logs
- [x] #move-production-app-logs Move production app logs from storage/logs to /var/log/xamxam + add logrotate config
- [x] #add-date-dropdown-to Add date dropdown to admin log viewer to browse retained daily log files
- [x] #fix-heure-de-d-p-t Fix heure de dépôt (submitted_at) fausse dans backoffice récapitulatif: timezone Europe/Brussels + interpréter datetimes SQLite (UTC) comme UTC
- [x] #add-date-de-d-p-t Add 'Date de dépôt' (date_depot) column: DB migration + view + recap display
- [x] #csv-export-emit-date-depot CSV export: emit date_depot as Brussels-local date
- [x] #csv-import-parse-date-depot CSV import: parse date_depot as Brussels-local and convert to UTC storage
- [x] #default-exemplaire-baiu Default Exemplaire BAIU + ERG to true on student (partage) submission in ThesisCreateController, replicating admin add-form default
- [x] #m-style-links-on Style links on licences, charte, a propos pages (underline + accent hover)
- [x] #recherche-backoffice-par-identifiant Recherche backoffice par identifiant : ajouter t.identifier a la WHERE de getThesesList/getThesesListCount
- [x] #add-admin-only-route-to [!low] Add admin-only route to open Interdit thesis files from backoffice --context repo
- [x] #identify-which-templates-load [!high] Identify which templates load base.min.css and the page types — DONE inventory: docs/css-split-analysis.md. Key finding: head.php loads base.min.css on EVERY full page (App::render => templates/head.php unconditional). is the per-page-type mechanism (public/tfe/repertoire/content-page/not-found/form/admin/system). Centralize inventory in docs/css-split-analysis.md. Gates both split (w) and unusedSymbols corpus (11).
- [x] #collect-content-sources-for [!high] Collect content sources for the unusedSymbols pass — Built scripts/css-content-sources.mjs: buildCorpus() returns {corpus, sources, totalBytes, safelist, prefixes}. Gathers templates/public/src PHP + first-party js/app JS (vendor excluded). Mined 22 exact dynamic classes (status-*, log-*, input-error, active, disabled, btn--*, fhb-*, admin-icon-btn--*, status-published/pending/badge) + 5 suffix prefixes (status-access--*, toc-level-*, admin-import-log__item--*, admin-body, student-body) from status-badge.php, SystemController statusClass/logLineClass, class=<?=...?> ternaries. Documented docs/css-split-analysis.md. Feeds task 12 report.
- [x] #write-report-script-to [!medium] Write report script to compute unused selectors + reclaimable bytes — Built scripts/css-unused-report.mjs + just css-report recipe. Extracts class/id symbols per dist bundle, matches against buildCorpus() corpus + safelists, measures reclaimable bytes via lightningcss transform unusedSymbols (no stripping to disk). FULL RESULT: 216,383B total, ~6.2KB (2.9%) reclaimable. See docs/css-split-analysis.md table. Feeds task 14 go/no-go.
- [x] #flag-or-safelist-dynamic [!medium] Flag or safelist dynamic classes before trusting the report — Vendor + dynamic safelists shipped. Dynamic: 22 exact classes (status-*, log-*, input-error, active, disabled, btn--*, fhb-*, admin-icon-btn--*, status-badge/published/pending) + 5 DB/state suffix prefixes (status-access--*, toc-level-*, admin-import-log__item--*, admin-body, student-body). VENDOR: filepond--* and htmx-* prefixes excluded (runtime vendor JS assembly) — without these the report inflated to 26% (56KB); with them honest 2.9%. Report surfaces needs-review (kept, not flagged removable).
- [x] #summarize-findings-and-decide [!low] Summarize findings and decide whether to proceed to pruning — Decision recorded in docs/css-split-analysis.md. Data: 216,383B total, ~6.2KB (2.9%) reclaimable; base.min.css only 484B. SPLIT: NO-GO (base.css already well-used; split adds complexity for ~2% of one bundle) -> defer u-w-x-y. PRUNING: CONDITIONAL-GO on hand-verifiable dead set only, from SOURCE css files, re-run just css-report after each edit, never touch needs-review/vendor-prefix classes.
- [x] #archive-non-documentation-one-offs-from Archive non-documentation one-offs from docs/ (plans, incidents, proposals, assessments); keep only reference docs
- [x] #verify-every-retained-docs Verify every retained docs/ file against current repo; fix inaccuracies found
- [x] #document-app-key-env-first Document APP_KEY/.env + first admin setup in dev and deploy docs
- [x] #add-idempotent-provisioning-scripts Add idempotent provisioning scripts (local + server) for APP_KEY/.env and just provision/provision-server
- [x] #podman-compose-test-env podman compose test env for fresh Debian server --context test-env
- [x] #deploy-permissions-fix-ownership-break deploy-permissions: fix ownership break so just deploy-code can't cause HTTP 500
- [x] #fix-desync-deploy-code-exit-23 Fix desync: deploy-code exit-23 'Operation not permitted' — drop -p/-t (destination owned by www-data:xamxam, setgid; SSH user can't chmod), use -rlDz --size-only --context deploy
- [x] #deploy-permissions-sudo-prompt-can-t deploy-permissions sudo prompt can't accept input: ssh -t drops pty when local stdin isn't a TTY. Add scoped NOPASSWD sudo drop-in (deploy/xamxam-fix-permissions.sudoers) + deploy-sudoers recipe and wire into deploy --context deploy
- [x] #fix-raw-markdown-leaking Fix raw markdown leaking into TOC labels on licence/charte/about pages
- [x] #rewrite-cc2r-checkbox-label Rewrite CC2r checkbox label to 'J'adhère au Collective Commitment to Reuse (CC2r)' (italic, both Libre and Interne branches)
- [x] #fix-admin-contenus-page [!high] Fix admin contenus page slowdown: langues/mots-clés fragments ship 2.4MB HTML (737 tag rows + 217 lang rows, ~1960 inline SVG icons + per-row CSRF forms). Implement htmx infinite-scroll 'load more' (paged fragments via limit/offset) for both tables.
- [x] #reduce-contenus-initial-page [!high] Reduce contenus initial page size from 100 to 25 rows per table (payload ~160KB total vs ~534KB)
- [x] #add-admin-session-keepalive Add admin session keepalive endpoint /admin/session-keepalive.php (204, gated, refreshes admin_last_activity)
- [x] #add-admin-session-keepalive-js-activity-driven-throttled Add admin-session-keepalive.js: activity-driven throttled ping (5min), visibility-aware, wired into admin-entry
- [x] #update-docs-security-md-to-document Update docs/security.md to document activity-driven keepalive vs navigation-only timeout
- [x] #add-test-for-session Add test for session keepalive endpoint auth gating + activity refresh
- [x] #raise-admin-idle-timeout Raise admin idle timeout 30min -> 4h for long-form encoding; keep absolute 12h
- [x] #fix-never-firing-session-id Fix never-firing session ID rotation (modulo on absolute age); use admin_last_rotation + interval
- [x] #decouple-rotation-interval-30min Decouple rotation interval (30min) from idle timeout constant
- [x] #update-docs-security-md-deploy-server-sh Update docs/security.md + deploy-server.sh comment for new idle value
- [x] #extend-smoke-test-for Extend smoke test for rotation and 4h idle boundary
- [x] #fix-14-biome-check Fix 14 biome check errors: unsorted imports in scripts/css-*.mjs + unformatted CSS/JS files
- [x] #fix-peertube-resumable-chunked-upload [!high] fix(peertube): resumable chunked upload to stop 504 on large A/V — Admin MP4 upload fails at 100%: PHP relays whole file to PeerTube via one blocking multipart POST; PeerTube edge nginx returns 504 Gateway Time-out (see xamxam-error log filepond_peertube). Migrate PeerTubeService::upload() to resumable upload protocol with chunked PATCH so no single request exceeds the proxy timeout.
- [x] #fix-migrations-run-php-not-loading Fix migrations/run.php not loading composer autoloader (fresh-DB failure) — run.php loaded no autoloader; PHP subprocess migrations require src/ files whose sibling classes (Database->DatabaseMigrations) only resolve via composer classmap. Loaded autoloader in run.php and injected into subprocesses via -d auto_prepend_file, preserving $argv[1]=db contract. Verified: fresh schema.sql DB applies 47 migrations, exit 0, idempotent on 2nd run.
- [x] #backup-branch-from-current [!high] Backup branch from current state (backup/pre-history-cleanup)
- [x] #squash-main-history-into [!high] Squash main..@ history into logical commits — Groups: (1) session-timeout+GC; (2) env/provision+docs; (3) coverage/accents; (4) cover-images; (5) admin-cleanup-page; (6) test-env+deploy; (7) admin-index-css; (8) toc; (9) misc features; (10) migrations/justfile/biome. Fold TODO-only commits. Keep postlaunch intact.
- [x] #verify-final-tree-identical [!medium] Verify final tree identical to backup
## Deferred / Blocked
- [ ] #just-setup-backs-a [!medium] just setup backs a stale setup-dev.sh (clones php-live-reload, legacy admin/data/ dirs) — needs rewrite or removal
- [ ] #csv-export-writes-cc2r-exemplaire [!low] CSV export writes CC2r/Exemplaire columns that import's $cell mapping ignores — document or wire up
- [ ] #split-base-min-css-into-per-page [!medium] Split base.min.css into per-page bundles to reduce cross-page CSS waste — NO-GO (task 14): per-page split parked. base.min.css already well-used (only 484B/2.3% reclaimable); split adds build/template complexity for ~2% of one bundle. See docs/css-split-analysis.md decision.
- [ ] #define-per-page-type-css-bundle [!medium] Define per-page-type CSS bundle boundaries and entry files — Using the template->page-type map, decide which source files (components/*, utilities.css, reset, typography, etc.) belong in each page-type bundle. Document the mapping so shared-vs-page-specific splits are explicit and reviewable.
- [ ] #implement-per-page-bundles-in [!medium] Implement per-page bundles in scripts/build-css.mjs — Extend build-css.mjs with new bundle targets following the existing bundleCss/concatBundle pattern. Emit per-page-type .min.css outputs into app/public/assets/dist/. Keep base.min.css for pages not yet split.
- [ ] #wire-templates-to-load [!medium] Wire templates to load their page-type bundle instead of base.min.css — Update each template's <link> tags to point at the appropriate per-page bundle. Ensure no page loads CSS it doesn't need and that shared pages still get full styling.
- [ ] #measure-before-after-css-bytes [!low] Measure before/after CSS bytes shipped per page type — Moot: part of split stream which is NO-GO (task 14). Skip unless split is revived.
- [ ] #add-lightningcss-unusedsymbols-report-only [!high] Add lightningcss unusedSymbols report-only pass for base.min.css — SEQUENCING: do this (unusedSymbols report-only) BEFORE the per-page split (u). Reasoning: high priority, zero-risk diagnostic-only, produces reclaimable-byte go/no-go (14) against ~216KB baseline; if pruning is not worthwhile the split may not be either. Reuses inventory from v (docs/css-split-analysis.md). Start: 11 collect-content-sources.