# Epik 2 — Tech Context: Assessment & Sertifikasi status: contexted phase: backend-planning note: Non-implementasi — konteks teknis & gating sebelum coding. ## Tujuan Menetapkan konteks teknis untuk Assessment & Sertifikasi: sesi ujian, penilaian, ringkasan hasil, dan kirim ulang email sertifikat (stub). ## Lingkup Teknis - Pembuatan & lifecycle sesi ujian - Endpoint penilaian jawaban (batch/stream) - Ringkasan hasil ujian (read-only) - Stub request resend email sertifikat (throttled, logged) ## Model Konseptual (Outline) - Exam: { id, title, questions[] } - ExamSession: { id, userId, examId, status, startTime, endTime } - Answer: { sessionId, questionId, choice, scoredAt } - Summary: { sessionId, totalScore, perQuestion[], duration } - Certificate: { id, userId, issueDate, templateRef } - ResendJob: { id, certificateId, recipientEmail, status, createdAt } ## Area API Terkait - POST /api/exam-session - POST /api/exam-session/{sessionId}/score - GET /api/exam-session/{sessionId}/summary - POST /api/certificates/{certificateId}/resend (stub) ## Acceptance Gates - Model sesi ujian, validasi dan lifecycle disetujui - Aturan penilaian & integritas data disepakati - Ringkasan hasil & akses kontrol disetujui - Template email, throttling & logging disetujui ## Dependencies - Ketersediaan daftar soal ujian (questions bank) - Integrasi dengan komponen sertifikat PDF (read-only) ## Risiko & Mitigasi - Beban scoring tinggi → pertimbangkan batch/stream & rate limit - Abuse resend email → throttling, audit log, anti-spam ## Contract Principle - Skema API/model/field mengikuti skema dummy frontend untuk area ujian. - Menghindari breaking change terhadap UI; perubahan mayor perlu versioning. - Field baru ditambahkan sebagai optional; validasi ketat setelah sinkronisasi. - Rujukan Exam: `src/app/exam-session/page.tsx`, `src/app/exam-summary/page.tsx`, `src/app/exams/page.tsx`. ## Catatan Dokumen konteks; implementasi backend ditunda sampai gate terpenuhi. ### Out-of-Scope (Eksplisit) - Integrasi email produksi (SMTP) di luar stub/throttling - Persistensi DB penuh sesi/hasil (pakai in-memory sementara) - Real-time scoring/streaming selain mode batch awal - Admin dashboard observabilitas ### NFR Ringkas (Reliability & Observability) - Logging terstruktur untuk create/score/summary/resend (requestId, sessionId) - Metrics: waktu proses scoring, error rate per endpoint, throttling hit - Alerting untuk lonjakan kesalahan `score`/`resend` - Audit trail untuk resend sertifikat (recipient, status, throttling) ### Dependencies (Versi Target) - Node.js `18.x`, Express `4.x`, Jest `29.x`, Supertest `6.x`, Nodemailer `6.x` ### Acceptance Criteria (Atomik & Testable) - POST `/api/exam-session` membuat sesi valid (validasi `examId`, `userId`); mengembalikan `sessionId` dan `startTime`. - POST `/api/exam-session/{sessionId}/score` menerima `answers[]` (MCQ dan union interaktif minimal) dan menghitung skor; idempotent via `idempotencyKey`. - GET `/api/exam-session/{sessionId}/summary` mengembalikan agregat skor dan `answers[].details` bila ada. - POST `/api/certificates/{certificateId}/resend` menerapkan throttling dan pencatatan audit; respons `202` atau `200` sukses. ### Test Strategy ↔ AC (Ringkas) - Unit: penilaian MCQ+interaktif (parser/scorer), util throttling/idempotency. - Integrasi: create session, score batch, summary read, resend stub. - Auth: header Bearer wajib untuk route ujian. - Observabilitas: verifikasi log/audit untuk resend dan idempotensi. ### Traceability Matrix (Ringkas) | AC ID | Spec Section | Components | Story | Tests | |------|---------------|-----------|-------|------| | E2-AC1 | Area API: POST /api/exam-session | server `server.js` | `docs/stories/2-1-exam-session-create-api.md` | `backend/tests/server.test.js` (create session) | | E2-AC2 | Scoring (batch+idempotency) | scorer util/server | `docs/stories/2-2-exam-scoring-api.md` | `backend/tests/server.test.js` (score + idempotency) | | E2-AC3 | Summary kompatibel + details | summary builder | `docs/stories/2-3-exam-summary-read-api.md` | `backend/tests/server.test.js` (summary) | | E2-AC4 | Resend throttled + audit | resend handler | TBD: `docs/stories/2-4-certificate-resend-api.md` | `backend/tests/server.test.js` (resend) |