ο»Ώ# 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:
- AI Question Generator β generate soal CPNS pakai OpenAI-compatible API (BYOK). Dua mode: quick (single prompt) dan agentic (multi-step validation)
- Question Bank β kumpulan soal publik/privat yang bisa di-browse, di-rating, dan digunakan ulang
- Package Builder β susun paket soal dari kombinasi soal existing + AI-generated
- Exam Interface β antarmuka ujian simulasi CAT (Computer Assisted Test)
- 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
- Sebagai peserta, saya ingin generate soal CPNS dengan AI menggunakan API key saya sendiri
- Sebagai peserta, saya ingin memilih section (TWK, TIU, TKP) dan tingkat kesulitan sebelum generate
- Sebagai peserta, saya ingin memilih topik spesifik (Pancasila, Deret Angka, Pelayanan Publik, dll.)
- 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) andagentic(multi-step) - Zod schemas for all question formats (type-safe generation + validation)
- OpenAI-compatible client abstraction
- Interface:
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
- Group answers by
section_typedanskill_tag - Hitung akurasi per group
- Identifikasi skill tags dengan akurasi di bawah threshold (default 70%)
- Sort by
total_attempts * (1 - accuracy)β prioritize yang sering salah - Cari paket soal publik dengan skill tags yang match kelemahan user
- 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"