UASA Quest — Asset V2 + Reset Feature

ANDAIAN SKEMA LIVE
- Jawapan semasa disimpan dalam attempt_answers (bukan student_answers); kolum flagged berada dalam jadual ini.
- exam_attempts.status asal: in_progress/submitted/marked. Migrasi menambah abandoned.
- Timer kekal MySQL NOW() + expires_at; timezone database.php kekal +08:00.

TUGAS 1 — RAJAH
1. Tiada CSS/JS/exam.php diubah untuk membaiki crop.
2. Sumber PDF: tools/source/UASA_2025_26.pdf.
3. Pada server CLI:
   php tools/export_assets_manifest.php
   python3 tools/check_assets.py --manifest tools/assets_manifest.csv --root . --csv tools/assets_check_before.csv
   python3 tools/rebuild_assets.py --pdf tools/source/UASA_2025_26.pdf --manifest tools/assets_manifest.csv --root .
   python3 tools/check_assets.py --manifest tools/assets_manifest_v2.csv --root . --csv tools/assets_check_v2.csv
4. rebuild_assets.py mencipta fail q{question_id}_fig{n}_v2.png, assets_preview.html, update_assets.sql dan rollback_assets.sql.
5. Semak preview + CSV. Hanya selepas semua OK, buka tools/update_assets.sql, semak, uncomment COMMIT dan run manual dalam phpMyAdmin.
6. Fail lama tidak ditimpa.

Punca crop: skrip ekstrak asal tidak berada dalam project. Aset terdahulu ialah crop rectangle/manual yang terlalu rapat, sedangkan rajah PDF terdiri daripada vector + text + raster. Audit pembangunan terhadap 32 mapping rows lama menandakan 32/32 menyentuh edge. Re-render V2 development test: 32/32 OK.

TUGAS 2 — RESET
1. Run sql/manual/reset_feature_migration.sql sekali dan semak hasil.
2. Upload semua fail project ini (kekalkan config/database.local.php live).
3. Peringkat A memadam attempt_answers sahaja + audit; expires_at tidak berubah.
4. Peringkat B menandakan attempt lama abandoned, cipta attempt baharu dengan NOW()/DATE_ADD(), attempt_no+1, reset_from_attempt_id.
5. api/save_answer.php kini lock attempt row semasa save supaya save tertunda tidak boleh menghidupkan jawapan selepas reset.
6. CLI developer: php tools/reset_attempt.php 1 --answers atau --full.

UJIAN PEMBANGUNAN YANG DILAKUKAN
- php -l: semua fail PHP lulus.
- node --check assets/js/exam.js: lulus.
- Asset edge test development mapping: lama 0/32 OK; V2 32/32 OK.

UJIAN LIVE YANG MASIH PERLU (perlukan DB/session server)
- Reset A: jawapan+flag hilang selepas reload; expires_at sama.
- Reset B: old=abandoned, new=in_progress, TIMESTAMPDIFF(MINUTE,started_at,expires_at)=120.
- Double click full reset menghasilkan satu attempt baharu sahaja.
- CSRF/owner/submitted/allow_reset/max_resets ditolak.
- Offline tidak mengosongkan UI.
- result.php redirect abandoned ke dashboard.
