Commit Graph

11 Commits

Author SHA1 Message Date
a2nr 087d338477 feat(quiz): izinkan guru melanjutkan attempt terminated dari jawaban tersimpan
Kebijakan termination tetap strict, tapi guru pegang override untuk kendala
tak terduga (false-positive blur dari dialog OS, browser crash, refresh
tak sengaja). Selain reset (siswa mengulang dari nol), guru kini bisa
memberi izin resume — siswa melanjutkan dari jawaban yang sudah tersimpan.

- Tambah kolom quiz_attempts.resumed_at (migrasi 0006) sebagai penanda izin
  guru melanjutkan attempt terminated
- Tambah endpoint teacher-only POST /resume-quiz-attempt — kontrak keamanan
  sama dengan /reset-progress (guru cukup student_id anonim, tanpa token siswa)
- Syarat: hanya attempt ber-status terminated yang bisa di-resume; submitted
  ditolak karena kuis sudah selesai normal
- has_quiz_attempt meloloskan attempt ber-izin sehingga gate one-attempt
  terbuka selama sesi lanjutan
- finalize_quiz_attempt menimpa row attempt sekali (status/skor/answers baru)
  lalu clear resumed_at; retry berikutnya kembali ke jalur idempotent normal
- Sinyal ke frontend siswa lewat quiz_resumable pada data lesson; laporan guru
  menampilkan badge "Dilanjutkan" dan tombol "Lanjutkan" untuk attempt
  terminated
- Frontend: restoreQuizSession() merekonstruksi sesi dari jawaban tersimpan per
  question_id, is_correct dihitung ulang dari source sebagai guard bila
  konten soal berubah; option_id tak dikenal dianggap belum dijawab
- Frontend: firstUnansweredIndex() menentukan soal awal sesi lanjutan;
  resolveQuizTabView() memusatkan keputusan view agar transisi resume dapat
  diuji Vitest
- UI siswa: panel "Lanjutkan Kuis" + snackbar mode lanjutan (sekali muncul).
  Attempt di-refetch segar sebelum sesi dimulai agar izin yang sudah dicabut
  guru tidak memulai sesi yang jawabannya akan terbuang
- Test: 16 integrasi backend (services/tests/test_resume_quiz.py), 9 unit
  quiz-session, 10 unit quiz-view
- Docs: alur resume + keterbatasan di 12-quiz-integrity.md, ringkasan di
  07-quiz-authoring.md, kontrak endpoint di 02-backend-flask.md
2026-10-20 19:24:40 +07:00
a2nr f95365a6e3 feat(teacher): refactor progress into tree view and separate classroom management
- Redesign /teacher/progress into a folder-like tree view (sub-bab -> lesson -> completed students)
- Create /teacher/classroom for student management (import/export CSV, add, bulk delete)
- Enrich /progress-report.json API response with sub_bab, sub_bab_title, and sub_bab_list
- Add Classroom navigation item to teacher navbar menu
2026-09-15 04:51:35 +07:00
a2nr 9bfecfbcab feat(student-management): sync imported progress with composite model and add inline expected format to CSV headers
- Sync imported progress (completed, scored, done, reset) to composite progress model and recompute composite_percent
- Prevent caching of /progress-report.json with Cache-Control: no-store and frontend cache-busting timestamp
- Provide inline expected format guides in exported CSV lesson headers (e.g. [completed], [<earned>/<total>], [done:<1|0>:<earned>/N])
- Support robust slug extraction from formatted headers in CSV roundtrip import with full backward compatibility
- Add example composite lesson (exercise + quiz) in examples/content/dasar/composite_test.md
- Add comprehensive unit and integration tests covering progress synchronization, header formatting, and roundtrip workflows
2026-09-08 19:01:33 +07:00
a2nr 41c434f064 feat(progress): composite scoring, roundtrip CSV grammar, and report export
- Integrate diagnostic and evaluation MCQ scoring in quiz sessions
- Extend round-trip CSV grammar with `done:<ex>:<earned>/<total>` and `RESET`
- Fix completed count aggregation in repositories to include 'done' state
- Update progress report CSV export to output composite scores per lesson
- Add comprehensive test coverage for scoring, CSV round-trip, and exports
2026-08-30 04:12:23 +07:00
a2nr 467b146988 feat: unified lesson progress — composite score & /api/lesson-progress
- composite score: exercise 70% + quiz 30%, done ≥75% (env LESSON_*)
- endpoint /api/lesson-progress menggantikan /track-progress + /quiz-attempts
- state baru 'done'/'in_progress'; deprecated per-lesson min:N% -> global threshold
- progress_status emit composite; teacher report single composite column
- frontend: submitLessonProgress/lessonProgressBeacon/fetchLessonProgress, QuizTab fix, SW url
- migration 0005; test baru: composite, lesson-progress routes, composite flow
2026-08-29 00:22:10 +07:00
a2nr ac37db5c91 feat(storage): migrasi penyimpanan CSV ke PostgreSQL (SQLAlchemy + Alembic)
- facade storage: csv_backend + postgres_backend, dipilih via STORAGE_BACKEND
- token disimpan sebagai HMAC-SHA256 digest (TOKEN_PEPPER), tanpa plaintext
- schema alembic 0001: users, access_tokens, lessons, student_progress
- importer CSV idempotent + dry-run + sparse model (not_started tanpa row)
- lesson registry: sync dari home.md (lesson hilang di-deactivate, bukan dihapus)
- routes progress/auth: report & reset via DB, validasi via token hash
- elemes.sh: dbupgrade/dbstatus/dbimport/synclessons/dbverify/dbbackup/dbrestore/dbexport
- podman-compose: service postgres (PG18), tokens_siswa.csv mount :ro
- frontend: api client + progress page; tests kontrak dual-backend + isolasi DB
- load-test: skenario database (locustfile_db.py)
- docs: 01-11 termasuk 11-database-migration.md (arsitektur & operasional)
2026-08-08 04:57:08 +00:00
a2nr 5f150da651 fix: progress path fix 2026-05-12 14:49:18 +07:00
a2nr ea3556d05f feat: implement interactive quiz with secure content protection, scoring, and teacher reset 2026-05-09 13:04:42 +07:00
a2nr 2b6ec21633 perf: fix race conditions with file locking and optimize backend latency 2026-05-05 22:57:19 +07:00
a2nr a41711fb54 security: implement gVisor sandboxing and harden API endpoints
- Menambahkan service 'compiler-worker' terpisah untuk isolasi eksekusi kode C/Python.
   - Mengintegrasikan gVisor (runsc) pada worker untuk mencegah RCE pada level kernel.
   - Menggunakan Gunicorn (4 workers) pada compiler-worker untuk mendukung concurrency.
   - Menambahkan otentikasi token wajib pada endpoint /compile dan laporan progres.
   - Memperketat CORS policy menggunakan environment variable ORIGIN.
   - Menerapkan secure_filename pada rute pelajaran untuk mencegah Path Traversal.
   - Mengubah volume mounting backend utama menjadi Read-Only (:ro) untuk perlindungan data.
   - Memperbarui proposal.md dan .env.example dengan standar keamanan terbaru.
2026-04-21 15:13:16 +07:00
a2nr d2b6d62b28 refactor to make it better 2026-03-25 09:39:51 +07:00