Lewati ke isi

SPMB Tests · CBT · Ranking · Penerimaan · Pengumuman — Audit & Gap Analysis

Status: Audit dokumen (read-only, no code changes). Sumber: source code FE scola-fe-v2 + BE scola-odoo-module (tag/branch develop per Apr 2026), Permendikdasmen No. 3 Tahun 2025, dan Surat Edaran Dirjen PAUD Dikdasmen No. 0301/C/HK.04.01/2026.

Pendamping: Implementation plan di docs/implementation/spmb-tests-cbt-ranking-plan.md. Audit lama spmb-flow-audit.md (wizard/upload) tetap berlaku — dokumen ini melengkapi.

Lingkup: 5 domain — Tes Masuk, CBT, Penilaian/Ranking, Penerimaan/Daftar Ulang, Pengumuman. Lintas-repo (FE + BE).


1. Latar & Scope

1.1 Mengapa audit ini ada

Audit spmb-flow-audit.md (Q1 2026) fokus pada wizard registrasi & upload dokumen. Bagian downstream — tes masuk, eksekusi CBT, skoring, ranking, penerimaan, pengumuman — belum punya audit terkonsolidasi. Beberapa indikasi gap muncul saat refactor menu v2 dan smoke test admin SPMB: - SPMBCBTRunner route tidak ada → klik "Mulai CBT" crash. - /spmb/dashboard di-redirect dari SPMBDaftarUlang.vue setelah enrollment confirm → 404. - Tidak ada UI proctor / pewawancara / grader esai untuk SPMB. - FE pendaftar tampilkan tab "Tes Masuk" walau register tidak punya jadwal (variant tanpa tes).

1.2 Ruang lingkup audit

Domain FE BE Endpoint
Tes Masuk (jadwal & kehadiran) Public/SPMBTestSchedule.vue, Public/SPMBAdmissionDetail.vue spmb_api.py::get_my_test_schedules; scola_admission/models/admission_test.py (test_type, schedule, slot, result); overlay scola_admission_assessment /api/SPMB/my/test-schedules, /api/SPMB/test-schedules* (admin)
CBT (start & runner) Public/SPMBCBTStart.vue, hilang SPMBCBTRunner.vue scola_cbt/models/{exam,attempt,participant,question}.py + scola_admission_assessment::cbt_participant.py belum ada endpoint pendaftar untuk launch/submit
Penilaian (rapor + achievement + tes) Public/SPMBAdmissionDetail.vue, services/spmb/spmb.service.js (saveRaporGrades, getMyTestResults) spmb_api.py::get_my_test_results, admission.py::_compute_total_test_score, _compute_ranking_score /api/SPMB/my/test-results
Ranking AdmissionApplicationList.vue, RankingList.vue (admin) spmb_complaints_ranking_api.py::ranking_list, ranking_update_status; admission.py::action_calculate_ranks /api/SPMB/ranking, /api/SPMB/ranking/update-status
Penerimaan / Daftar Ulang Public/SPMBDaftarUlang.vue, services/spmb/spmbEnrollment.service.js spmb_api.py::confirm_enrollment, get_admission_invoice, create_admission_invoice /api/SPMB/my/admission/confirm-enrollment, /api/SPMB/my/admission/invoice*
Pengumuman components/spmb/SPMBAnnouncementBanner.vue, Public/SPMBStatusCheck.vue spmb_api.py::get_selection_result, get_public_status /api/SPMB/selection/result, /api/SPMB/public/status

2. Inventaris

2.1 FE Vue Components / Routes (pendaftar portal)

File Role Route Catatan
src/views/AdmissionManagement/Public/SPMBAdmissionDetail.vue pendaftar /spmb/admission/:id Hub utama: mengandung SPMBAnnouncementBanner, jadwal tes, dokumen, status
src/views/AdmissionManagement/Public/SPMBTestSchedule.vue pendaftar /spmb/admission/:id/test-schedule Listing jadwal tes; tombol "Mulai CBT" → SPMBCBTRunner (route tidak ada)
src/views/AdmissionManagement/Public/SPMBCBTStart.vue pendaftar belum terdaftar Orphan; router.push('/spmb/dashboard') ke route mati
src/views/AdmissionManagement/Public/SPMBDaftarUlang.vue pendaftar /spmb/admission/:id/enrollment Konfirmasi enrollment → redirect /spmb/dashboard (mati)
src/views/AdmissionManagement/Public/SPMBStatusCheck.vue publik (no auth) /spmb/status-check Cek status by application number
src/components/spmb/SPMBAnnouncementBanner.vue shared embed Banner accepted/rejected/pending + jadwal tes
src/components/spmb/SPMBNotificationBell.vue shared embed Listing notifikasi portal
src/components/spmb/SPMBCountdownTimer.vue shared embed Countdown enrollment deadline

