Commit Graph

154 Commits

Author SHA1 Message Date
a2nr d51c7da972 chore: bump version to v33 2026-10-01 13:29:12 +07:00
a2nr ed7e7d1b26 feat: tombol export/import bundle di content editor 2026-10-01 12:11:58 +07:00
a2nr 961d2a0ac2 feat: extractBundle — unzip client-side via fflate dengan validasi entry 2026-10-01 12:09:12 +07:00
a2nr 796fd47800 feat: exportBundle + importBundle per-file via endpoint existing 2026-10-01 12:08:07 +07:00
a2nr f1f0b57189 chore: tambah fflate untuk unzip client-side 2026-10-01 12:06:24 +07:00
a2nr ba1e7240f3 feat(offline-db): implement offline progress persistence and sync manager for lessons
- Add getProgress and getAllProgress to local IndexedDB SyncManager
- Support opportunistic background sync for lesson progress and quizzes
- Connect LessonManager to IndexedDB progress cache for offline lesson completion status
- Disable SSR for /lesson and /bab routes to ensure consistent client-side local storage
2026-09-16 22:19:53 +07:00
a2nr 53b704c7de fix(teacher): align student and teacher counters on progress tree view
- Count only distinct students for sub-chapter folder completion badge
- Separate teacher attempts from student counter on lesson header with a dedicated '+Y guru' badge
- Differentiate teacher rows with teacher icon and dashed styling
2026-09-16 20:15:20 +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 c765399715 feat(playground): implement synchronous interactive input for client-side C and Python
- Unbuffer C stdout via setbuf(stdout, NULL) so prompts flush before blocking on input
- Break Emscripten FS.read loop with justFinishedLine and upgrade float/%f to double/%lf for PicoC compatibility
- Provide reactive waitingForInput state with auto-focus, dynamic placeholder, and highlighted send button in ConsolePanel
- Enable full multi-step interactive stdin flow in browser execution mode via SharedArrayBuffer and Atomics
2026-09-14 04:13:08 +07:00
a2nr 0decd6ce86 fix(playground): resolve mobile layout overlap and missing console input
- Lock viewport and relative navbar in +layout.svelte on both mobile and desktop
- Remove static min-height and overflow-y overrides on mobile in +page.svelte
- Auto-collapse file tree and compact code toolbar on mobile
- Add safe-area padding and 200px mobile height in ConsolePanel.svelte
- Bump APP_VERSION to 32
2026-09-13 15:53:02 +07:00
a2nr c1cb60be1e feat(code-runner): implement client-side C and Python execution with offline mirror and COEP iframe embedding
- Add client-side code runner via Web Workers (PicoC for C, MicroPython WASM for Python)
- Support interactive stdin with SharedArrayBuffer and Atomics
- Implement offline database mirror using Dexie.js with opportunistic auto-sync
- Add execution mode toggle in Playground (Browser vs Server)
- Configure COOP, COEP, and CORP security headers in SvelteKit server hook
- Fix Velxio and Flowchart Nginx headers and add credentialless attribute to iframes
- Mount Nginx configs in podman-compose.yml for velxio and flowchart services
- Add unit and E2E Playwright integration tests (100% passed)
2026-09-13 10:14:51 +07:00
a2nr d0e4645c36 fix(playground): resolve desktop layout overlap and show velxio toolbar 2026-09-11 12:55:35 +07:00
a2nr 1f4217be76 fix(quiz): enforce 75% passing threshold, sync server progress, and persist attempt review
- Only show celebration overlay and top bar completed checkmark if quiz score meets 75% threshold (>= 0.75) and exercises are done
- Return is_done, state, and composite_percent in POST /lesson-progress for exercise and quiz submissions
- Synchronize frontend LessonManager state with authoritative server is_done response
- Add has_quiz_attempt check in routes/lessons.py and token_service to recognize existing attempts even when composite state is in_progress
- Update QuizTab to display persistent attempt review, score status, and explanation instead of retake prompt on page load/refresh
- Make QuizQuestionView finish handler async, await finishQuiz(), and disable submission buttons to prevent navigation race conditions
- Update local ordered_lessons completion state dynamically upon passing
- Add unit and integration tests covering response payload attributes and has_quiz_attempt API field
- Bump APP_VERSION to 30
2026-09-09 07:33:52 +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 17713303bb fix(review): address code review findings for dev to master merge
- Optimize N+1 queries in get_all_students_progress via bulk fetch
- Backfill legacy progress in migration 0005 and startup sync
- Use arrayBuffer in hooks.server proxy for binary payload safety
- Restrict postMessage targetOrigin from wildcard to window.location.origin
- Harden iframe polling in TeacherVelxioEditor and reduce frequency
- Improve markdown section extractor line-boundary detection
- Clean up child subprocesses on exception in CLI runner
- Add console.error in contentEditor catch blocks and parameterize repro script
- Configure sequential vitest execution to optimize test runs
2026-09-06 18:08:58 +07:00
a2nr 7d590e0f95 fix(content-editor): sync and auto-save velxio arduino draft on publish
- Auto-save dirty draft before publishing in ContentEditorManager so in-memory
  Velxio circuit/code changes are never lost when clicking Publish directly
