# 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) |