CBT E2E Hardening Implementation Plan¶
Scope¶
Dokumen ini menjadi referensi implementasi lanjutan audit CBT E2E pada:
- Frontend:
scola-fe-v2 - Backend custom module:
scola-odoo-module/scola_cbt,scola_admission_assessment,scola_assessment_bridge
Fokus: RBAC, kontrak FE-BE, keamanan token dan timing ujian, integrasi SPMB/LMS/penilaian/eRapor, dan penyederhanaan UX.
Current Findings (Ringkas)¶
- RBAC backend over-grant: assignment group teacher + record rule creator terlalu lebar.
- Attempt deadline belum dikunci ke
exam.end_time. - Token CBT masih terekspos terlalu luas (student schedule + tampilan UI default).
- FE export endpoint belum konsisten dengan arsitektur same-origin
/api. - Capability student CBT belum seragam antara menu dan route.
- Admission CBT masih berpotensi punya dua sumber kebenaran (halaman CBT umum vs jadwal SPMB).
- Proteksi CRUD question set perlu diperketat (khususnya delete saat sudah terpakai).
- Transparansi pipeline publish nilai sampai eRapor belum eksplisit di UI.
Target Architecture¶
- Backend sebagai security boundary utama (RBAC, deadline, token, publish).
- FE konsisten dengan kontrak backend, tidak menyimpan workaround endpoint.
- Ownership context tunggal:
learningdari flow kelas/ulangan.admissiondari jadwal SPMB.independentdari CBT center.- Nilai CBT learning dipublish idempotent ke gradebook dan terlihat status sinkronisasi ke eRapor.
Access Model Decision — 2026-05-04¶
Model ideal yang dipakai untuk CBT guru:
- Guru mapel / pembuat ujian boleh membuka grading workspace untuk ujian yang ia kelola. FE memakai capability
academics.cbt_exams.manage, lalu backend tetap menjadi batas final melalui ownership / teaching-assignment check. - Proctor console bukan hak default guru. Akses proctor harus lewat
scola_cbt.group_cbt_proctor, CBT Manager, atau admin akademik yang memang diberi bridge proctor. scola_cbt.group_cbt_gradertidak diberikan otomatis ke semua guru. Group ini disimpan untuk elevated/cross-context grading bila sekolah membutuhkan penugasan grader eksplisit.- Auto-create user guru hanya memberi capability authoring CBT (
group_cbt_exam_creator), bukan proctor/grader.
Follow-up Decision — Exam-Scoped Staff Assignment¶
Audit lanjutan pada 2026-05-04 menemukan satu gap tersisa: group_cbt_proctor dan group_cbt_exam_creator masih terlalu global jika dipakai sebagai satu-satunya dasar akses. Model ideal diperbarui:
group_cbt_exam_creator,group_cbt_proctor, dangroup_cbt_graderadalah capability/entry-point role, bukan bukti final bahwa user boleh mengelola semua ujian.- Otorisasi final untuk proctor dan grader membaca assignment per ujian:
cbt_author_user_idscbt_proctor_user_idscbt_grader_user_ids- Proctor console hanya menampilkan ujian yang dapat diproctor oleh user saat ini:
- CBT manager/admin akademik tetap full access.
- Panitia SPMB/admin admission dapat menangani context
admission. - Guru/staf biasa harus masuk
cbt_proctor_user_idspada ujian tersebut. - Context
admissiontidak boleh lagi dibuat oleh generic teacher yang kebetulan memilikigroup_cbt_exam_creator. Pembuatan SPMB CBT dibatasi ke panitia SPMB/admin admission/admin akademik/CBT manager. - Untuk praktik ujian sekolah/final, delegasi proctor idealnya dilakukan dari detail ujian melalui assignment petugas, bukan lewat pemberian akses global.
Execution Plan¶
Phase 1 — Contract & Frontend Consistency¶
- Standarisasi URL export CBT agar selalu via
/api. - Samakan capability route student CBT dengan capability menu student.
- Hardening tampilan token di FE: masked-by-default, reveal on demand.
- Tambahkan/ubah test FE untuk menjaga konsistensi route-capability dan endpoint.
Deliverable:
- Patch src/services/cbt/*.
- Patch route student CBT.
- Patch halaman CBT guru untuk token visibility.
Phase 2 — Backend RBAC Hardening¶
- Hapus auto-grant group proctor/grader untuk semua teacher.
- Ubah rule exam creator agar tidak full-access seluruh exam untuk faculty.
- Tambah rule ketat untuk
scola.cbt.attemptdanscola.cbt.attempt.answerscope per pemilik. - Tambah test backend RBAC (teacher generic, proctor, grader, manager).
Deliverable:
- Patch scola_cbt/__init__.py, scola_cbt/security/*.xml, ir.model.access.csv bila perlu.
- Test backend untuk akses lintas exam lintas guru.
Phase 3 — Exam Timing & Submission Integrity¶
- Set
attempt.end_time = min(now + duration, exam.end_time). - Pastikan sync/answer tidak menerima jawaban saat waktu habis.
- Tambah test edge case: start near end, expired sync, resume after expiry.
Deliverable:
- Patch scola_cbt/models/attempt.py, controllers/runner_attempt_api.py.
- Test backend timing dan submission.
Phase 4 — Token Lifecycle Hardening¶
- Stop expose
cbt_tokenpada student schedule API. - Review kebutuhan token per context:
- Admission authenticated: optional bypass (sesuai kebijakan existing).
- Learning/independent: token sesuai policy.
- Audit event untuk token reveal/regenerate (di backend + FE action log bila tersedia).
Deliverable:
- Patch controllers/student_schedule.py, related runner payload.
- Update FE runner flow bila token wajib input manual.
Phase 5 — SPMB Canonical Ownership¶
- Tegaskan admission CBT dikelola dari jadwal SPMB.
- Halaman CBT umum untuk admission hanya read-only/deep-link ke SPMB bila perlu.
- Uji flow penuh SPMB: create schedule → sync participant → runner → sync result.
Deliverable: - Patch FE entry point/CTA admission context. - Patch backend guard jika diperlukan.
Phase 6 — Grade Pipeline UX & Observability¶
- Tampilkan status pipeline per exam:
- graded
- publish gradebook
- synced to eRapor
- Surface failure reason untuk publish/republish.
- Tambah audit dashboard ringkas untuk exam-level incidents.
Deliverable: - Patch halaman detail/report CBT. - Patch endpoint summary jika data belum tersedia.
Validation Strategy¶
Urutan gate minimum per batch:
npm run lintnpm run testnpm run build- Backend unit/integration test terkait module CBT/SPMB (saat patch backend)
- E2E smoke:
- learning CBT
- admission CBT
- publish nilai ke gradebook/eRapor
Batching Strategy¶
- Batch FE cepat: Phase 1.
- Batch backend security: Phase 2.
- Batch integrity timing/token: Phase 3-4.
- Batch integrasi/UX: Phase 5-6.
Progress Evaluation — 2026-05-03¶
Status implementasi terhadap plan:
| Phase | Status | Catatan |
|---|---|---|
| Phase 1 — Contract & Frontend Consistency | Done | Export CBT sudah memakai /api, route student CBT diselaraskan dengan feature flag menu, token student tidak lagi dikirim dari schedule API, dan launch siswa memakai input token manual. |
| Phase 2 — Backend RBAC Hardening | Done | Auto-grant proctor/grader untuk semua teacher dihentikan, exam creator dibatasi ke own exam, attempt/answer student diberi record rule eksplisit. |
| Phase 3 — Exam Timing & Submission Integrity | Done | Deadline attempt dikunci ke min(now + duration, exam.end_time), sync expired auto-submit dan tidak menerima jawaban setelah waktu habis. |
| Phase 4 — Token Lifecycle Hardening | Done | cbt_token dihapus dari student schedule, invalid token masuk audit event token_invalid, token SPMB schedule tidak lagi ditampilkan karena flow pendaftar memakai auth SPMB. |
| Phase 5 — SPMB Canonical Ownership | Done | Entry point pendaftar tetap dari /spmb/cbt, route SPMB CBT memakai featureFlag: scola_cbt, jadwal SPMB menjadi sumber launch peserta dan sync participant/result. |
| Phase 6 — Grade Pipeline UX & Observability | Done | Report hasil CBT menampilkan pipeline grading → gradebook → eRapor, failure reason publish, incident summary, serta audit event publish score yang valid. |
Evidence test lokal yang sudah dijalankan selama implementasi:
- FE:
npm run test— 204 files passed, 1026 tests passed, 2 files skipped. - BE targeted:
test_observability_structure_unit.py,test_runner_timeout_unit.py,test_question_set_contract_unit.py, dan test CBT hardening lain lulus pada batch sebelumnya.
Remaining operational validation:
- Jalankan Odoo module upgrade
scola_cbt,scola_admission_assessment,scola_assessment_bridge, danscola_report_carddi environment dev/server. - Jalankan E2E smoke learning CBT dan admission CBT dengan data nyata untuk memverifikasi browser flow, karena unit/structure test tidak membuktikan sesi Odoo penuh.
Progress Evaluation — 2026-05-04 Follow-up¶
Gap yang ditutup pada batch ini:
| Gap | Status | Implementasi |
|---|---|---|
Guru generic bisa membuat CBT Admission karena semua guru mendapat group_cbt_exam_creator |
Closed | Backend admission guard sekarang hanya menerima panitia SPMB/admin admission/admin akademik/CBT manager. |
| Proctor role bersifat global dan tidak scoped per ujian | Closed | op.exam punya assignment cbt_proctor_user_ids; proctor controller membaca assignment ini sebelum membuka console/status/action. |
| Tidak ada tempat UI untuk mendelegasikan proctor/grader/author per ujian | Closed | Detail CBT menampilkan kartu Petugas Ujian dan modal assignment author/proctor/grader. |
| Proctor Console masih mengambil semua exam aktif | Closed | FE memakai endpoint /api/scola_cbt/proctor/exams; backend hanya mengembalikan exam yang boleh diproctor user tersebut. |
| SPMB/admission participant permission masih memakai generic exam creator/proctor | Closed | Participant admission read/write guard membaca panitia SPMB atau staff assignment spesifik. |
File utama yang berubah:
- Backend:
scola_cbt/models/exam.pyscola_cbt/controllers/exam.pyscola_cbt/controllers/exam_read_api.pyscola_cbt/controllers/exam_lifecycle_api.pyscola_cbt/controllers/exam_staff_api.pyscola_cbt/controllers/exam_lookup_api.pyscola_cbt/controllers/proctor.pyscola_cbt/controllers/proctor_read_api.pyscola_cbt/controllers/grading.pyscola_cbt/controllers/participant.py- Frontend:
src/services/cbt/examService.jssrc/services/cbt/proctorService.jssrc/views/ExamManagement/Faculty/Exam/CBTExamDetail.vuesrc/views/ExamManagement/Faculty/Proctor/ProctorDashboard.vue
Validation tambahan yang wajib setelah deploy:
- Upgrade module
scola_cbtagar field M2M staff assignment terbentuk. - Login sebagai guru pembuat ujian: pastikan bisa grading own/assigned exam tetapi tidak bisa proctor jika belum ditugaskan.
- Assign guru sebagai proctor dari detail ujian, logout-login guru tersebut, lalu pastikan menu/route proctor hanya menampilkan ujian yang ditugaskan.
- Buat CBT Admission sebagai admin staff/SPMB; pastikan generic teacher tidak bisa membuat context admission.
Progress Evaluation — 2026-05-04 SPMB Internal Entry Points¶
Gap lanjutan yang ditutup:
| Gap | Status | Implementasi |
|---|---|---|
Capability admissions.cbt_author.manage, admissions.cbt_proctor.manage, dan admissions.cbt_grade.manage belum punya entry point internal yang eksplisit |
Closed | Ditambahkan route dan menu CBT SPMB untuk admin dan admin staff. |
Halaman CBT admission internal masih berpotensi menumpang route /faculty sehingga context SPMB tidak menjadi sinyal route yang kuat |
Closed | CBTExamList, CBTExamDetail, ProctorDashboard, grading, analytics, item analysis, dan integrity report sekarang bisa berjalan melalui route SPMB yang memiliki meta.examContext = admission. |
| Proctor SPMB belum dipisahkan dari console proctor umum di UX | Closed | Menu Proctor CBT SPMB membuka console dengan filter exam_context = admission, sehingga dropdown hanya menampilkan ujian admission yang boleh diproctor user tersebut. |
| Navigasi detail/report/grading masih hard-coded ke route faculty | Closed | Komponen detail, grading, analytics, item analysis, dan integrity report sekarang memakai route name dari meta.cbt*RouteName bila tersedia. |
File utama yang berubah:
src/router/admissionsRoutes.jssrc/config/apps/appFragments/admissionsApp.jssrc/config/apps/appFragments/adminStaffApp.jssrc/views/ExamManagement/Faculty/Exam/CBTExamList.vuesrc/views/ExamManagement/Faculty/Exam/CBTExamDetail.vuesrc/views/ExamManagement/Faculty/Exam/CBTExamAnalytics.vuesrc/views/ExamManagement/Faculty/Exam/CBTItemAnalysis.vuesrc/views/ExamManagement/Faculty/Exam/CBTIntegrityReport.vuesrc/views/ExamManagement/Faculty/Exam/GradingWorkspace.vuesrc/views/ExamManagement/Faculty/Proctor/ProctorDashboard.vuetests/menu/cbtMenuRouteRbacSync.spec.js
Validation:
- FE targeted:
npm run test -- tests/menu/cbtMenuRouteRbacSync.spec.js tests/menu/routerNavigationContract.spec.js— 2 files passed, 10 tests passed.
Remaining operational validation:
- Jalankan E2E browser sebagai admin staff/SPMB:
- buka
/admin-staff/admissions/cbt/exams - buat CBT admission
- assign author/proctor/grader
- buka
/admin-staff/admissions/cbt/proctor - nilai attempt admission melalui route grading SPMB
- Ulangi sebagai admin pada
/admin/spmb/cbt/examsdan/admin/spmb/cbt/proctor. - Upgrade module
scola_cbttetap wajib sebelum validasi server karena field assignment petugas berasal dari backend batch sebelumnya.
Progress Evaluation — 2026-05-04 Operational Validation Follow-up¶
Validasi setelah user menyatakan backend sudah di-upgrade menemukan dua blocker server-side yang masih harus ikut deploy/upgrade sebelum plan bisa dinyatakan selesai secara operasional:
| Temuan | Status | Dampak | Tindak lanjut |
|---|---|---|---|
Remote FE https://dev.gcgscola.id masih menampilkan maintenance untuk route CBT SPMB baru |
Open deploy check | Route FE baru belum terbukti tersedia di deployment remote. | Deploy/build FE yang memuat route /admin/spmb/cbt/* dan /admin-staff/admissions/cbt/*. Validasi lokal FE ke backend remote sudah berhasil membuka list dan proctor page untuk admin/admin staff. |
admin_staff mendapat halaman/tombol create CBT SPMB, tetapi /api/scola_cbt/question_set/list mengembalikan 0 bank soal |
Patched in BE source | UI create buntu karena question_set_id wajib namun dropdown kosong. |
scola_cbt patch: admission context manager bisa read-only list/get question set memakai sudo scope; update/delete tetap owner/CBT manager. |
Guru generic budi.santosa masih bisa create exam_context=admission di remote backend |
Open deploy/upgrade check | Guard admission creator belum aktif di server remote, walaupun source backend sudah punya unit test guard. | Pastikan deployment/upgrade memakai source terbaru dan upgrade module scola_cbt. Probe exam id=70 yang sempat dibuat untuk validasi sudah dihapus. |
Patch backend lokal untuk menutup blocker:
scola_cbt/controllers/question_set_api.pyscola_cbt/tests/test_question_set_contract_unit.pyscola_cbt/__manifest__.pyversi17.0.1.0.10
Validation yang sudah dijalankan:
- FE route local vs remote backend:
/admin/spmb/cbt/exams— opened, menampilkanUjian CBT SPMB./admin/spmb/cbt/proctor— opened, menampilkanProctor CBT SPMB./admin-staff/admissions/cbt/exams— opened, menampilkanUjian CBT SPMB./admin-staff/admissions/cbt/proctor— opened, menampilkanProctor CBT SPMB.- Backend source unit:
python3 scola_cbt/tests/test_question_set_contract_unit.py— passed.python3 scola_cbt/tests/test_exam_permissions_unit.py— passed.
Remaining operational validation setelah backend patch ter-deploy dan module scola_cbt versi 17.0.1.0.10 di-upgrade:
- Re-run
/api/scola_cbt/question_set/listsebagaiadmin_staff; harus mengembalikan bank soal aktif. - Re-run create admission CBT sebagai
budi.santosa; harus gagal dengan pesan guard admission context. - Re-run smoke penuh:
- admin staff create CBT admission dari UI route SPMB,
- assign author/proctor/grader,
- sync peserta dari jadwal SPMB,
- start dan submit attempt admission,
- buka grading route SPMB admin/admin staff,
- finalize grading,
- sync hasil kembali ke jadwal/result SPMB.
Progress Evaluation — 2026-05-04 Operational Validation Closeout¶
Environment validasi:
- FE remote:
https://dev.gcgscola.id - BE remote:
https://be-dev.gcgscola.id - Odoo DB:
scoladev - Backend module terkonfirmasi:
scola_cbtversi17.0.1.0.10
Koreksi data user:
budi.santosabukan guru generic untuk negative RBAC test. Di dev user ini punya role privileged termasukAdministrator,Back Office Admin,Scola Admin,Settings,CBT Exam Creator,CBT Proctor,CBT Grader, danCBT Auditor.abdur.kodarjuga tidak valid sebagai generic teacher untuk smoke remote: password seedteacher123ditolak dan user tetap punya groupAdministrator.- Karena tidak ada seed guru low-privilege yang usable, negative RBAC admission/proctor diuji memakai temporary QA user yang diarsipkan setelah smoke.
Validation yang sudah lulus:
- FE remote page smoke:
/admin/spmb/cbt/exams— renderUjian CBT SPMB./admin/spmb/cbt/proctor— renderProctor CBT SPMB./admin-staff/admissions/cbt/exams— renderUjian CBT SPMB./admin-staff/admissions/cbt/proctor— renderProctor CBT SPMB.- Negative admission create:
- temporary low-privilege teacher ditolak saat POST
/api/scola_cbt/exams/createdenganexam_context=admission. - Proctor assignment scoping:
- temporary low-privilege teacher tidak melihat admission CBT sebelum assignment.
- user yang sama melihat exam setelah masuk
cbt_proctor_user_ids. - Positive operational SPMB CBT smoke:
- run id:
20260504030917 - exam id:
83, state akhirdone - SPMB schedule id:
16 - slot id:
12 - CBT participant id:
14 - attempt id:
4 - runner start → answer → submit berhasil, score
100 - sync result ke SPMB berhasil:
synced=1, slotattendance_status=present,cbt_last_attempt_id=4 - FE targeted test:
npm run test -- --run tests/menu/cbtMenuRouteRbacSync.spec.js tests/menu/routerNavigationContract.spec.js tests/menu/teacherCapabilityCoverage.spec.js tests/unit/services/spmbAdminTestSchedule.service.spec.js tests/unit/services/gradingService.spec.js tests/unit/services/cbtExam.service.spec.js tests/unit/services/spmbCbtFlow.contract.spec.js- 7 files passed, 40 tests passed.
- FE full test:
npm run test- 204 files passed, 1029 tests passed, 2 files skipped, 6 tests skipped.
Temuan gap yang masih terbuka:
| Gap | Status | Evidence | Ideal implementation |
|---|---|---|---|
| Assigned grader tidak punya jalur RBAC yang konsisten | Open BE gap | Temporary assigned grader tanpa op.exam ACL gagal di /api/scola_cbt/grading/attempts/<exam_id> sebelum policy cbt_grader_user_ids dievaluasi. Jika diberi openeducat_exam.group_op_exam_admin, user menjadi terlalu luas dan bisa masuk grading sebelum assignment. |
Grading controller harus melakukan explicit exam access check berbasis cbt_grader_user_ids/author/admin, lalu browse/search attempt via service sudo yang ter-scope. Jangan mensyaratkan OpenEduCat Exam Admin untuk grader terdelegasi. |
group_cbt_grader/assigned grader tidak melihat submitted admission attempt |
Open BE gap | budi.santosa yang assigned/global CBT grader mendapat response success dari grading attempts tetapi attempt id 4 tidak muncul. Record rule attempt saat ini hanya manager/faculty-own/student-own; belum ada rule untuk assigned grader atau controller sudo setelah access check. |
Tambahkan record rule assigned grader/proctor untuk attempt/answer, atau gunakan sudo search setelah _check_teacher_access(exam) lulus. Pastikan domain tetap exam-scoped. |
| Assignment staff masih memberi global CBT group | Open design gap | exam_staff_api.update_exam_staff menambah group_cbt_proctor/group_cbt_grader ke user yang ditugaskan. Ini membantu menu visibility, tetapi berisiko membuat role global bila controller/record rule membaca group tanpa scope exam. |
Pisahkan menu capability dari data scope. Global group boleh hanya membuka shell/menu, sedangkan data dan action wajib scoped ke M2M assignment. |
| Failed create dapat meninggalkan draft record saat controller menangkap exception | Open hardening gap | Selama smoke, beberapa failed create meninggalkan draft exam/seed yang harus dibersihkan manual sebelum re-run. | Bungkus create flow dengan savepoint/rollback atau validasi constraint (exam_code, marks, overlap, state enum) sebelum op.exam.create. |
Next implementation plan untuk menutup gap tersisa:
- Backend grading RBAC:
- Patch
scola_cbt/controllers/grading_read_api.pyagar exam dibaca dengan sudo setelah endpoint menerimaexam_id, lalu_check_teacher_access(exam)menjadi satu-satunya gate policy. - Search attempt/answer memakai
_cbt_sudo_model()setelah gate lulus, dengan domainexam_id = target exam. - Patch
grading_write_api.pydengan pola sama untuk score/finalize operation. - Backend security rules:
- Tambahkan record rule atau controller-scoped sudo untuk
scola.cbt.attempt,scola.cbt.attempt.answer, danscola.cbt.score.revisionbagi assigned grader/proctor. - Audit ulang apakah
group_cbt_graderglobal masih boleh full grading. Jika tetap ada, batasi ke user operasional khusus; assignment per exam tidak boleh menjadi full-school grader. - Staff assignment behavior:
- Evaluasi ulang
_assign_group_to_users. Jika group hanya untuk menu visibility, dokumentasikan dan pastikan semua data endpoint tetap scoped. Jika tidak perlu, hentikan auto-grant global group dan gunakan capability dari assignment endpoint/metadata. - Create transaction hardening:
- Tambahkan pre-validation untuk
exam_code,min_marks,total_marks, state schedule, dan overlap sebelum create. - Bungkus route create dengan savepoint agar failed response tidak meninggalkan draft record.
- Remote seed data:
- Sediakan akun guru generic non-admin khusus QA, misalnya
teacher.cbt.e2e, tanpa Back Office/Scola Admin/Settings/CBT Manager. - Gunakan akun ini untuk regression smoke negative RBAC tanpa membuat temporary user setiap run.
- Re-run setelah backend patch:
- negative generic teacher admission create,
- assigned grader sees only assigned exam attempts,
- assigned grader cannot access unrelated exam attempts,
- SPMB CBT smoke end-to-end sampai grading attempt visible, sync result, dan exam done.