2.2 FE Services

File Methods relevan
src/services/spmb/spmb.service.js getAdmissionDetail, submitAdmission, confirmEnrollment, getMyTestSchedules, getMyTestResults, getSelectionResult, saveRaporGrades
src/services/spmb/spmbEnrollment.service.js getSpmbEnrollmentInvoice, createSpmbEnrollmentInvoice
src/services/spmb/spmbPublicStatus.service.js checkPublicStatus (sudah ada vitest contract)

2.3 BE Models utama

Model File Purpose
op.admission openeducat_admission + scola_admission/models/admission.py Record pendaftaran utama; punya state, ranking_score, rank_in_pathway, total_test_score
op.admission.register openeducat_admission Periode SPMB (gelombang); punya pathway_quota, registration_fee
op.admission.pathway scola_admission Jalur (domisili/afirmasi/prestasi/mutasi); kode pathway dipakai di _compute_ranking_score
scola.admission.test.type scola_admission/models/admission_test.py Jenis tes (kode, durasi, max_score, weight, is_required)
scola.admission.test.schedule scola_admission + overlay scola_admission_assessment Jadwal tes; overlay menambah cbt_exam_id, cbt_participant_count, cbt_last_synced_at
scola.admission.test.slot scola_admission + overlay Slot peserta per jadwal; punya attendance_status, attendance_time, score; overlay menambah cbt_participant_id, cbt_last_attempt_id
scola.admission.test.result scola_admission Summary skor per admission × test_type; punya weighted_score (computed)
op.exam (CBT) scola_cbt/models/exam.py Exam header; punya exam_context (learning/admission/independent), is_cbt
scola.cbt.participant scola_cbt/models/participant.py Peserta CBT; bisa identity_type=admission dengan FK admission_id
scola.cbt.attempt scola_cbt/models/attempt.py Attempt (jawaban + skor); state submitted/graded

2.4 BE Endpoints (controller)

