Lewati ke isi

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)

  1. RBAC backend over-grant: assignment group teacher + record rule creator terlalu lebar.
  2. Attempt deadline belum dikunci ke exam.end_time.
  3. Token CBT masih terekspos terlalu luas (student schedule + tampilan UI default).
  4. FE export endpoint belum konsisten dengan arsitektur same-origin /api.
  5. Capability student CBT belum seragam antara menu dan route.
  6. Admission CBT masih berpotensi punya dua sumber kebenaran (halaman CBT umum vs jadwal SPMB).
  7. Proteksi CRUD question set perlu diperketat (khususnya delete saat sudah terpakai).
  8. Transparansi pipeline publish nilai sampai eRapor belum eksplisit di UI.

Target Architecture

  1. Backend sebagai security boundary utama (RBAC, deadline, token, publish).
  2. FE konsisten dengan kontrak backend, tidak menyimpan workaround endpoint.
  3. Ownership context tunggal:
  4. learning dari flow kelas/ulangan.
  5. admission dari jadwal SPMB.
  6. independent dari CBT center.
  7. 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:

  1. 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.
  2. 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.
  3. scola_cbt.group_cbt_grader tidak diberikan otomatis ke semua guru. Group ini disimpan untuk elevated/cross-context grading bila sekolah membutuhkan penugasan grader eksplisit.
  4. 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:

  1. group_cbt_exam_creator, group_cbt_proctor, dan group_cbt_grader adalah capability/entry-point role, bukan bukti final bahwa user boleh mengelola semua ujian.
  2. Otorisasi final untuk proctor dan grader membaca assignment per ujian:
  3. cbt_author_user_ids
  4. cbt_proctor_user_ids
  5. cbt_grader_user_ids
  6. Proctor console hanya menampilkan ujian yang dapat diproctor oleh user saat ini:
  7. CBT manager/admin akademik tetap full access.
  8. Panitia SPMB/admin admission dapat menangani context admission.
  9. Guru/staf biasa harus masuk cbt_proctor_user_ids pada ujian tersebut.
  10. Context admission tidak boleh lagi dibuat oleh generic teacher yang kebetulan memiliki group_cbt_exam_creator. Pembuatan SPMB CBT dibatasi ke panitia SPMB/admin admission/admin akademik/CBT manager.
  11. 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

  1. Standarisasi URL export CBT agar selalu via /api.
  2. Samakan capability route student CBT dengan capability menu student.
  3. Hardening tampilan token di FE: masked-by-default, reveal on demand.
  4. 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

  1. Hapus auto-grant group proctor/grader untuk semua teacher.
  2. Ubah rule exam creator agar tidak full-access seluruh exam untuk faculty.
  3. Tambah rule ketat untuk scola.cbt.attempt dan scola.cbt.attempt.answer scope per pemilik.
  4. 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

  1. Set attempt.end_time = min(now + duration, exam.end_time).
  2. Pastikan sync/answer tidak menerima jawaban saat waktu habis.
  3. 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

  1. Stop expose cbt_token pada student schedule API.
  2. Review kebutuhan token per context:
  3. Admission authenticated: optional bypass (sesuai kebijakan existing).
  4. Learning/independent: token sesuai policy.
  5. 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

  1. Tegaskan admission CBT dikelola dari jadwal SPMB.
  2. Halaman CBT umum untuk admission hanya read-only/deep-link ke SPMB bila perlu.
  3. 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

  1. Tampilkan status pipeline per exam:
  2. graded
  3. publish gradebook
  4. synced to eRapor
  5. Surface failure reason untuk publish/republish.
  6. 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:

  1. npm run lint
  2. npm run test
  3. npm run build
  4. Backend unit/integration test terkait module CBT/SPMB (saat patch backend)
  5. E2E smoke:
  6. learning CBT
  7. admission CBT
  8. publish nilai ke gradebook/eRapor

Batching Strategy

  1. Batch FE cepat: Phase 1.
  2. Batch backend security: Phase 2.
  3. Batch integrity timing/token: Phase 3-4.
  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, dan scola_report_card di 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.py
  • scola_cbt/controllers/exam.py
  • scola_cbt/controllers/exam_read_api.py
  • scola_cbt/controllers/exam_lifecycle_api.py
  • scola_cbt/controllers/exam_staff_api.py
  • scola_cbt/controllers/exam_lookup_api.py
  • scola_cbt/controllers/proctor.py
  • scola_cbt/controllers/proctor_read_api.py
  • scola_cbt/controllers/grading.py
  • scola_cbt/controllers/participant.py
  • Frontend:
  • src/services/cbt/examService.js
  • src/services/cbt/proctorService.js
  • src/views/ExamManagement/Faculty/Exam/CBTExamDetail.vue
  • src/views/ExamManagement/Faculty/Proctor/ProctorDashboard.vue

