Commit Graph

153 Commits

Author SHA1 Message Date
a2nr c356e234fa fix(frontend): resolve 26 svelte-check type errors
- add @types/node for hooks.server process/env types
- fix katex auto-render import path (contrib/auto-render)
- declare global Web Bluetooth API types in ble-deployer
- guard simApi null in CircuitEditor autosave interval
- default-type imports for CodeEditor/CircuitEditor
- make lesson slug getter non-nullable
- add expected_flowchart to LessonContent type
- key lesson workspace by slug; drop phantom onReset prop
- guard CodeTab render when lesson data is null
2026-08-09 12:28:17 +07:00
a2nr d602b0f642 feat(student-management): kelola siswa round-trip CSV + bulk delete (PG)
- 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
2026-08-09 07:29:19 +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 ec66d794a8 feat(playground): alur interaktif Run→prompt→jawab + file tree collapsible & dukungan .h
- store: normalisasi lifecycle sesi (runStatus/runSessionId/outputCursor/runError,
  stdinQueue tetap untuk kompatibilitas)
- +page.svelte: session controller — start, polling recursive setTimeout non-overlap,
  delta output via cursor, stop + cleanup unmount/generation counter
- ConsolePanel.svelte: input interaktif (onSendInput/onStop async, mode antrean vs kirim)
- FileTree.svelte: validasi rename (foo.h diterima di C), tombol + langsung mode rename,
  collapsible shell dengan handle persisten
- playground-files.ts: validasi nama file (basename, traversal, duplikat case-insensitive)
- api.ts/compiler.ts: client sesi interaktif
- tests: playground.test.ts + playground-files.test.ts
2026-08-02 14:14:53 +00:00
a2nr ddfbbb80f3 feat(playground): FileTree filter per bahasa — C dan Python dipisah
- FileTree menerima prop language ('c' | 'python', default 'c')
- hanya merender file dengan ekstensi yang cocok (.c atau .py)
- tombol + buat file dengan ekstensi bahasa aktif
- header menampilkan nama bahasa (C/Python), bukan generik 'File'
2026-08-01 22:39:20 +00:00
a2nr 152ca85718 fix(playground): Run mengonsumsi stdinQueue atomik via consumeStdin()
- runActiveFile() memanggil consumeStdin() (antrean + draft, digabung, dikosongkan)
- pesan info jika stdin kosong: program yang membaca input akan mendapat EOF
- hapus pembacaan consoleInput langsung yang menyebabkan baris hilang
2026-08-01 22:38:47 +00:00
a2nr a92411fa45 fix(playground): Kirim menambah baris ke stdinQueue, bukan hanya history 2026-08-01 22:36:52 +00:00
a2nr 1aef334d59 feat(playground): stdinQueue di store — enqueue/consume/clear atomik 2026-08-01 22:34:32 +00:00
a2nr dbed014474 feat(playground): multi-tab playground + FileTree + Console + stdin wiring to compile worker
- playground route: velxio/flowchart/circuit/code tabs with auto-save
- FileTree + ConsolePanel for C/Python code tab
- compileCode() forwards stdin through routes/compile.py to compiler_worker
- compiler_worker run_c_code/run_python_code accept stdin, pass via subprocess.run(input=)
- known issue: Console UI does not queue stdin properly → fix in next cycle
2026-08-01 22:32:54 +00:00
a2nr 0ee39f152e refactor(compose): adaptasi pola network tailscale ala firefly-iii
- Semua service share netns elemes-ts (network_mode: service:elemes-ts),
  hapus bridge network elemes_network
- lms-tail.json: proxy target 127.0.0.1 (bukan nama service DNS)
- flowchart pindah port 80 → 8081 (konflik port di netns bersama),
  tambah nginx.conf custom + EXPOSE 8081
- env internal (COMPILER_WORKER_URL, VELXIO_COMPILER_URL, API_BACKEND,
  hooks fallback, vite dev proxy) → 127.0.0.1
- fix format volume velxio-data/velxio-arduino-libs agar kompatibel
  podman-compose 1.0.6 (named volume standar)
