| ο»Ώ# PRD: Pram β AI-Powered CPNS Test Practice Platform |
|
|
| ## Problem Statement |
|
|
| Calon Pegawai Negeri Sipil (CPNS) di Indonesia kesulitan menemukan soal latihan yang: |
| - **Bervariasi** dan mencakup format soal spesifik (TWK, TIU, TKP) |
| - **Terjangkau** β platform existing biasanya berbayar dan tidak fleksibel |
| - **Relevan** dengan kelemahan personal β tidak ada analisis per-section yang memberi rekomendasi perbaikan |
| - **Terbuka** β tidak ada platform open-source "bring your own key" untuk generasi soal AI |
|
|
| ## Solution |
|
|
| **Pram** adalah platform open-source yang menyediakan: |
| 1. **AI Question Generator** β generate soal CPNS pakai OpenAI-compatible API (BYOK). Dua mode: quick (single prompt) dan agentic (multi-step validation) |
| 2. **Question Bank** β kumpulan soal publik/privat yang bisa di-browse, di-rating, dan digunakan ulang |
| 3. **Package Builder** β susun paket soal dari kombinasi soal existing + AI-generated |
| 4. **Exam Interface** β antarmuka ujian simulasi CAT (Computer Assisted Test) |
| 5. **Deep Analytics** β evaluasi per-section (TWK, TIU, TKP), identifikasi kelemahan, rekomendasi paket soal |
|
|
| Target pengguna: Calon Pegawai Negeri Sipil (CPNS) Indonesia. |
|
|
| ## User Stories |
|
|
| ### AI Generation |
| 1. Sebagai peserta, saya ingin generate soal CPNS dengan AI menggunakan API key saya sendiri |
| 2. Sebagai peserta, saya ingin memilih section (TWK, TIU, TKP) dan tingkat kesulitan sebelum generate |
| 3. Sebagai peserta, saya ingin memilih topik spesifik (Pancasila, Deret Angka, Pelayanan Publik, dll.) |
| 4. Sebagai power user, saya ingin menggunakan mode "agentic" untuk validasi kualitas soal yang lebih tinggi |
|
|
| ## Exam Sections Supported |
|
|
| | Section | Type | Focus Areas | |
| |---------|------|-------------| |
| | TWK | Tes Wawasan Kebangsaan | Nasionalisme, Integritas, Bela Negara, Pilar Negara, Bahasa Indonesia | |
| | TIU | Tes Intelegensia Umum | Analogi, Silogisme, Analitis, Deret Angka, Perbandingan, Soal Cerita, Figural | |
| | TKP | Tes Karakteristik Pribadi | Pelayanan Publik, Jejaring Kerja, Sosial Budaya, TIK, Profesionalisme, Anti Radikalisme | |
|
|
| ## Question Formats |
|
|
| Semua soal CPNS menggunakan format **Multiple Choice** dengan 5 pilihan jawaban (A, B, C, D, E). Beberapa format tambahan untuk latihan: |
| - Multiple Choice (Standard) |
| - Benar / Salah (Latihan Konsep) |
| - Melengkapi Kalimat (Bahasa Indonesia) |
| - Analogi & Silogisme (TIU) |
| - Deret Angka (TIU) |
|
|
| ## Implementation Decisions |
|
|
| ### Tech Stack |
| - **Frontend**: React 19 + TanStack Router (SPA) + TanStack Query + Tailwind CSS 4 + shadcn/ui |
| - **Backend**: Hono + tRPC |
| - **Auth**: Better Auth (email/password) |
| - **Database**: PostgreSQL + Drizzle ORM |
| - **AI**: OpenAI-compatible API (generic interface, user-provided keys) |
| - **Monorepo**: Turborepo + Bun workspaces |
| - **Theme**: Light default, dark toggle (system preference aware via next-themes) |
|
|
| ### Architecture |
|
|
| ``` |
| apps/web/ React SPA frontend |
| routes/ File-based routes (TanStack Router) |
| index.tsx Landing / Home |
| generate.tsx AI Generator wizard |
| bank.tsx Question Bank browse |
| bank/$id.tsx Package / Question detail |
| builder.tsx Test Builder (craft package) |
| builder/combo.tsx Package Combiner |
| exam/$id.tsx Exam Interface |
| exam/$id/result.tsx Exam Results |
| analytics.tsx Deep Analytics dashboard |
| settings.tsx Settings (API keys, profile) |
| |
| apps/server/ Hono backend |
| Mounts Better Auth + tRPC |
| |
| packages/ |
| ai/ AI generation pipeline (new) |
| api/ tRPC routers + context |
| routers/ |
| ai.ts generateQuestions (streaming) |
| question.ts CRUD questions, search, filter |
| package.ts CRUD packages, sections |
| combo.ts Combo package creation |
| exam.ts Attempts, grading, results |
| analytics.ts Stats, trends, recommendations |
| settings.ts API key management |
| auth/ Better Auth config |
| db/ Drizzle ORM schema |
| ui/ shadcn/ui shared components |
| env/ Environment validation |
| ``` |
|
|
| ### Deep Modules (testable in isolation) |
|
|
| - **`packages/ai/`** β AI generation pipeline |
| - Interface: `generateQuestions(input: GenerationInput) => GenerationResult` |
| - Two pipelines: `quick` (single call) and `agentic` (multi-step) |
| - Zod schemas for all question formats (type-safe generation + validation) |
| - OpenAI-compatible client abstraction |
|
|
| - **`packages/api/src/routers/`** β tRPC routers |
| - Each router encapsulates one domain with clear procedures |
|
|
| ### Database Schema (New Tables) |
|
|
| ``` |
| exam_type id, name, language, description |
| section_type id, name |
| question id, exam_type_id, section_type_id, format, passage_text, |
| question_text, options_json, correct_answer, explanation, |
| difficulty (1-5), skill_tags[], source (ai|manual), |
| ai_model, creator_user_id, is_public, usage_count, avg_rating |
| package id, title, description, exam_type_id, creator_user_id, |
| is_public, total_questions, usage_count, avg_rating |
| package_section id, package_id, section_type_id, title, order_index |
| section_question id, section_id, question_id, order_index |
| combo_package id, title, description, creator_user_id, is_public |
| combo_section id, combo_id, source_package_id, source_section_id, order_index |
| test_attempt id, user_id, package_id_or_combo_id, started_at, finished_at, total_score |
| section_result id, attempt_id, section_type, score, max_score, time_spent_sec |
| answer id, section_result_id, question_id, user_answer, is_correct, time_spent_sec |
| user_api_key id, user_id, provider, base_url, api_key_encrypted, model_name, is_active |
| question_rating id, user_id, question_id, score (1-5), created_at |
| ``` |
|
|
| ### Agentic AI Pipeline |
|
|
| ``` |
| Step 1: Passage Generator β Authentic reading passage sesuai level ujian |
| Step 2: Passage Validator β Validasi akurasi, difficulty, grammar, panjang |
| Step 3: Question Generator β Generate N questions dalam format yang diminta |
| Step 4: Self-Answer & Validate β AI menjawab sendiri, flag ambigu, hitung confidence |
| Step 5: Quality Scorer β Overall score, needsHumanReview flag |
| ``` |
|
|
| ### Weakness Analysis Algorithm |
|
|
| 1. Group answers by `section_type` dan `skill_tag` |
| 2. Hitung akurasi per group |
| 3. Identifikasi skill tags dengan akurasi di bawah threshold (default 70%) |
| 4. Sort by `total_attempts * (1 - accuracy)` β prioritize yang sering salah |
| 5. Cari paket soal publik dengan skill tags yang match kelemahan user |
| 6. Return top-N rekomendasi paket |
|
|
| --- |
|
|
| ## Implementation Phases |
|
|
| ### Phase 1 β Foundation (Schema + Core Infrastructure) |
| **Goal:** Database siap, user bisa manage API key, AI pipeline dasar berjalan |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 1.1 | Add application tables to Drizzle schema | `packages/db/` | |
| | 1.2 | Generate & run migrations | `packages/db/` | |
| | 1.3 | Create `packages/ai/` β OpenAI-compatible client + Zod schemas for all question formats | `packages/ai/` | |
| | 1.4 | AI key management tRPC router (encrypt/decrypt) | `packages/api/` | |
| | 1.5 | Settings page β API key CRUD UI | `apps/web/` | |
| | 1.6 | Quick mode AI generation pipeline (single call) | `packages/ai/` | |
| | 1.7 | AI Generator router + basic UI page | `packages/api/` + `apps/web/` | |
|
|
| **User stories delivered:** 1, 2, 3, 4, 7, 31, 32, 33 |
|
|
| ### Phase 2 β Question Bank & Packages |
| **Goal:** Soal bisa disimpan, dipublikasikan, di-browse, dan dibundle |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 2.1 | Question CRUD tRPC router (search, filter, publish/unpublish) | `packages/api/` | |
| | 2.2 | Package CRUD tRPC router (create, add sections, add questions) | `packages/api/` | |
| | 2.3 | Question Bank browse page (grid, search, filters) | `apps/web/` | |
| | 2.4 | Package detail page (preview soal, rating, stats) | `apps/web/` | |
| | 2.5 | AI Generator β save result as question / package | `apps/web/` | |
| | 2.6 | Test Builder page (craft package from bank items) | `apps/web/` | |
| | 2.7 | Rating system for public questions/packages | `packages/api/` | |
|
|
| **User stories delivered:** 5, 8, 9, 10, 11, 12, 13, 14, 15, 17 |
|
|
| ### Phase 3 β Package Combiner + Agentic Mode |
| **Goal:** Pengguna bisa mix section dari berbagai paket; power user bisa pakai agentic generation |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 3.1 | Combo package tRPC router | `packages/api/` | |
| | 3.2 | Package Combiner UI (select sections from different packages) | `apps/web/` | |
| | 3.3 | Agentic mode AI pipeline (multi-step) | `packages/ai/` | |
| | 3.4 | Agentic mode toggle + streaming progress in AI Generator UI | `apps/web/` | |
|
|
| **User stories delivered:** 6, 16 |
|
|
| ### Phase 4 β Exam Experience |
| **Goal:** Pengguna bisa mengerjakan ujian dengan antarmuka side-by-side, timer, auto-grade |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 4.1 | Exam attempt + answer submission tRPC router | `packages/api/` | |
| | 4.2 | Auto-grade logic (untuk semua format objektif) | `packages/api/` | |
| | 4.3 | Exam Interface page (side-by-side passage + questions) | `apps/web/` | |
| | 4.4 | Timer component (client-side with periodic sync) | `apps/web/` | |
| | 4.5 | Question navigation (prev/next/jump, mark for review) | `apps/web/` | |
| | 4.6 | Auto-save answers | `apps/web/` | |
| | 4.7 | Exam Results page (per-section scores, answer review) | `apps/web/` | |
|
|
| **User stories delivered:** 18, 19, 20, 21, 22, 23, 24, 25 |
|
|
| ### Phase 5 β Analytics & Recommendations |
| **Goal:** User bisa melihat performa, kelemahan, dan rekomendasi perbaikan |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 5.1 | Analytics tRPC router (stats, trends, skill breakdown) | `packages/api/` | |
| | 5.2 | Weakness identification + recommendation algorithm | `packages/api/` | |
| | 5.3 | Deep Analytics dashboard page (stats cards, line chart, radar chart) | `apps/web/` | |
| | 5.4 | Performance by Skill table | `apps/web/` | |
| | 5.5 | Recommended packages section on dashboard | `apps/web/` | |
|
|
| **User stories delivered:** 26, 27, 28, 29, 30 |
|
|
| ### Phase 6 β Community & Polish |
| **Goal:** Platform terasa hidup dengan konten komunitas, trending, PWA offline support |
|
|
| | # | Task | Package | |
| |---|------|---------| |
| | 6.1 | Trending / most-used packages endpoint | `packages/api/` | |
| | 6.2 | Staff pick / featured content | `apps/web/` | |
| | 6.3 | Creator stats (usage count, rating) on profile | `apps/web/` | |
| | 6.4 | Share link for public packages | `apps/web/` | |
| | 6.5 | PWA offline support for exam mode (cache questions) | `apps/web/` | |
| | 6.6 | UI polish, loading skeletons, empty states, error boundaries | `apps/web/` | |
| | 6.7 | i18n foundation (Bahasa Indonesia UI strings) | `apps/web/` | |
|
|
| **User stories delivered:** 34, 35, 36, 37 |
|
|
| --- |
|
|
| ## Out of Scope |
|
|
| - Mobile app (React Native) β web-first, PWA covers mobile |
| - Writing essay auto-grading β terlalu kompleks dan unreliable untuk AI saat ini |
| - Speaking section generation β fokus ke reading comprehension dulu |
| - Listening audio generation β perlu TTS, terlalu kompleks untuk initial release |
| - Proctoring / anti-cheat |
| - Subscription / payment system β open-source, self-hosted |
| - Real-time multiplayer |
| - Social features (comments, following) beyond ratings |
| - Admin dashboard β semua management via DB langsung atau CLI |
| - Email verification & password reset flow (bisa ditambah nanti) |
| - OAuth login (Google, GitHub) β email/password saja untuk initial release |
|
|
| ## Testing Strategy |
|
|
| - **AI package** (`packages/ai/`): Unit tests for Zod validation schemas, integration tests with mocked LLM responses |
| - **API routers** (`packages/api/src/routers/`): tRPC procedure tests against test database |
| - **Package Combiner**: Complex business logic β priority for testing |
| - **Auto-grade logic**: Must be correct β parametrized tests per format |
| - **Test structure**: `packages/*/__tests__/` (establishing fresh β codebase has no tests yet) |
|
|
| A good test: |
| - Tests external behavior (API contract), not implementation details |
| - Uses tRPC test client to call procedures end-to-end |
| - Isolates AI calls via mocking |
|
|
| ## Further Notes |
|
|
| - Repo akan dijadikan open-source β semua API key di-skip dari git, dokumentasi jelas untuk self-hosting |
| - UI text dalam Bahasa Indonesia (target pengguna), kode dalam English |
| - Soal bisa bilingual (passage dalam bahasa target, instruksi dalam Bahasa Indonesia) |
| - Timer di exam interface harus client-side dengan periodic sync ke server |
| - PWA support sudah ada, perlu di-enhance untuk offline exam mode (cache soal) |
| - Default theme: light, dark toggle tetap ada |
| - Nama "Pram" dari "labs" + "bahasa" |
|
|