Validation tambahan yang wajib setelah deploy:

  1. Upgrade module scola_cbt agar field M2M staff assignment terbentuk.
  2. Login sebagai guru pembuat ujian: pastikan bisa grading own/assigned exam tetapi tidak bisa proctor jika belum ditugaskan.
  3. Assign guru sebagai proctor dari detail ujian, logout-login guru tersebut, lalu pastikan menu/route proctor hanya menampilkan ujian yang ditugaskan.
  4. 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.js
  • src/config/apps/appFragments/admissionsApp.js
  • src/config/apps/appFragments/adminStaffApp.js
  • src/views/ExamManagement/Faculty/Exam/CBTExamList.vue
  • src/views/ExamManagement/Faculty/Exam/CBTExamDetail.vue
  • src/views/ExamManagement/Faculty/Exam/CBTExamAnalytics.vue
  • src/views/ExamManagement/Faculty/Exam/CBTItemAnalysis.vue
  • src/views/ExamManagement/Faculty/Exam/CBTIntegrityReport.vue
  • src/views/ExamManagement/Faculty/Exam/GradingWorkspace.vue
  • src/views/ExamManagement/Faculty/Proctor/ProctorDashboard.vue
  • tests/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:

  1. Jalankan E2E browser sebagai admin staff/SPMB:
  2. buka /admin-staff/admissions/cbt/exams
  3. buat CBT admission
  4. assign author/proctor/grader
  5. buka /admin-staff/admissions/cbt/proctor
  6. nilai attempt admission melalui route grading SPMB
  7. Ulangi sebagai admin pada /admin/spmb/cbt/exams dan /admin/spmb/cbt/proctor.
  8. Upgrade module scola_cbt tetap 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.py
  • scola_cbt/tests/test_question_set_contract_unit.py
  • scola_cbt/__manifest__.py versi 17.0.1.0.10

Validation yang sudah dijalankan:

  • FE route local vs remote backend:
  • /admin/spmb/cbt/exams — opened, menampilkan Ujian CBT SPMB.
  • /admin/spmb/cbt/proctor — opened, menampilkan Proctor CBT SPMB.
  • /admin-staff/admissions/cbt/exams — opened, menampilkan Ujian CBT SPMB.
  • /admin-staff/admissions/cbt/proctor — opened, menampilkan Proctor 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:

  1. Re-run /api/scola_cbt/question_set/list sebagai admin_staff; harus mengembalikan bank soal aktif.
  2. Re-run create admission CBT sebagai budi.santosa; harus gagal dengan pesan guard admission context.
  3. Re-run smoke penuh:
  4. admin staff create CBT admission dari UI route SPMB,
  5. assign author/proctor/grader,
  6. sync peserta dari jadwal SPMB,
  7. start dan submit attempt admission,
  8. buka grading route SPMB admin/admin staff,
  9. finalize grading,
  10. 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_cbt versi 17.0.1.0.10

Koreksi data user:

  • budi.santosa bukan guru generic untuk negative RBAC test. Di dev user ini punya role privileged termasuk Administrator, Back Office Admin, Scola Admin, Settings, CBT Exam Creator, CBT Proctor, CBT Grader, dan CBT Auditor.
  • abdur.kodar juga tidak valid sebagai generic teacher untuk smoke remote: password seed teacher123 ditolak dan user tetap punya group Administrator.
  • 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 — render Ujian CBT SPMB.
  • /admin/spmb/cbt/proctor — render Proctor CBT SPMB.
  • /admin-staff/admissions/cbt/exams — render Ujian CBT SPMB.
  • /admin-staff/admissions/cbt/proctor — render Proctor CBT SPMB.
  • Negative admission create:
  • temporary low-privilege teacher ditolak saat POST /api/scola_cbt/exams/create dengan exam_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 akhir done
  • 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, slot attendance_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:

  1. Backend grading RBAC:
  2. Patch scola_cbt/controllers/grading_read_api.py agar exam dibaca dengan sudo setelah endpoint menerima exam_id, lalu _check_teacher_access(exam) menjadi satu-satunya gate policy.
  3. Search attempt/answer memakai _cbt_sudo_model() setelah gate lulus, dengan domain exam_id = target exam.
  4. Patch grading_write_api.py dengan pola sama untuk score/finalize operation.
  5. Backend security rules:
  6. Tambahkan record rule atau controller-scoped sudo untuk scola.cbt.attempt, scola.cbt.attempt.answer, dan scola.cbt.score.revision bagi assigned grader/proctor.
  7. Audit ulang apakah group_cbt_grader global masih boleh full grading. Jika tetap ada, batasi ke user operasional khusus; assignment per exam tidak boleh menjadi full-school grader.
  8. Staff assignment behavior:
  9. 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.
  10. Create transaction hardening:
  11. Tambahkan pre-validation untuk exam_code, min_marks, total_marks, state schedule, dan overlap sebelum create.
  12. Bungkus route create dengan savepoint agar failed response tidak meninggalkan draft record.
  13. Remote seed data:
  14. Sediakan akun guru generic non-admin khusus QA, misalnya teacher.cbt.e2e, tanpa Back Office/Scola Admin/Settings/CBT Manager.
  15. Gunakan akun ini untuk regression smoke negative RBAC tanpa membuat temporary user setiap run.
  16. Re-run setelah backend patch:
  17. negative generic teacher admission create,
  18. assigned grader sees only assigned exam attempts,
  19. assigned grader cannot access unrelated exam attempts,
  20. SPMB CBT smoke end-to-end sampai grading attempt visible, sync result, dan exam done.