Integrasi Sejoli Tryout

Pembagian role dan kontrak integrasi antara yellow-bank-soal dan plugin sejoli-tryout (WordPress).

Pembagian Role dengan sejoli-tryout

Integrasi belum aktif di sejoli-tryout. Halaman ini menggambarkan rencana pembagian tanggung jawab (sesuai SEJOLI_TRYOUT_INTEGRATION.md).

Prinsip Umum

  • Sejoli/WordPress = source of truth untuk: pembelian, kepemilikan produk, quota attempt, autentikasi siswa sebelum sesi dimulai.
  • yellow-bank-soal (App) = source of truth untuk: pengiriman soal, scoring, data audit, dan record attempt.

Tabel Pembagian Tanggung Jawab

AktivitasSejoli / WordPressyellow-bank-soal
Autentikasi siswa (login WP)✅ Sumber utamaVerifikasi via POST /api/v1/wordpress/verify_session
Verifikasi token WP✅ Validasi JWT WP
Pengecekan kepemilikan produk
Pengurangan quota attempt❌ (hanya catat metadata entitlement)
Penentuan attempt_number berikutnya
Validasi pembayaran/order
Identitas multi-tenant (website_id)✅ Pemilik mapping✅ Isolasi data via X-Website-ID
Pemilihan soal (fixed/adaptive/hybrid)
Penyimpanan & pengiriman soal
Perhitungan CTT (p, Bobot, NM, NN)
Kalibrasi IRT (b, SE)
Estimasi theta siswa (θ)
Pembuatan soal AI
Impor/ekspor Excel
Penyimpanan jawaban siswa✅ (UserAnswer)
Penyimpanan snapshot identitas & order✅ (audit)
Penilaian akhir & tampilan hasil
Laporan performa siswa & analisis soal
Manajemen admin (CRUD tryout/soal)✅ (admin app)

Diagram Alur Integrasi (Visi Pola B)

Status: planned — lihat Gap Analysis untuk status implementasi endpoint.

Setelah integrasi penuh, Sejoli Tryout adalah UI yang siswa lihat (tidak redirect, tidak iframe app). Setiap klik "Next" memicu Sejoli call API app untuk dapat soal berikutnya. App = backend headless; Sejoli = full UI (render, navigasi, timer).

sequenceDiagram
    autonumber
    participant Siswa
    participant Sejoli as Sejoli Tryout UI
    participant App as yellow-bank-soal API

    Siswa->>Sejoli: Buka halaman ujian
    Sejoli->>Sejoli: Cek entitlement & attempt tersisa
    Sejoli->>App: POST /wordpress/verify_session
    App-->>Sejoli: app access token

    Sejoli->>App: POST /session/ start attempt
    Note over Sejoli,App: Format session_id: sejoli-tryout_id-wp_user_id-attempt_number
    App-->>Sejoli: session_id + konfigurasi tryout

    loop Setiap soal selama tryout
        Siswa->>Sejoli: Klik Next
        Sejoli->>App: POST /session/id/next_item
        Note over App: Algoritma pilih soal berdasarkan mode
        App-->>Sejoli: 1 soal terpilih
        Sejoli-->>Siswa: Render soal itu saja
        Siswa->>Sejoli: Jawab
        Sejoli->>App: POST /session/id/answer
        Note over App: Update theta real-time, cek terminasi
    end

    Siswa->>Sejoli: Selesai atau waktu habis
    Sejoli->>App: POST /session/id/complete
    App-->>Sejoli: NM, NN, theta, hasil
    Sejoli-->>Siswa: Tampilkan hasil

    Note over Sejoli,App: App tidak decrements quota. Sejoli pemilik keputusan boleh mulai lagi.

Prinsip Kunci

  • Sumber soal utama = App DB. Soal di plugin Sejoli hanya fallback saat app unavailable.
  • Soal dipilih per-request, bahkan di mode fixed — karena app perlu pilih varian level Sedang/Mudah/Sulit untuk personalisasi.
  • Tidak ada pre-bundle tryout di awal sesi. Yang di-preload cuma konfigurasi + pool soal tersedia.
  • Theta diupdate real-time setiap jawaban (kritis untuk mode adaptive).
  • Sejoli pegang state UX (timer, localStorage, navigasi). App pegang state scoring.

Kontrak Identitas

  • Kunci identitas kanonik: wp_user_id + website_id.
  • Field opsional tapi disarankan untuk admin search & laporan: user_email (di-lowercase), user_display_name, user_login.
  • String identitas kosong diperlakukan sebagai missing.
  • session_id harus unik. Rekomendasi format: sejoli-{tryout_id}-{wp_user_id}-{attempt_number} (+ suffix bila perlu).

Urutan Plugin Sejoli (Rekomendasi)

  1. Konfirmasi user WP login punya entitlement Sejoli valid untuk tryout.
  2. Hitung attempt_number berikutnya yang diizinkan.
  3. Verifikasi token WP ke /wordpress/verify_session.
  4. Mulai sesi app via POST /session/ dengan metadata identitas & entitlement.
  5. Render UI ujian di Sejoli (timer, navigasi, layout) — bukan redirect.
  6. Setiap klik Next: call POST /session/{id}/next_item, render soal yang diberikan app.
  7. Setiap jawaban: call POST /session/{id}/answer, app update theta real-time.
  8. Saat selesai: call POST /session/{id}/complete, tampilkan hasil di Sejoli.

Endpoint next_item dan answer belum ada di app — lihat Gap Analysis Gap 1 & 2.

Last updated Jul 25, 2026