Endpoint Auth File
/api/SPMB/my/test-schedules user (pendaftar) spmb_api.py::get_my_test_schedules
/api/SPMB/my/test-results user spmb_api.py::get_my_test_results
/api/SPMB/my/admission/confirm-enrollment user spmb_api.py::confirm_enrollment
/api/SPMB/my/admission/invoice user spmb_api.py::get_admission_invoice
/api/SPMB/my/admission/invoice/create user spmb_api.py::create_admission_invoice
/api/SPMB/selection/result user spmb_api.py::get_selection_result
/api/SPMB/public/status public spmb_api.py::get_public_status
/api/SPMB/test-schedules* (overloaded) user (admin) spmb_complaints_ranking_api.py::test_schedule_* (overlay overrides type='json')
/api/SPMB/ranking, /api/SPMB/ranking/update-status user (admin) spmb_complaints_ranking_api.py
/api/SPMB/complaints/* user spmb_complaints_ranking_api.py

3. Data Flow Diagram (tekstual)

                       ┌──────────────────────────────────────────────────────┐
                       │                ADMIN SPMB SETUP                      │
                       │                                                      │
                       │  op.admission.register   ──┬── pathway_quota         │
                       │                            └── registration_fee      │
                       │  scola.admission.test.type ─── (CBT|Tulis|Wawancara) │
                       │  op.exam (is_cbt, exam_context='admission')          │
                       │  scola.admission.test.schedule ─── cbt_exam_id?      │
                       └────────────┬─────────────────────────────────────────┘
                                    │
                                    ▼
PENDAFTAR  ── register ──► op.admission (draft)
                │                │
                │ submit form    │  upload doc + rapor + achievement
                ▼                ▼
            (state=submit)
                │
                │ admin verify + invoice biaya pendaftaran (opsional)
                ▼
            (state=confirm)
                │
                │ admin assign slot per schedule (auto-sync ke scola.cbt.participant kalau CBT)
                ▼
            scola.admission.test.slot ─────► scola.cbt.participant (kalau V1)
                │                                    │
                │ HARI-H tes                         │
                │  V1 (CBT): pendaftar attempt       │
                │  V2 (tulis): hadir + jawab kertas  │
                │  V3 (wawancara): rubrik            │
                │                                    ▼
                │                            scola.cbt.attempt (state=submitted)
                │                                    │
                │ admin/sistem score+attendance ─────┘
                ▼
            scola.admission.test.slot.score
                │ rollup
                ▼
            scola.admission.test.result.weighted_score
                │ rollup
                ▼
            op.admission.total_test_score
                │ + rapor_average + total_achievement_score + distance_to_school
                ▼
            op.admission.ranking_score (compute per pathway formula)
                │ admin: action_calculate_ranks
                ▼
            op.admission.rank_in_pathway
                │ admin set hasil per kandidat
                ▼
            (state=admission|reject|pending)
                │ scheduled release saat announcement_at (gap)
                │ notif portal+email
                ▼
            PENDAFTAR lihat banner pengumuman
                │ kalau diterima:
                ▼
            stage daftar ulang (dok + invoice + confirm)
                ▼
            (state=done) ───► confirm_enrollment ───► op.student

4. Variasi Metode Seleksi (Selection Variants)

Tes masuk TIDAK WAJIB. Sistem mendukung kombinasi berikut, ditentukan implisit dari setup data:

Variant Metode Komponen Skor Stage Tes (8) Stage Skoring (9)
V1 Full CBT online total_test_score (weighted) Pendaftar via runner CBT Auto via _sync_from_cbt_attempts
V2 Tes tulis manual (PBT) total_test_score (weighted) Hadir lokasi, jawab kertas, panitia koreksi Admin input slot.score manual
V3 Wawancara total_test_score dengan test_type ber-rubrik wawancara Hadir slot, pewawancara nilai Pewawancara input score manual
V4 Hybrid (CBT + wawancara, tulis + wawancara, dll) Sum weighted_score semua test_type Pendaftar ikuti semua jadwal Auto (CBT) + manual
V5 Tanpa tes — administrative only total_test_score=0, sisanya rapor + achievement + jarak (sesuai pathway formula) DILEWATI Auto via _compute_ranking_score
V6 Portfolio / berkas total_achievement_score + verifikasi manual DILEWATI Admin proxy via test_result atau adjust achievement

Pemilihan variant saat ini implisit dari: - Ada/tidaknya scola.admission.test.schedule per register × pathway (kosong → V5/V6) - cbt_exam_id di-set atau null (kosong → V2/V3/V4 manual) - pathway.code di _compute_ranking_score (domisili/afirmasi/prestasi/mutasi punya formula khusus; "else" hanya pakai tes)


5. Role Mapping (BE-authoritative + FE Scola UX)

SSOT: BE Odoo groups (authoritative) + mapping FE Scola role untuk navigasi/UX.

5.1 Pembuat soal CBT (Question Bank)

Aktivitas BE group FE Scola role Bukti
Buat bank soal & choice scola_cbt.group_cbt_exam_creator (own) + group_cbt_manager (semua) teacher, homeroom, admin, head_admin (capability academics.question_bank.manage) scola_cbt/security/cbt_security.xml:13-19; FE teacherPortalApp.js "Bank Soal"
Buat blueprint / question_set group_cbt_exam_creator + group_cbt_manager sama cbt_security.xml:14-19

Catatan: untuk konteks admission (exam_context='admission'), question bank tetap dibuat oleh CBT Exam Creator. Belum ada role khusus "SPMB Question Author" — risiko: guru biasa bisa lihat/buat soal tes masuk. SOP belum dokumentasikan.

5.2 Pembuat jadwal tes SPMB

Aktivitas BE group FE Scola role
Buat scola.admission.test.schedule openeducat_admission.group_op_admission_admin (di-bridge dari group_scola_admin, group_scola_admin_staff, group_scola_head_admin) admin, admin_staff, head_admin (capability admissions.schedule.view/manage)
Buat scola.admission.test.type sama sama

Sumber bridge: scola_admission/security/scola_admission_security.xml:11-21. Tidak ada role granular "Panitia SPMB" — semua admin staff sama level.

5.3 Pengisi kehadiran peserta tes

Aktivitas BE group FE Scola role Bukti
action_mark_present / action_mark_absent slot group_op_admission_admin admin, admin_staff, head_admin scola_admission/models/admission_test.py:213-220
Sync attendance dari CBT attempt sistem (sudo) sistem scola_admission_assessment/models/admission_test.py:269

Gap: tidak ada role "Pengawas/Proctor SPMB" terpisah. CBT punya group_cbt_proctor tapi tidak diaktifkan untuk konteks admission. UI live monitor sesi belum ada di FE.

5.4 Penghubung soal CBT ↔ jadwal tes masuk

Aktivitas BE group FE Scola role
Set cbt_exam_id di schedule group_op_admission_admin admin, admin_staff, head_admin
Sync slot → scola.cbt.participant (auto on create/write) sistem sistem
Sync hasil CBT → score slot (manual / cron) group_op_admission_admin sama

Gap critical: pembuatan op.exam ber-exam_context='admission' butuh group_cbt_exam_creator ATAU group_cbt_manager. Admin SPMB tidak otomatis punya CBT Exam Creator (tidak ada bridge XML). Constraint: cbt_security.xml belum bridge ke group_scola_admin_staff/head_admin.

5.5 Pendaftar mengerjakan CBT

Aktivitas BE group FE Scola role
Login portal SPMB base.group_portal + role custom pendaftar
Mulai exam (scola.cbt.attempt) record rule via participant.user_id pendaftar

Gap: FE runner CBT pendaftar belum ada (lihat F-001 di gap matrix).

5.6 Penilai esai (manual scoring)

Aktivitas BE group FE Scola role
Grade essay/manual question group_cbt_grader belum di-bridge ke role Scola apapun

Gap: untuk SPMB, tidak jelas siapa yang grade esai. UI grading di FE Scola belum ada.

5.7 Audit / read-only

Aktivitas BE group FE Scola role
Lihat audit log CBT group_cbt_auditor, group_cbt_manager belum di-bridge
Lihat ranking & seleksi (read) group_op_admission_user (di-bridge ke group_scola_principal) principal, plus admin

5.8 Aktor E2E SPMB

Aktor Role Scola BE group Tanggung Jawab
Calon siswa / orang tua pendaftar base.group_portal + portal pendaftar Daftar akun, isi formulir, upload dok, kerja CBT, daftar ulang
Admin SPMB / Panitia admin_staff, head_admin group_op_admission_admin (bridged) Buka register, buat jadwal tes, verifikasi dok, isi kehadiran, hitung ranking, umumkan
Pembuat soal CBT teacher / admin_staff group_cbt_exam_creator (need bridge) Tulis question bank, blueprint, link ke exam
Pengawas / Proctor belum ada role spesifik group_cbt_proctor (belum aktif untuk SPMB) Monitor sesi CBT, force submit, perpanjang waktu
Pewawancara belum ada role spesifik belum ada Wawancara V3
Grader esai belum ada role spesifik group_cbt_grader (belum aktif untuk SPMB) Nilai jawaban esai manual
Treasurer / Keuangan treasurer, vice_principal_finance scola_finance + accounting Validasi pembayaran biaya pendaftaran & daftar ulang
Kepala Sekolah principal group_op_admission_user (read) Approve hasil seleksi
Foundation foundation_chairman group_op_admission_user (read) Oversight
Sistem / Cron system sudo Kirim notif, sync CBT result, lock/unlock pengumuman

6. E2E Workflow (14 Stage, dengan branching variant)

# Stage Aktor primer Aksi Endpoint / Komponen State op.admission
1 Setup periode Admin SPMB Buat op.admission.register + pathway_quota + registration_fee + (gap) announcement_at /admin/spmb/periode n/a
2 Setup metode seleksi (opsional, tergantung variant) Admin SPMB + Exam Creator V1: buat test_type + CBT exam + schedule + link cbt_exam_id. V2: test_type tulis + schedule (no CBT). V3: test_type wawancara + schedule (no CBT). V4: kombinasi. V5/V6: skip. /admin/spmb/test, /faculty/question-bank n/a
3 Pendaftar register akun Calon siswa Form register → OTP email /api/SPMB/account/register, verify-email n/a
4 Buat admission Pendaftar Login → pilih register & pathway → submit form data pribadi /api/SPMB/my/admission/create draft
5 Lengkapi & submit Pendaftar Upload dokumen, isi rapor, achievement → submit /api/SPMB/my/admission/submit draft → submit
6 Verifikasi & invoice biaya pendaftaran (opsional, gap A17) Admin SPMB + Treasurer Admin verifikasi dok, generate invoice (jika is_paid_admission); pendaftar bayar confirm_in_progress, /api/SPMB/my/admission/invoice submit → confirm
7 Assign jadwal tes (skip jika V5/V6) Admin SPMB Buat slot. V1: auto sync slot → cbt.participant. V2-V4 manual: cukup slot. admin Test Schedule UI confirm
8 Hari-H tes (skip jika V5/V6) Pendaftar + Proctor/Pewawancara V1: runner CBT (gap). V2: tandai kehadiran + jawab tulis. V3: rubrik wawancara (gap UI). V4: kombinasi. gap Phase 2 confirm
9 Skoring & ranking Sistem + Admin SPMB V1: auto-sync. V2/V3: input manual (gap UI). V5/V6: skip skoring tes. _compute_ranking_score auto, admin klik "Hitung Ranking" → action_calculate_ranks. /api/SPMB/ranking confirm
10 Approve & umumkan Principal + Admin SPMB Principal review, admin set hasil per admission, sistem cron release saat announcement_at (gap), notif portal+email. admission_confirm, confirm_rejected confirm → admission atau reject
11 Daftar ulang & invoice Pendaftar + Treasurer Pendaftar lihat banner, sistem buat invoice, pendaftar bayar+upload dok+konfirmasi confirm-enrollment, invoice/create admission → done
12 Konversi ke siswa Sistem confirm_enrollment membuat op.student, assign batch, generate NIS confirm_enrollment done
13 (Opsional) Sanggah / banding Pendaftar + Admin SPMB Pendaftar buat complaint; admin proses (process → resolve/reject) /api/SPMB/complaints/* tidak berubah
14 (Opsional) Reapply Pendaftar Ditolak → reapply ke register lain /api/SPMB/my/admission/reapply new admission draft

Decision Gates

  • Gate 1 (post-5): dokumen wajib lengkap → admin verify; bila gagal status balik draft + alasan.
  • Gate 2 (post-6): invoice biaya pendaftaran lunas (jika is_paid_admission) → admin assign jadwal (V1-V4) atau langsung skoring (V5/V6).
  • Gate 3 (post-8): kondisional per variant — V1-V4 kehadiran & skor terisi; V5/V6 rapor & achievement terverifikasi → ranking compute.
  • Gate 4 (post-10): approve principal + tanggal pengumuman tercapai → state release.
  • Gate 5 (post-11): dok daftar ulang lengkap + invoice lunas → confirm_enrollment diizinkan.

Notifikasi (existing vs gap)

Trigger Channel Status
Admission confirmed (post 6) Portal + email ✅ ada (admission_confirmed)
Test schedule assigned (7) Portal ✅ ada (admission_test_scheduled)
Result released (10) Portal + email ⚠️ partial (admission_accepted ada tapi tanpa scheduled release)
Enrollment deadline reminder (11) Portal + email + WA ❌ gap
Waitlist promoted Portal + email ❌ gap

7. Gap Matrix

Severity: Critical (broken/blocking) | High (kontrak FE↔BE timpang / regulasi) | Medium (UX/resilience) | Low (cleanliness)

7.1 FE/BE Functional Gaps

ID Sev Domain Finding Bukti Owner
F-001 Critical CBT SPMBCBTRunner route name dirujuk dari SPMBTestSchedule.vuerouter.push({ name: 'SPMBCBTRunner' }) tapi tidak terdaftar di src/router/spmbRoutes.js. Klik "Mulai CBT" → router warning + UI dead-end. SPMBTestSchedule.vue:74 FE
F-002 Critical Penerimaan /spmb/dashboard tidak terdaftar di router. Dirujuk dari SPMBCBTStart.vue:15 & SPMBDaftarUlang.vue:582 setelah confirmEnrollment sukses → 404. SPMBDaftarUlang.vue:582 FE
F-003 Critical CBT SPMBCBTStart.vue orphan: dipanggil dengan name: 'SPMBCBTStart' dari SPMBTestSchedule.vue:272 tapi router tidak punya entry untuk komponen ini. SPMBTestSchedule.vue:272 FE
F-004 Critical CBT Tidak ada FE runner CBT pendaftar + tidak ada BE endpoint launch/save-answer/submit untuk pendaftar. Kontrak cbt_launch.enabled ada di response BE tapi target endpoint untuk start session belum eksis. Best practice CBT (anti-cheat, auto-save, time sync, integrity token) belum diadopsi. spmb_complaints_ranking_api.py (admin only); search FE: tidak ada SPMBCBTRunner.vue FE+BE
F-005 High Tes Masuk schedule.attendance_status digunakan FE (SPMBTestSchedule.vue); _schedule_to_dict BE belum konfirmasi mengembalikan field ini untuk pendaftar (route get_my_test_schedules). Risk: undefined → label tampil mentah. SPMBTestSchedule.vue consumer BE
F-006 High Penilaian testResults.total_test_score & result.weighted_score dipakai FE; perlu sinkron dengan schema scola.admission.test.result. Bila tidak selalu disertakan, tabel tampil 0. getMyTestResults consumer BE
F-007 High CBT schedule.cbt_launch.return_to diasumsikan FE; perlu konfirmasi BE menyertakan saat schedule sync ke cbt_exam. launchCbt di FE BE
F-008 High Penilaian Komponen skor ranking tidak transparan ke pendaftar — ranking_score hanya angka final di Detail; tidak ada breakdown rapor/achievement/test. Tidak memenuhi prinsip transparansi Permendikdasmen. SPMBAdmissionDetail.vue FE+BE
F-009 High Pengumuman Pengumuman hasil tidak punya scheduled release. State berubah segera setelah admin update; tidak ada announcement_at / locking di BE. Tidak ada countdown pre-announcement di FE. admission.py (no announcement_at field) FE+BE
F-010 Medium Pengumuman SPMBAnnouncementBanner tidak menampilkan komponen waitlist promotion / refund flow. SPMBAnnouncementBanner.vue FE
F-011 Medium Penerimaan confirmEnrollment redirect ke route mati (/spmb/dashboard); FE belum punya success destination yang tahan banting. SPMBDaftarUlang.vue:582 FE
F-012 Medium Pengumuman Tidak ada notifikasi push/email saat ranking dirilis (BE punya notification_type_spmb tapi tidak di-trigger di state transition ke result). grep notification_type_spmb BE
F-013 Medium CBT SPMBCBTStart.vue dan SPMBTestSchedule.vue duplikat logika listing CBT (state, attendance config, formatDate). grep duplikasi FE
F-014 Medium QA testing-guidelines.md belum punya kontrak test untuk endpoint /api/SPMB/my/test-schedules, /api/SPMB/my/test-results, /api/SPMB/selection/result. Tidak ada vitest service contract. tests/unit/services/spmb/ FE
F-015 Medium Penilaian Admin SPMB tidak punya UI "input skor manual per slot" yang explicit untuk V2/V3 — saat ini hanya bisa via tree edit score di Odoo backend. grep admin FE FE
F-016 Medium Penilaian Tidak ada UI rubric scoring untuk wawancara (V3) — pewawancara harus mengetik angka mentah. n/a FE+BE
F-017 Medium Tes Masuk FE pendaftar tidak adaptif: tab "Tes Masuk" tampil walau register tidak punya schedule (V5/V6). Tampil "Belum ada jadwal" alih-alih "Pathway ini tidak memerlukan tes". SPMBAdmissionDetail.vue FE
F-018 Medium Penilaian _compute_ranking_score else-branch fallback hanya pakai tes — kalau pathway baru tanpa tes & kode tidak match domisili/prestasi/afirmasi/mutasi, ranking_score = 0 silently. admission.py:316 BE
F-019 Low Ranking Admin Ranking re-calc (AdmissionApplicationList.vue) panggil calculateRegisterRanks tanpa konfirmasi modal / audit trail. AdmissionApplicationList.vue FE+BE
F-020 Low Ranking PDF export ranking (generateRankingAnnouncementPDF) tidak punya watermark / metadata signer. grep export FE
F-021 Low Penerimaan Tidak ada idempotency/lock pada confirm_enrollment BE (potensi double-click race). spmb_api.py::confirm_enrollment BE

7.2 Role Gaps

ID Sev Finding Resolusi
R-001 High Tidak ada bridge group_scola_admin_staff/head_admingroup_cbt_exam_creator/group_cbt_manager. Admin SPMB tidak bisa buat CBT exam tanpa grant manual. Phase 7
R-002 Medium Tidak ada role granular "Panitia SPMB" / "Proctor SPMB" / "SPMB Question Author". Phase 7 (opsional)
R-003 Medium group_cbt_proctor tidak dipakai di konteks admission (UI proctor SPMB belum ada). Phase 7
R-004 Medium group_cbt_grader tidak terhubung ke FE Scola — manual scoring esai SPMB tidak punya UI. Phase 7
R-005 Low FE roleApps.js tidak ada konfigurasi khusus untuk SPMB committee. Phase 7

7.3 Variant Gaps

ID Sev Finding Resolusi
V-Gap-1 High Tidak ada field eksplisit selection_method (enum) di op.admission.register atau op.admission.pathway. Risiko mis-config & sulit audit. Phase 8
V-Gap-2 Medium FE pendaftar tidak adaptif terhadap V5/V6 (lihat F-017). Phase 8
V-Gap-3 Medium _compute_ranking_score else-branch silent zero (lihat F-018). Phase 5
V-Gap-4 Medium Admin tidak punya UI input skor manual untuk V2/V3 (lihat F-015). Phase 3
V-Gap-5 Medium Tidak ada UI rubric scoring untuk wawancara V3 (lihat F-016). Phase 3

7.4 Regulatory Gaps (Permendikdasmen 3/2025)

ID Sev Aspek Status Resolusi
Reg-1 High Tie-breaker jenjang-aware (SD: usia→jarak; SMP: jarak→usia; SMA: TKA→jarak→usia) ❌ tidak ada Phase 8
Reg-2 High Domisili by wilayah administrasi (kelurahan/kecamatan), bukan jarak murni ❌ tidak ada (distance_to_school only) Phase 8
Reg-3 Medium Validasi kuota minimum jenjang (SD ≥70%/SMP ≥40%/SMA ≥30% domisili dst.) ❌ tidak ada Phase 8
Reg-4 Medium Validasi kk_issued_date ≥ 1 tahun, achievement_date ≤ 3 tahun, rapor 5 semester ⚠️ field ada, validasi belum Phase 5 / 8
Reg-5 Medium Flag is_paid_admission (sekolah negeri dilarang pungut biaya pendaftaran) ❌ tidak ada Phase 8
Reg-6 Medium Public quota monitor (transparansi daya tampung) ❌ tidak ada Phase 8
Reg-7 Low Validasi DTKS afirmasi ❌ tidak ada (manual verify only) Phase 7 backlog
Reg-8 Low Penyaluran murid tertolak ke sekolah lain (untuk pemda) ❌ tidak ada Phase 6 backlog
Reg-9 Low Integrasi Dapodik (untuk pemda) ❌ tidak ada backlog
Reg-10 Low Terminologi PPDB → SPMB consistency ⚠️ mixed backlog

8. Best Practice Reference

8.1 Permendikdasmen No. 3 Tahun 2025 — Highlights

  • 4 jalur wajib: Domisili, Afirmasi, Prestasi, Mutasi.
  • Kuota minimum acuan nasional:
  • Domisili: SD ≥70%, SMP ≥40%, SMA ≥30%
  • Afirmasi: SD ≥15%, SMP ≥20%, SMA ≥30%
  • Prestasi: SMP ≥25%, SMA ≥30% (tidak berlaku SD)
  • Mutasi: maks 5% semua jenjang
  • Domisili = wilayah administrasi, bukan zonasi jarak murni. Pemda boleh: (a) admin area, (b) radius, (c) metode lain.
  • Tie-breaker jenjang-aware (lihat tabel di bagian audit plan).
  • Validasi: KK ≥ 1 tahun, prestasi maks 3 tahun, rapor 5 semester.
  • Afirmasi pakai DTKS / bansos / kartu disabilitas, bukan SKTM kelurahan.
  • Prinsip wajib: objektif, transparan, akuntabel, berkeadilan, tanpa diskriminasi.
  • Pendaftaran daring paling lambat minggu pertama Mei (jenjang dasar/menengah negeri).

8.2 CBT Best Practice (UTBK/SNBT-style)

  • Anti-cheat: tab visibility detection, blur warn, fullscreen enforcement, copy-paste block, keyboard shortcut block, mouse leave warn, max N violations → auto-submit.
  • Auto-save: simpan jawaban tiap N detik atau saat blur.
  • Server time sync: hindari client-side timer manipulation; backend-authoritative.
  • Integrity token: signed JWT per attempt, validasi tiap save.
  • Resume support: kalau koneksi putus, attempt bisa dilanjutkan (state intermediate).
  • Logging: setiap event (start, answer, focus, submit) audit-logged.

8.3 Transparansi Skoring (PMB Public Sector)

  • Breakdown skor publik (rapor, achievement, test_total, weighted) per kandidat di portal pendaftar masing-masing.
  • Formula publik (read-only di footer pengumuman / link "Bagaimana skor dihitung").
  • Tie-breaker rule visible.
  • Dispute window (sanggah) ≥ 2 hari kerja setelah pengumuman.

8.4 Notifikasi & Komunikasi

  • Multi-channel mandatory untuk milestone kritis (assign jadwal, hasil, deadline daftar ulang): Portal + Email; WA opsional.
  • Idempotency_key per notif untuk hindari duplikat saat retry.
  • Email template branded + i18n.

9. Risk Register

ID Risk Likelihood Impact Mitigation
RK-1 Pendaftar klik "Mulai CBT" → crash; massa keluhan saat hari-H tes High Critical Phase 0 (route fix skeleton) sebelum periode SPMB aktif
RK-2 Setelah daftar ulang sukses, redirect 404 → pendaftar panik, support ticket banyak High High Phase 0
RK-3 Kontrak FE↔BE timpang → silent UI bug (label kosong, score 0) Medium Medium Phase 1 (contract test)
RK-4 CBT runner tanpa anti-cheat → integritas tes diragukan Medium Critical Phase 2 (anti-cheat hooks + audit log)
RK-5 Pengumuman bocor lebih awal (admin mengubah state sebelum tanggal) Medium High Phase 4 (announcement_at lock + cron release)
RK-6 Sekolah negeri pakai Scola tapi default ada registration_fee → pelanggaran regulasi Low Critical Phase 8 (is_paid_admission flag)
RK-7 Tie-breaker SMA tidak pakai TKA → ranking dibantah, sanggah massal Medium High Phase 8 (jenjang-aware tie-breaker)
RK-8 Domisili by jarak murni → tidak match juknis pemda 2026 Medium Medium Phase 8 (domicile_method)
RK-9 Race condition confirm_enrollment (double-click) → invoice/student dobel Low High Phase 4 (idempotency lock)

10. Out of Scope

  • Audit performa (backend query, FE bundle size).
  • Audit i18n / a11y SPMB pages.
  • Migrasi data SPMB lama (PPDB → SPMB schema).
  • Integrasi pembayaran provider baru (di luar invoice flow existing).
  • Audit security pen-test (di-handle Tier 2 audit terpisah).

11. Referensi

  • Permendikdasmen No. 3 Tahun 2025 — Sistem Penerimaan Murid Baru
  • Surat Edaran Dirjen PAUD Dikdasmen No. 0301/C/HK.04.01/2026
  • docs/qa/spmb-flow-audit.md — audit wizard/upload (existing)
  • docs/qa/spmb-end-to-end-uat.md — UAT skenario (existing)
  • docs/qa/testing-guidelines.md — kontrak test guidelines
  • docs/implementation/spmb-tests-cbt-ranking-plan.md — implementation plan (companion)