- Publish konten langsung menyinkronkan lesson registry dan merekomputasi
composite/state siswa bila jenis evaluasi (latihan/kuis) berubah, tanpa
menunggu restart server.
- TTL cache (`LESSON_LIST_CACHE_TTL`, default 30 detik) untuk daftar lesson
agar worker gunicorn lain ikut segar tanpa invalidasi lintas proses.
- Endpoint POST /content/sync-registry (teacher-only) + tombol Sinkronisasi di
/teacher/progress untuk menangkap perubahan konten di luar webapp.
- Notifikasi editor saat progress siswa dihitung ulang pasca-publish.
- `recompute_lesson_progress()`: skor historis tetap disimpan; state legacy
completed/scored tidak disentuh.
- Test unit (TTL cache + signature evaluasi) dan integrasi (publish recompute,
sync registry, endpoint auth) + dokumentasi.
Tanpa perubahan schema DB.
- Export siswa terpilih/seluruh + progress ke CSV round-trip (token tidak
pernah diekspor; teacher tidak ikut; urutan deterministik)
- Import preview all-or-nothing: siswa existing di-restore (nama+progress,
token lama dipertahankan), siswa baru dibuat dari student_id kosong +
token; conflict tidak menyebut raw token/digest
- Bulk delete multi-seleksi dengan validasi ketat (teacher terlindungi,
zero-delete bila ada ID bermasalah)
- fix(import): deteksi delimiter berbasis schema — menerima titik koma
(;) maupun koma (,), ekspor tetap ';' + BOM; header tab/campuran ditolak
dengan pesan jelas (regresi: file Excel/Sheets kini bisa diimpor)
- refactor: progress_status.py — kontrak status legacy tunggal dipakai
storage PG, export, dan import; report siswa hanya role student
- UI /progress: dialog import/export + bulk delete, selection store,
respon import tanpa raw token; APP_VERSION 22 -> 26
- ops: ORIGIN env var di podman-compose.yml
- docs: README section 9 (workflow round-trip + delimiter) dan
docs/11-database-migration (kelola siswa via round-trip CSV)
- test: parser round-trip (45), repositories, route management (24,
PostgreSQL), frontend 91, fixtures CSV valid/invalid