- Add resolveRestoredContent and baseline tracking to velxio-manager so lesson
  view immediately reflects updated server code instead of stale localStorage
- Invalidate in-memory lesson and markdown caches on draft publish and file operations
- Update teacher content page publish button disabled condition to check saving state
2026-09-06 16:17:35 +07:00
a2nr e4ab058078 feat(velxio): improve teacher arduino toolbar, add expected_wiring template, and harden deployer board detection
- Add EXPECTED_WIRING block to set-arduino template and standalone expected-wiring feature in teacher content editor
- Reposition reload button to the far left inline with status dot, and shorten status text to 'Siap' / 'Menghubungkan...'
- Decouple transfer from save: replace 'Simpan ke Dokumen' with 'Pindahkan Hasil' and centralize document saving to top header save button
- Dynamically detect board FQBN from circuit in DeployTab with arduino:avr:uno fallback
2026-09-06 05:10:13 +07:00
a2nr 812ede0acc test(velxio): add comprehensive unit test suites for velxio-manager, hooks redirect, and backend markdown parsing 2026-09-05 18:06:19 +07:00
a2nr 032e7f29ae fix(teacher): fix CSS height collapse and flex layout in content editor arduino tab 2026-09-05 17:32:21 +07:00
a2nr 21ffb65e05 fix(frontend): handle /editor gracefully and enable desktopLayout for teacher arduino tab 2026-09-05 17:03:15 +07:00
a2nr c3fc8dc8f1 feat(teacher): integrate full Velxio editor with bi-directional circuit and code sync 2026-09-05 16:50:31 +07:00
a2nr da6d7e25d3 fix(quiz): pakai state eksplisit + keyed each agar opsi render konsisten
currentQuizQuestion dijadikan $state (bukan getter) yang di-sync lewat
_syncCurrentQuestion() tiap ganti soal, dan {#each} opsi memakai :key
option.id. Mencegah opsi 'hilang' 1 frame saat navigasi mcq<->flashcard.
Tambah test integritas shuffle (opsi tetap lengkap & id konsisten).
2026-08-30 10:55:14 +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 630f004834 fix(content-editor): slide preview mounting, reactivity loop fix & template sidebar
- Mount SlideCarousel secara dinamis di LessonContentView (#slide-mount-point)
- Fix infinite reactivity loop (effect_update_depth_exceeded) dengan menggunakan plain variable bukan $state untuk handle slideComponent
- Tambah auto-rendering (math, code, flowchart, circuit) saat slide berubah/expand di SlideCarousel
- Defensive try-catch unmount/mount dan eksplisit type ReturnType<typeof mount>
- Update sidebar feature template di /teacher/content (Layout, Set Soal bundle, Inline)
2026-08-29 13:28:13 +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 9087a77096 refactor(markdown): konsolidasi polyfill nodeCompat & hapus dependency dompurify
- CLN-01: Verifikasi dan konsolidasi polyfill worker_threads.markAsUncloneable ke helper nodeCompat.ts
- CLN-01: Dokumentasi mekanisme require-time (node-polyfill.cjs) vs import-time (nodeCompat.ts)
- CLN-02: Hapus dependency dompurify dan @types/dompurify yang tidak terpakai dari package.json
- Verifikasi seluruh test suite (13 test files, 165 tests) tetap 100% lulus
2026-08-28 11:12:39 +07:00
a2nr 2d557df061 fix(markdown): sanitasi DOMPurify, perbaikan parser flashcard & kompatibilitas SSR Node 20
- Mengganti sanitizer manual dengan isomorphic-dompurify dan hook whitelist/blocklist (BF-01 & BF-02)
- Memperbaiki parsing penjelasan flashcard non-MCQ agar mencari blockquote di seluruh body (BF-03)
- Menambahkan node-polyfill.cjs dan konfigurasi NODE_OPTIONS untuk mengatasi incompatibilitas worker_threads.markAsUncloneable pada Node 20 runtime (SSR blank screen fix)
- Menambahkan unit test keamanan embed (BF-04) dan parity tests dengan fixture backend (BF-05)
- Mendokumentasikan deduplikasi quiz tab pada detectActiveTabs (BF-06)
2026-08-28 05:24:44 +07:00
a2nr bb04245d85 feat: migrate markdown preview rendering to client-side SvelteKit 2026-08-26 19:32:28 +07:00
a2nr db4d15ba50 fix(quiz): render LaTeX/KaTeX pada opsi, pembahasan, & preview guru
- QuizTab: ganti use:renderMath (jalan sekali pas mount) dengan $effect
  yang jalan ulang autoRenderMath tiap konten kuis berubah — cover opsi
  MCQ aktif, review live, dan review hasil-load async (setelah refresh).
- QuizPreviewReadonly (content editor guru): tambah $effect autoRenderMath
  agar LaTeX di soal/opsi/penjelasan ke-render di pratinjau kunci jawaban.

autoRenderMath idempoten sehingga aman dijalankan berulang tanpa dobel render.
2026-08-23 13:15:54 +07:00
a2nr f78eaaca11 fix: regresi hapus folder tidak kosong, tambah test contentEditor
- Perbaiki pemanggilan deleteEntry di +page.svelte baris 531: argumen
  force=true tidak lagi diteruskan dengan benar setelah signature
  fungsi berubah (confirmCritical ditambah di tengah)

- Koreksi komentar dengan karakter Mandarin di content_editor.py baris 488

- Tambah test unit contentEditor.test.ts dengan 5 kasus:
  - deleteEntry force delete
  - deleteEntry confirm_critical untuk file kritis
  - deleteEntry default parameter
  - renameEntry standar
  - renameEntry confirm_critical

Fixes: hapus folder dengan isi tidak lagi gagal 409.
All tests: 119 passed.
2026-08-23 10:43:18 +07:00
a2nr 1659063784 fix(playground): view tab Arduino/Flowchart/Circuit mengikuti ruang kosong & tambah link Playground di menu burger
- playground +page: jadikan main.container flex-column + .playground-page flex:1
  agar memenuhi ruang sisa setelah navbar (sebelumnya height:100% resolve ke
  tinggi intrinsik karena parent display:block)
- pg-content: tambah flex-direction:column supaya flex:1 grow tinggi bukan lebar
- override :global .flowchart-container & .circuit-wrapper jadi height:100%;flex:1;
  min-height:0 (hilangkan min-height:400px / height:550px fix) agar melar
- Navbar: tambah link Playground di dropdown burger tepat di bawah Tema Gelap
- terverifikasi Playwright desktop(1280x800) & mobile(390x780): semua tab 98-100%
2026-08-23 09:27:11 +07:00
anggoro ffceb519be feat(content-editor): konfirmasi ganda file navigasi kritis & hapus narrow sidebar
- Tambah PROTECTED_BASENAMES (home.md, sub-home.md) dengan konfirmasi
  kedua saat rename/delete agar tidak merusak navigasi siswa (tidak
  bisa di-undo). Diteruskan ke renameEntry/deleteEntry di contentEditor.ts.
- Hapus fitur featureSidebarNarrow + CSS terkait (tidak dipakai).
- Footer & backend: penyesuaian rute/test content editor.
2026-08-23 08:18:02 +07:00
anggoro a1ccef2d71 feat(content-editor): tambah template Exp Wiring & buat iframe Velxio mengisi area
- Tambah FEATURE_TEMPLATES 'expected-wiring' (grup Penilaian) untuk
  menyisipkan blok ---EXPECTED_WIRING--- yang dipakai velxio-evaluator
  grading wiring (sudah diekstrak backend lesson_service.py).
- Perbaiki iframe Velxio tab Arduino tidak dinamis: tambah height:100%
  pada .velxio-tab-content agar mengisi tinggi area kosong di desktop & mobile.
2026-08-23 08:17:42 +07:00
a2nr c90a8787f7 feat(teacher-nav): tambah Edit Content & Progress di navbar, pindah route /progress -> /teacher/progress, perbaiki toolbar editor
- Navbar: item 'Edit Content' (/teacher/content) & 'Progress' (/teacher/progress)
  muncul hanya saat akun guru login, ditaruh di atas divider login/logout
- Pindahkan route /progress -> /teacher/progress (git mv) agar konsisten dg /teacher/content
- Hapus link Progress di Footer (sudah ada di navbar)
- Editor content: tombol Fitur (toggle sidebar) dipindah ke header samping Simpan/Publish,
  Simpan/Publish diubah jadi icon, hapus tombol panah floating di tepi & di header sidebar,
  tombol dock/undock & minimize dipindah ke pojok kanan (mode desktop)
- Bump APP_VERSION 28 -> 29
2026-08-22 21:30:06 +07:00
a2nr f7fa1c70c2 fix(content-editor): bersihkan tab saat pindah asset & perbaiki upload gagal 500
- Reset previewActiveTabs/previewSlides saat pindah ke asset & saat hapus
  file aktif, agar tab dinamis (C/Python/Circuit/Arduino/Flowchart) tidak
  menetap setelah berpindah konteks.
- Ganti Pillow Image.verify() dengan Image.load() di validasi upload asset.
  verify() false-positive CRC pada chunk IDAT PNG valid -> backend 500.
  load() cukup membuktikan file adalah gambar yang bisa di-decode.
2026-08-22 09:39:46 +07:00
a2nr daa813f511 feat(content-editor): remove Preview tab, load Circuit/Velxio/Flowchart components
- Remove Preview tab (preview already shown in left content panel)
- Circuit tab loads actual CircuitEditor component with extracted initial_circuit
- Velxio tab loads velxio iframe with embed mode
- Flowchart tab loads flowchart iframe
- C/Python tabs remain as read-only CodeEditor with extracted code
2026-08-21 23:46:15 +07:00
a2nr fbc8a3fb03 feat(content-editor): dynamic tabs for C/Python/circuit preview
Add dynamic chrome tabs based on previewActiveTabs from markdown parsing.
When teacher writes ---INITIAL_CODE--- or ---INITIAL_PYTHON--- blocks,
the corresponding C/Python tab appears with read-only code preview.

- Widen activeTab type to string for dynamic tab IDs
- Extract code blocks client-side from raw markdown body
- Render chrome tabs dynamically from allTabs derived state
- Auto-switch away from invalid tabs when preview updates
2026-08-21 23:27:37 +07:00
a2nr 0d299055b0 fix(content-editor): reuse WorkspaceHeader icons & CSS, make editor fill parent
- Replace inline SVGs with Unicode icons from WorkspaceHeader (⊞ ▽ △ ◀)
- Use shared .panel-btn / .panel-actions / .btn-float-toggle CSS classes
- Match .resize-handle and .panel-header styling from lesson page
- Make CodeEditor dynamically fill workspace at any height (flex + height:100%)
- Override .cm-editor max-height in content-editor to remove fixed 60vh cap
2026-08-21 22:26:36 +07:00
a2nr b75eb06346 feat(content-editor): dockable/floating workspace, mobile view modes, asset preview
- Floating/dockable editor panel with drag & resize handles
- Mobile view modes: hidden → 50% → 100% toggle cycle
- Mobile tree-first: show file tree when no file selected, back button to return
- Asset file preview with image display and copy-path button
- Touch support for drag and resize on mobile
- Fix missing closing div in asset preview section
2026-08-21 19:03:53 +07:00
a2nr 084eb71a71 feat(content-editor): tambah editor konten guru dengan draft & publish
Backend:
- Model ContentDraft + migration 0004_content_drafts
- CRUD draft: save, reload, preview, publish, discard
- Tree ops: create file/folder, rename, delete dengan draft cleanup
- Refactor _render_markdown_string() agar bisa render dari buffer
- Refactor teacher_auth ke modul shared (teacher_auth.py)
- Blueprint routes/content_editor.py (17 endpoint)
- Permission error handling di semua write operations
- Tambah Pillow ke requirements.txt
- Mount content/ & assets/ dari :ro ke :rw

Frontend:
- Page /teacher/content dengan panel tree + editor + preview
- ContentFileTree, LessonContentView, QuizPreviewReadonly components
- contentEditor.ts service layer & contentEditor.svelte.ts state manager
- CodeEditor support @codemirror/lang-markdown + sync code prop
- Tambah @codemirror/lang-markdown dependency
2026-08-21 15:55:21 +07:00
a2nr 16031fa728 fix(docs/api): hilangkan sync berulang di api_reference + UI API Reference di /docs
- routes/docs.py: pakai current_app, bukan create_app() per request — tidak
  lagi memicu DB sync ulang di setiap hit /docs/api-reference (dead code
  route_modules/rule_map dihapus)
- frontend: entry statis API Reference di sidebar /docs, fetch lazy
  /api/docs/api-reference, render method badge + auth + docstring
- test: 4 test yatim di test_teacher_bootstrap diberi marker unit;
  Makefile test-stats kini menampilkan count per marker + orphan (harus 0)
- docs_service: hapus dead code _read_md_cached, sederhanakan cache-check
  _parse_frontmatter (satu getmtime, kondisi jelas)
- lesson_service: gabung pemanggilan bleach.clean dobel jadi satu dengan
  css_sanitizer opsional — hilangkan NoCssSanitizerWarning (7x)
- conftest: fixture autouse _isolate_database lewati isolasi untuk test unit
  supaya make test-unit tetap jalan tanpa DB walau DATABASE_URL diset

Verifikasi: unit 114 passed, full suite 239 passed (0 warnings) dengan
Postgres test, svelte-check 0 error, vitest 114 passed, docs-validate ok.
2026-08-17 16:37:30 +07:00
a2nr 429b23e9b8 fix(docs): frontend load must fetch /api/docs (not /docs) for SSR proxy
- hooks.server.ts only proxies /api/* to Flask (strips /api prefix)
- load() fetching /docs (no /api) caused SSR recursion/500
- Revert to /api/docs so proxy reaches Flask /docs route correctly
- selectDoc client fetch already uses /api/docs (correct)
2026-08-17 13:05:59 +07:00
a2nr d243df898a fix(docs): correct API route prefix — strip /api to match Flask proxy convention
- Flask docs routes changed from /api/docs to /docs (no /api prefix)
  because hooks.server.ts proxies /api/* by stripping /api, so /api/docs
  reached Flask as /docs (404). Other routes (lessons, help) also lack /api.
- Frontend load functions now fetch /docs and /docs/<slug> (not /api/docs)
- Fixes 500 on /docs SSR (proxy ECONNREFUSED / 404 from stripped route)
2026-08-17 12:40:48 +07:00
a2nr 9c2563a2bf feat(docs): docs viewer, API reference generator, markdown rendering
- Add YAML frontmatter (title/order/category) to 13 docs/*.md files
- Add services/docs_service.py: mtime-cache, frontmatter parsing w/ fallback,
  bleach sanitize, path traversal protection
- Add routes/docs.py: GET /api/docs, GET /api/docs/<slug>, GET /api/docs/api-reference
- Register docs_bp in app.py
- Add frontend /docs + /docs/[slug] routes (sidebar nav + markdown render)
- Add frontend/src/types/docs.ts interfaces
- Add link from /help page to /docs viewer
- Add scripts/validate_docs.py: frontmatter + broken link validation
- Add elemes.sh docs-validate command

Endpoints documented in API reference: /quiz-attempts/<lesson>,
/sessions, /bab/<folder>, /compile/sessions, /lesson/<slug>.json + all 30 routes
2026-08-17 11:45:05 +07:00
a2nr 25269fca08 fix(quiz/progress): perbaiki temuan audit — btn:disabled, css mati, indentasi 2026-08-17 09:23:05 +07:00
a2nr 9aef612f01 feat(quiz/progress): pindah navigator ke quiz view, tampilkan guru di /progress, tambah 1 siswa, fix breakdown eval/diag
- Task 1: pindahkan .quiz-navigator & .quiz-controls dari QuizTab ke
  QuizQuestionView; refactor props jadi mgr: LessonManager; CSS ke lesson.css.
  Navigator+kontrol kuis selalu terlihat di mobile walau workspace hidden.
- Task 2: get_all_students_progress tidak filter role guru; field role per row;
  badge 'Guru', bulk-action & empty-state & ringkasan hanya hitung siswa.
- Task 3: endpoint POST /students/add (reuse StudentRoundTripRow +
  find_student_import_conflicts + run_student_import); validate_single_student_input;
  AddStudentDialog + addStudent(); import/export/bulk-delete CSV lama tetap ada.
- Fix (Opsi A): breakdown eval/diag hanya hitung MCQ (flashcard netral) —
  selaraskan dengan skor resmi FE; perbaiki tampilan eval:4/6 yg membingungkan.
  Tambah field type ke QuizAnswerPayload.

Test: backend 239 passed (termasuk test baru teacher-in-report, add-student,
breakdown-excludes-flashcards); svelte-check 0 error; build sukses.
version.ts 27->28.
2026-08-17 08:32:42 +07:00
a2nr 2d5f100808 feat(quiz): perbaikan refresh quiz + enhancement UI kuis
- QUIZ-01: beforeunload hanya kirim beacon (tanpa finalisasi state) sehingga
  Cancel dialog membatalkan reload dan quiz lanjut; beforeNavigate tidak lagi
  memfinalisasi untuk tipe 'leave' (full-page unload/reload); review
  disembunyikan untuk page_unload (display policy anti-eksploitasi)
- QUIZ-02: opsi MCQ tampil 2-kolom grid (single-col untuk <=2 pilihan,
  fallback 1 kolom di mobile sempit)
- QUIZ-03: hapus info "soal X dari Y / X dijawab" + progress bar dari
  workspace dan question view
- QUIZ-04: opsi tinggi workspace mobile hide/30%/50%/70%/full dengan
  stepUp/stepDown untuk swipe & tombol resize
- QUIZ-05: workspace flashcard hanya 2 tombol "Sudah Mengerti"/"Tidak
  Mengerti" (tracking understood), indikator di summary review

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-08-16 19:17:42 +07:00
a2nr 58cb35a01a feat(quiz): tag kategori diagnostik + breakdown evaluasi/diagnostik di kuis & report guru
- Backend parser (_parse_flashcards): deteksi marker ::diagnostic di baris sendiri -> category='diagnostik' (default evaluasi), strip dari tampilan.
- Persistensi: kolom answers_json (migration 0003) simpan ringkasan per-soal {question_id, selected_option_id, is_correct, category}.
- quiz_attempts: validasi/serialize answers_json + endpoint GET /quiz-attempts/<lesson> untuk review-after-refresh.
- quiz-session: hitung evalCorrect/evalTotal/diagCorrect/diagTotal/diagUnmastered; skor resmi = evaluasi saja.
- Frontend: QuizTab badge per-soal + breakdown 'Belum dikuasai'; progress guru tampil badge Eval/Diag per lesson.
- Content: pindahkan ::diagnostic ke baris sendiri (fix kerusakan fenced code/blockquote dari edit sebelumnya).
- Tests: unit parser kategori + payload answers.
2026-08-15 09:33:23 +07:00
a2nr 432a8c2eca fix: show lesson progress on sub-home /bab pages
The /bab/<folder> endpoint returned raw get_sub_home_data() output, so
lessons had no completed/locked fields and green checkmarks never
appeared. api_bab now reads the student token, injects progress via
get_ordered_lessons_with_learning_objectives (scoped to the folder's
sub-home.md), and computes lock status from prerequisites — matching
/lessons. The bab page load also forwards the student token, and tests
cover progress injection and prerequisite locking.
2026-08-14 05:23:50 +07:00
a2nr 7e17da46c2 fix(frontend): hide CircuitJS toolbar & menu bar in lesson embeds
Append &hideMenu=true to the circuitjs.html iframe src used by
renderCircuitEmbeds so lesson content embeds render clean without
the toolbar and menu bar. The embed path in CircuitEditor.svelte
is untouched, so the editor keeps its full toolbar.

Verified:
- Bundle contains embed URL (with hideMenu=true) and editor URL
  (without) as separate variants
- svelte-check: 0 errors
- /lesson/rangkaian_dasar returns 200 on the running stack
2026-08-12 07:49:34 +07:00