2026-08-01 12:56:51 +00:00
a2nr 02d5969619 refactor(quiz): restructure quiz session, question view, and tab safety
Restructure quiz flow into QuizSession primitive + atomic quiz state in
LessonManager, and extract QuizQuestionView for split-view display.

Tab-safety fix: add lesson-tabs.ts with pickDefaultTab(), getAvailableTabs()
mirroring the exact {#if} conditions in +page.svelte, and ensureActiveTab()
safety-net that falls back to pickDefaultTab() when the desired tab is not
rendered. A reactive $effect in lesson/[slug]/+page.svelte validates
activeTab against lesson data on every change, preventing the "tab quiz
kosong" (empty workspace) regression for quiz-only lessons and phantom-tab
state after data changes.

Files:
- lib/services/lesson-tabs.ts (+test): pure helpers, 18 tests pass
- lesson/[slug]/+page.svelte: ensureActiveTab reactive guard + QuizQuestionView
- lesson/[slug]/lesson.svelte.ts: atomic startQuiz, getExitStatus, idempotent
  submit on navigate/exit
- lib/services/quiz-session.ts (+test), lib/types/quiz.ts, QuizTab.svelte
  (mgr-driven), QuizQuestionView.svelte, lesson.css
- services/lesson_service.py, services/tests/test_lesson_service_quiz.py
  (test_lesson_service_quiz.py), requirements.txt (+pytest)
- docs/07-quiz-authoring.md
- version.ts APP_VERSION 21 -> 22 (forces SW update for the fix)
- examples/content/dasar/quiz_test.md synced to live content root
2026-08-01 00:14:29 +07:00
a2nr 2f689afc27 feat: implement sub-home/bab feature
- Generalize _read_md_cached() for generic file caching
- Add find_sub_home_for_lesson() and get_sub_home_data() helpers
- Add /api/bab/<folder> endpoint
- Detect sub-home in api_lesson for nav context
- Skip sub-home.md in find_lesson_file() and _parse_lesson_links()
- Add title to bab frontend page data
- Update generate_tokens.py & content_parser.py to skip sub-home.md
2026-07-27 22:01:01 +07:00
a2nr 9637740ea9 feat(quiz): add login gate, one-attempt enforcement, and exit penalty 2026-07-27 21:16:50 +07:00
a2nr 32ef89159a refactor(DeployTab): mode toggle inline in serial monitor + deploy FAB 2026-07-26 11:49:01 +07:00
a2nr bbdc53e601 refactor: playground self-contained full-viewport via svelte:head style 2026-07-24 15:54:29 +07:00
a2nr f705f1f314 fix: playground full-viewport width (override container max-width) 2026-07-24 15:41:36 +07:00
a2nr 455d449d1e fix: circuit tab full height in playground (override fixed 550px) 2026-07-24 14:03:44 +07:00
a2nr 1b2c51f72f chore: bump version to 19 for playground multi-tab 2026-07-24 13:46:18 +07:00
a2nr 589f3a148d feat: playground multi-tab (Velxio/Flowchart/Circuit/Code) with auto-save 2026-07-24 13:45:28 +07:00
a2nr 7e1139e7d1 refactor: make FlowchartTab eval button conditional on onRun prop 2026-07-24 13:44:25 +07:00
a2nr 8e89fde3c1 fix: docked editor panel height + quiz image parser + assets dir config
- fix(layout): editor-area docked mode sekarang height:70vh (sebelumnya
  max-height:85vh tanpa height, menyebabkan tab Arduino/velxio menciut
  ke 150px karena iframe tidak punya intrinsic height)
- fix(layout): tambah overflow:hidden pada velxio/flowchart/quiz panel
  untuk mencegah nested scrollable flex collapse
- feat(quiz): parser image dari 'image:' directive dan markdown ![alt](path)
  di question flashcard; konversi bare filename ke /assets/ path
- feat(assets): ASSETS_DIR derived dari CONTENT_DIR untuk support
  custom content directory (bukan hardcoded 'assets')
- fix(quiz): QuizTab container gunakan flex:1+min-height:0 (bukan height:100%)
- chore: hapus placeholder examples/assets/put_your_image.here
2026-07-21 20:50:01 +07:00
a2nr 98adc0b860 fix(usb-deployer): review fixes — reset pumpRunning on exit, clear buffer on readExact timeout
WARN-1: pumpRunning now reset to false when the pump loop exits via
{done} or error, so future startPump() isn't a silent no-op.
WARN-3: readExact clears rxBuffer on timeout to avoid stale bytes
leaking into the next non-retried STK500 command.
2026-07-19 19:15:20 +07:00
a2nr 6f2f9c589a chore(frontend): bump APP_VERSION to 18 for SW cache-bust
Service worker evicts old caches on activate, so users always
get the new usb-deployer bundle with the read-pump fix instead
of a stale cached one.
2026-07-19 19:09:45 +07:00
a2nr 056b1a47b6 refactor(usb-deployer): serial monitor + flashBuffer + lifecycle use pump
- startSerialMonitor/setBaudRate stop+restart pump, subscribe rxBuffer.onData
- flashBuffer stops pump, reuses/reopens port, starts pump, drains before sync
- stopReaderWriter now just releases locks; cleanup stops pump first
- remove dead keepReading field
2026-07-19 19:09:10 +07:00
a2nr f7c088013a fix(usb-deployer): read from rxBuffer, kill orphaned-read race in get_sync
readExact and drainStray now consume the FIFO buffer fed by the pump
instead of calling reader.read() directly. No orphaned reader.read()
promise can swallow optiboot INSYNC/OK replies anymore. This is the
core fix for "get_sync failed after N attempts".
2026-07-19 19:06:44 +07:00
a2nr 121d592ce0 feat(usb-deployer): add read pump + start pump after pair
Single pump loop becomes the only reader.read() caller, feeding
rxBuffer. Serial monitor + readExact/drain will consume from the
buffer (next tasks). Build passes.
2026-07-19 19:05:54 +07:00
a2nr bf4b1a4932 feat(frontend): add vitest + ByteStreamBuffer FIFO for orphan-read fix
Test runner setup (vitest) plus deadline-based FIFO buffer that
becomes the single sink for serial bytes. readExact keeps
partial bytes buffered on timeout — the exact case that dropped
optiboot INSYNC/OK replies under the orphaned-reader race.
7 unit tests pass.
2026-07-19 19:03:40 +07:00
a2nr 2a09ee77ab feat(embed): add raw HTML embed fence with bleach sanitization
- Add embed markdown fence: user pastes raw embed HTML code
  (from Canva/YouTube/Google Docs Share→Embed) into lesson markdown
  and slide content. Backend sanitizes via bleach (whitelist
  tags/attrs/styles) + checks iframe src against domain blacklist
  (SSRF prevention). Frontend renders iframe directly — no lazy
  action needed.
- Backend: _process_embed_embeds + _sanitize_embed_html in
  lesson_service.py, applied to lesson_content, exercise,
  lesson_info, and slide loop. Graceful fallback if tinycss2
  missing (CSS unsanitized but tags/attrs still stripped).
- Tests: 9 pytest cases (Canva/YouTube HTML, script stripping,
  onclick stripping, blocked domain, non-https iframe, empty,
  unchanged, dangerous style).
- Frontend: remove renderEmbedEmbeds.ts + wire-up + .generic-embed
  CSS (URL-only approach from earlier iteration, superseded).
  Keep .embed-error CSS for error messages.
- Example: update test_slides.md with raw HTML Canva embed (slide)
  + YouTube embed (body).
- Deps: bleach>=6.0.0, tinycss2>=1.2.0 in requirements.txt.
- Docs: consolidate 4 plan files into docs/06-embed-content.md.
2026-07-19 15:39:38 +07:00
a2nr 0cbac64c6f feat(frontend): Velxio iframe fullscreen + playground route + SvelteKit service worker
- VelxioTab: add allowfullscreen to Velxio editor iframe
- lesson.css: flex/shrink fixes for .velxio-iframe on mobile
- +layout.svelte: hide Navbar/Footer on /playground full-viewport route
- Add /playground route: Velxio editor iframe + DeployFAB bridge
- Migrate static sw.js to SvelteKit module service-worker.ts
2026-07-18 17:26:59 +07:00
a2nr f164134222 fix(usb-deployer): CH340 port reuse fix — skip reopen, single DTR, baud tracking 2026-07-17 14:35:30 +07:00
a2nr 2773bf2a83 feat(usb-deployer): double DTR reset + post-write delay for stubborn clones 2026-07-17 12:47:58 +07:00
a2nr 95a3569be9 chore: bump version to v17 2026-07-17 11:07:46 +07:00
a2nr 8adc28b745 refactor(usb-deployer): use named settle constant and fix comment 2026-07-17 10:38:40 +07:00
a2nr 852fccacdf fix(usb-deployer): rebalance sync retries/backoff for optiboot window 2026-07-17 10:37:57 +07:00
a2nr 2fd2b1b5b4 fix: register SvelteKit service-worker.js instead of static sw.js 2026-07-17 10:37:48 +07:00
a2nr 84827350af fix(usb-deployer): drain stray bytes until quiet window 2026-07-17 10:37:08 +07:00
a2nr 3d941191e3 refactor(usb-deployer): name timing constants for sync window tuning 2026-07-17 10:35:23 +07:00
a2nr 4ec5d4cb92 fix(usb-deployer): add detailed diagnostic logging for sync failures 2026-07-17 10:24:39 +07:00
a2nr 7dd8e5d522 fix(usb-deployer): preliminary get_sync robustness improvements 2026-07-17 10:23:39 +07:00
a2nr 24db01fd8d refactor: Footer.svelte imports APP_VERSION from $lib/version 2026-07-17 09:46:29 +07:00
a2nr 12725cbdad chore: bump version to v16 2026-07-17 09:26:17 +07:00
a2nr 01f68d354a fix: disable toggle during deploy, SSR guard for matchMedia, reactive isDesktop, safe deployBinary guard 2026-07-17 08:20:56 +07:00
a2nr 185fed636e feat: add BLE/USB toggle with auto-detect in DeployTab 2026-07-17 08:17:54 +07:00
a2nr 369897529d fix: harden USBHardwareDeployer — drain after timeout, async cleanup, flash error recovery, baud切换 2026-07-17 08:15:21 +07:00
a2nr f8e92875c9 feat: add USBHardwareDeployer with STK500v1 protocol via Web Serial API 2026-07-17 08:10:12 +07:00
a2nr 1b51e75ff0 feat: add HardwareDeployer interface, BLEHardwareDeployer implements it 2026-07-17 08:03:42 +07:00
a2nr a7c9d1c499 fix(deploy-tab): await handleOpenSerial() in deploy success path for proper error handling 2026-07-05 17:53:45 +07:00
a2nr bb19523f65 feat(deploy-tab): auto re-pair before deploy if connection lost 2026-07-05 17:49:40 +07:00
a2nr 87364da0c5 feat(deploy-fab): auto-reset Arduino when starting serial monitor 2026-07-05 17:48:44 +07:00
a2nr f6b57c08d1 feat(deploy-tab): auto-reset Arduino when starting serial monitor 2026-07-05 17:48:31 +07:00
a2nr c6c6daecbf feat(ble-deployer): add resetArduino() method for DTR pulse 2026-07-05 17:46:32 +07:00
a2nr a18d3f660c feat(ble-deployer): add CMD_RESET for Arduino DTR pulse reset 2026-07-05 17:38:40 +07:00
a2nr bba06933bd feat(elemes): v3.1 checkpoint — BLE deployer enhancements before port to Velxio
v3.1 enhancements (4 Jul 2026):
- Baud dropdown (9600/19200/38400) + CMD_SET_BAUD
- LED blink patterns per-state (IDLE/RECEIVING/FLASHING/SERIAL_BRIDGE)
- Arduino event-based connect/disconnect (CherryUSB)
- Serial terminal always visible saat paired
- Re-deploy fix: serial_bridge_stop before parser
- Dual baud: 115200 STK500 + 9600 serial bridge
- Footer v15, SW cache v14

This is a checkpoint commit. Next cycle: port Deploy from
SvelteKit (DeployTab.svelte) to Velxio React app (native integration).
DeployTab.svelte will be deprecated after port complete.
2026-07-04 20:21:46 +07:00
a2nr 3dd29e1ba1 revert: DATA sendCommandWithRetry ke f6a04b8 (direct write+waitForAck, no readPoll)
cad90eb merutekan DATA melalui sendCommand() dengan readPoll state===1
yang selalu true — menyebabkan chunk lambat 5s/kirim saat ACK di-drop.
Kembalikan ke direct writeValueWithResponse + waitForAck.
Selama transfer aktif tidak ada idle gap (Qualcomm >8s), jadi ACK notify
tidak terpengaruh idle-drop.

Perubahan:
- sendCommandWithRetry: build payload sendiri, pakai chunkCRC param,
  write+waitForAck langsung (tidak lewat sendCommand)
- sendCommand: hanya handle INIT dan END (DATA dihapus dari blok)
- Hapus writeSucceeded flag (tidak lagi dipakai)
- Hapus readPoll fallback untuk DATA
- Bump v12 (Footer + SW cache)
2026-07-01 06:07:57 +07:00
a2nr 26ada16c4d feat(frontend): bump version badge + SW cache to v11 for deploy verification 2026-07-01 05:12:42 +07:00
a2nr c20b2d5a8e fix: END ACK regression — readPoll pintar + INIT_ACK_INDEX 0xFFFE + binary_parser.c git track
Akar masalah:
- 4a6ef8c menambah binary_parser_reset() di handler re-deploy SERIAL_BRIDGE
  yang menghapus expected_total_crc setelah INIT — menyebabkan CRC mismatch
  di END. Source 1d3a489 sudah menghapus reset-nya, tapi device butuh rebuild.
- cad90eb merutekan DATA melalui sendCommand() dengan readPoll state===1
  yang selalu true saat DATA — write gagal dilaporkan sukses.

Perbaikan:
1. readPoll pintar untuk DATA: state===1 tidak lagi dianggap sukses.
   readPoll hanya fast-fail di state>=5; deadline fallback hanya ok
   jika writeValueWithResponse sukses (GATT write response = bukti delivery).
2. INIT_ACK_INDEX=0xFFFE (Fase 3): inisialisasi INIT dengan index unik
   menghilangkan tabrakan dengan DATA[0] (index 0). binary_parser.c echo
   index recv di ACK INIT. Guard handleFlashingNotification diperluas.
3. pendingAcks.clear() di awal deployHex mencegah poisoning antar deploy.
4. Track firmware inti ke git: binary_parser.c, checksum.c, stk500v1.c,
   usb_host.c + headers + CMakeLists + sdkconfig + partitions.

Build: ESP-IDF v6, ESP32-S3, flash via /dev/ttyACM0
2026-07-01 05:10:38 +07:00
a2nr d146e445d6 feat(frontend): add version badge (v10) in footer for deploy verification 2026-06-30 19:39:15 +07:00
a2nr 1d3a48940e fix(firmware+frontend): remove binary_parser_reset() re-deploy wipes CRC + tighten INIT poll
Firmware (state_machine.c):
- Remove binary_parser_reset() from SERIAL_BRIDGE→RECEIVING handler
- Remove binary_parser_reset() from ERROR→RECEIVING handler
- Parser's INIT handler already resets itself; calling reset AFTER
  INIT payload processing wipes expected_total_crc to 0 → CRC fail

Frontend (ble-deployer.ts):
- Tighten INIT readValue poll: state===1 (RECEIVING) only
  Previously accepted state >= 1 && <= 4 which could false-positive
  on FLASHING(3) or SERIAL_BRIDGE(4) stale states

Cache v9 → v10
2026-06-30 19:21:35 +07:00
a2nr 6ccbb88678 bump(frontend): cache v8→v9 for clean SW refresh 2026-06-30 18:32:05 +07:00
a2nr cad90ebd2e fix(frontend): route DATA through sendCommand for readValue() fallback
sendCommandWithRetry now delegates to sendCommand() instead of
using raw writeValueWithResponse + await ackPromise. This ensures
DATA chunks also benefit from the readValue() state poll fallback
when Android BLE notify is unreliable after idle.
2026-06-30 18:14:03 +07:00
a2nr f6a04b81ba fix: re-deploy crash + readValue poll for INIT/DATA
Firmware (state_machine.c):
- Add EVENT_BLE_INIT handler to SERIAL_BRIDGE state
  -> transition back to RECEIVING for re-deploy
- Add EVENT_BLE_INIT handler to ERROR states
  -> allows re-deploy from error without pressing Retry

Frontend (ble-deployer.ts):
- Add readValue() state poll for INIT and DATA commands
  (same Android notify idle-drop bug affects these too)
- INIT success: firmware state >= 1 (RECEIVING+)
- DATA success: firmware state == 1 (RECEIVING)
- Error on state >= 5
2026-06-30 17:55:26 +07:00
a2nr 9918aafe41 fix: Phase B — readValue() state poll fallback for END ACK
Firmware:
- Add BLE_GATT_CHR_F_READ to flashing characteristic
- Read callback returns state_machine_get_current() as 1 byte
  (4=SERIAL_BRIDGE=success, 5/6=ERROR)

Frontend:
- Replace ineffective pendingAcks poll with readValue() poll
- CCCD refresh fire-and-forget (non-blocking)
- Race ackPromise (notify) vs readPoll (readValue)
- Clean up ackPromise resolver on readPoll win
- Cache v7 → v8
2026-06-30 17:35:23 +07:00
a2nr 9dda8fe3e6 fix: event-driven poll loop for END ACK to work around Android BLE notification delivery issue on Qualcomm chipsets
- Race ackPromise against a polling loop that yields to the event loop
  every 200ms (vs a single blocking await that can miss notifications)
- bump SW cache v5→v6
2026-06-30 13:12:55 +07:00
a2nr e4ec3f1ded feat: custom evaluation config 2026-06-17 20:34:36 +07:00
a2nr 120a1338c0 feat: enhance fullscreen mode slide and hide able slide 2026-05-14 20:25:21 +07:00
a2nr 58e897f743 feat: add markdown-based interactive slide carousel with fullscreen mode 2026-05-14 18:53:46 +07:00
a2nr 7384b6e585 feat: readable content: 2026-05-14 16:26:11 +07:00
a2nr 5f150da651 fix: progress path fix 2026-05-12 14:49:18 +07:00
a2nr 097f2c5609 feat: enhance lesson UI with centered images, bordered tables, and conditional output tab 2026-05-11 07:27:15 +07:00
a2nr 438d96ef13 feat: update image capability inside quiz 2026-05-10 20:38:35 +07:00
a2nr 459ceff2d8 fix: prevent localStorage leakage and fix navigation by implementing component isolation and reactive state management 2026-05-10 09:14:00 +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 7e77748b6b feat: add quiz feature 2026-05-08 09:50:07 +07:00
a2nr 9ed207d2fa feat: implement secured lesson prerequisite system with interactive links and auto-docking UI 2026-05-07 10:54:42 +07:00
a2nr c103bc02ad feat(flowchart): support interactive embedding in markdown with readonly mode and frontend evaluation 2026-05-02 19:45:04 +07:00
a2nr 433c095394 feat(flowchart): implement text-based logic with auto-layout and migrate evaluation to frontend 2026-05-02 18:47:46 +07:00
a2nr 0ff56ed9d2 bug fix : leak content python_expected_output 2026-05-01 15:32:55 +07:00
a2nr 6db1344622 feat: maximize workspace on mobile mode 2026-05-01 11:24:41 +07:00
a2nr c5348a9166 add feature: flowchart maker 2026-05-01 09:09:45 +07:00
a2nr 6f1b86226e Enhance UI Experience 2026-04-28 12:47:53 +07:00
a2nr f8de0cab5f feat: implement \"Coba\" button for code blocks
and improve mobile UX

   - Menambahkan fitur tombol \"Coba ▶\" untuk menyalin kode
     materi ke editor secara otomatis.
   - Implementasi setupTryButtons.ts (Svelte Action) untuk
     injeksi tombol berdasarkan label bahasa Markdown (c, python,
  `arduino).
   - Mengatur perilaku tombol agar hanya memuat kode dan
     memfokuskan tab (No Auto-Run) untuk memberikan kesempatan
     siswa meninjau kode.
   - Optimasi tampilan Mobile (< 768px):
       - Tombol \"Coba\" selalu terlihat (tanpa hover).
       - Otomatis membuka workspace ke mode 'half-sheet' dan
         melakukan smooth scroll ke editor saat tombol diklik.
   - Sinkronisasi urutan render: setupTryButtons dijalankan
     sebelum highlightAllCode untuk memastikan deteksi bahasa
     yang akurat.
   - Update documentation.md dengan panduan penggunaan fitur
     tombol \"Coba\" dan dokumentasi refactoring modularitas
     halaman lesson.
   - Menambahkan modul uji coba LaTeX ke daftar materi di
     home.md
2026-04-27 21:38:36 +07:00
a2nr 5aebd4487d refactor(frontend): pecah komponen raksasa
+page.svelte dan perbaiki backend parser

Pembaruan ini
     mencakup:
- Refactoring skala besar pada halaman lesson SvelteKit untuk efisiensi kode.
- Ekstraksi evaluasi Code, Circuit, dan Velxio ke dalam direktori lib/services/.
- Memisahkan manajemen iframe (Zustand & PostMessage) ke  velxio-manager.ts.
- Memisahkan Tab Panel HTML menjadi komponen spesifik (CodeTab, CircuitTab, VelxioTab).
- Ekstraksi blok <style> menjadi stylesheet terpisah (lesson.css).
- Perbaikan warning A11y & penghapusan class usang pada Navbar.svelte.
- Memperbaiki regex parser 'Available_Lessons' pada lesson_service.py di backend.
- Menambahkan mekanisme auto-append ekstensi '.md' untuk  mengatasi bug Home kosong dan tombol 'Next Lesson' yang hilang akibat format URL baru di home.md.
2026-04-27 13:36:17 +07:00
a2nr b8fb67115e feat: implement LaTeX support with KaTeX and python-markdown-math
3 - Integration of KaTeX in frontend (SvelteKit) with a custom
  renderMath` action.

  - Added `python-markdown-math` extension in backend (Flask). to handle math blocks.
  - Configured Vite to handle KaTeX during SSR and browser rendering.
  - Added a LaTeX test lesson and updated home navigation.
  - Supported both inline ($) and block ($$) math rendering,
   including multi-line support.
2026-04-26 15:47:11 +07:00
a2nr dce4916b94 ui: refactor navbar and improve mobile experience
- Move navigation menu to the leftmost position and
   consolidate actions into a dropdown.
 - Replace clunky mobile sheet handle with explicit
   minimize/maximize buttons.
 - Fix home page content margins for list elements.
 - Ensure student identity remains visible on mobile devices
   with optimized font sizing.
 - Synchronize CircuitJS simulator theme with global
   light/dark mode.
 - Update elemes.sh to provide cleaner output by silencing
   podman-compose logs by default.
2026-04-22 21:04:38 +07:00
a2nr e4c68b2894 feat(security): implement anonymous access with rate limiting and secure proxy, harden authentication and implement session protection
Implements multiple layers of security to address high-risk session
   and authentication vulnerabilities identified in the security review:

   - Allow code compilation (C, Python, Arduino) for anonymous users.
   - Enforce a 1-request-per-2-minutes rate limit for anonymous IPs.
   - Implement a global anonymous compilation queue with 20 concurrent slots.
   - Proxy Velxio (Arduino) compilation through Flask to prevent API hijacking.
   - Exempt authenticated users (tokens/cookies) from all rate limits.
   - Fix networking and DNS resolution in podman-compose.
   - Fix Svelte a11y warnings and trailing slash routing issues.
   - Cookie Security: Added dynamic 'secure' flag support via COOKIE_SECURE
     env variable for HTTPS/Tailscale Funnel compatibility.
   - Rate Limiting: Integrated Flask-Limiter on /login (50 req/min) to
     prevent API abuse while accommodating shared school networks (NAT).
   - Tarpitting: Added 1.5s artificial delay on failed logins to neutralize
     automated brute-force tools without blocking legitimate users.
   - Session Invalidation: Implemented an in-memory token blacklist on
     logout to ensure session tokens cannot be reused.
   - Documentation: Updated technical docs and proposal status to reflect
     the current security architecture.

   Ref: @elemes/proposal.md (Poin 6.1, 6.2, 6.3)
2026-04-22 12:57:54 +07:00
a2nr 6d5c27f93f feat(help): add interactive student tutorial with video and integrated help page
- Create student tutorial documentation in Markdown with updated asset paths
 - Add backend routes to serve rendered help content and assets via JSON API
 - Implement frontend /help route using SvelteKit for professional rendering
 - Add "Bantuan" link to the navigation bar with custom styling
 - Generate tutorial screenshots and a demo video with virtual cursor and subtitles
 - Configure Tailscale and Vite proxies to support the new help routing
 - Add automated video generation scripts and assets
2026-04-20 13:43:45 +07:00
a2nr 7c069660f6 feat: add evaluation configuration support in lesson content and API 2026-04-16 11:12:23 +07:00
a2nr 7acce0b610 refactor: update component wiring and properties in Arduino examples 2026-04-16 08:00:54 +07:00
a2nr 405b6d8a6d update remove velxio featur 2026-04-15 21:07:39 +07:00
a2nr 65c12bc716 remove reset button, move auto save indicator in velxio 2026-04-15 20:03:36 +07:00
a2nr 998472f996 update auto save for arduino velxio 2026-04-15 14:24:33 +07:00
a2nr 314975ac65 feat: add actions snippet to OutputPanel and implement run-all evaluation logic for lessons 2026-04-10 14:15:16 +07:00
a2nr 997ab78f56 feat: improve evaluation system and update circuit editor to use localStorage for persistence 2026-04-10 14:00:35 +07:00
a2nr 74a8d87853 add velxio as submodule 2026-04-09 10:51:36 +07:00
a2nr 09827bf3ff fix python code 2026-04-01 12:56:27 +07:00
a2nr 1e6c6a884c feat: Enhance lesson functionality with circuit output and key text support, update token generation script for better CSV handling 2026-03-31 14:31:15 +07:00
a2nr d29c2f2e3e feat: Integrate CircuitJS1 into Elemes LMS
- Added CircuitJSApi interface for simulator API interaction.
- Updated lesson page to support circuit simulation alongside code execution.
- Implemented separate output states for code and circuit evaluations.
- Enhanced lesson content rendering to include circuit embeds using markdown.
- Refactored backend to process circuit embed syntax and convert to HTML.
- Updated podman-compose configuration to include new environment variable for cursor offset.
- Created a proposal document outlining the feasibility and implementation plan for CircuitJS1 integration.
2026-03-31 12:08:42 +07:00
a2nr 39d1b18c2a feat: integrate circuitjs1 simulator into frontend with new editor component and service worker support 2026-03-29 17:25:09 +07:00
a2nr 9b745f52f4 feat: Add a visual auto-save indicator to the code editor, clear session storage on authentication changes, and integrate auto-save functionality with lesson progress and solution viewing. 2026-03-27 20:38:20 +07:00
a2nr d3acfcf825 update green check, button start, de-overwhelm +page, improve mobile ui, add progress page for teacher only, add sessionStorage. 2026-03-27 16:41:57 +07:00