feat: implementasi Kodeva - sistem manajemen kursus coding

Fitur lengkap:
- Auth JWT + RBAC (Admin/Teacher) + halaman login
- Shell 3 kolom (left nav, topbar, right rail dashboard)
- CRUD siswa + follow up kanban + status calon/student/ex
- Dashboard: siswa aktif, kehadiran, bar sumber lead, perlu follow up
- Pembayaran prorata per pertemuan (cash/transfer/qris)
- Kelas, enrollment, generate sesi, kehadiran bulk
- Jurnal aktivitas + upload multi-foto
- Raport + placement test (tampil di detail siswa)
- Pengaturan & seed data contoh

Stack: Next.js 16, TypeScript, Tailwind v4, Prisma (SQLite), Recharts, Zod
This commit is contained in:
Amadea
2026-09-18 19:24:59 +07:00
commit 61ce9d7926
86 changed files with 13392 additions and 0 deletions
+360
View File
@@ -0,0 +1,360 @@
# PLAN.md — Rencana Pengembangan Kodeva
> Rencana eksekusi untuk membangun **Kodeva** (Sistem Manajemen Kursus Coding).
> Dokumen pendamping: [`AGENTS.md`](./AGENTS.md) (engineering), [`DESIGN.md`](./DESIGN.md) (UI/UX), [`seed.example.ts`](./seed.example.ts) (contoh data).
> Status: **Draft v1.0** · Estimasi total **810 minggu** (1 full-stack dev + AI agent).
---
## 1. Tujuan & Kriteria Sukses
**Tujuan:** Aplikasi web internal untuk mengelola siklus siswa kursus coding — dari calon siswa, follow up, enrollment, kehadiran, pembayaran prorata, jurnal, raport, hingga placement test.
**Kriteria sukses (v1.0):**
1. Admin bisa CRUD siswa + follow up dan mengubah status `CALON_STUDENT → STUDENT → EX_STUDENT` tanpa Excel.
2. Dashboard menampilkan angka **perlu follow up** & **ex student** serta 3 grafik (siswa aktif, kehadiran, sumber lead) di right rail.
3. Pembayaran prorata per pertemuan (contoh Rp 2.000.000/10 → Rp 200.000/pertemuan) dengan metode Cash/Transfer/QRIS.
4. Guru bisa input kehadiran, jurnal+foto, dan raport per siswa.
5. Kelas dapat dikonfigurasi (nama, level, guru, jumlah pertemuan, harga, kapasitas, jadwal).
6. Hasil placement test tampil di detail siswa.
7. Semua role & data terlindungi RBAC; tidak ada payment gateway.
8. Lulus e2e flow utama + `lint`/`typecheck`/`test` hijau.
---
## 2. Ruang Lingkup
### 2.1 In Scope (v1.0)
- Auth & RBAC (Admin, Teacher)
- Shell layout: left nav + main + right rail
- CRUD Siswa (field lengkap + foto profil + status + sumber lead)
- Follow Up pipeline (kanban) + aktivitas + jadwal due
- CRUD Kelas + Enrollment + generate Session
- Kehadiran per pertemuan (bulk)
- Pembayaran prorata + metode + bukti
- Jurnal aktivitas + upload multi-foto
- Raport (aspek penilaian + publish)
- Placement Test (skor kategori + level + rekomendasi)
- Dashboard + grafik right rail
- Seed contoh data
### 2.2 Out of Scope (ditunda)
- Payment gateway / auto-reconciliation
- Notifikasi WhatsApp otomatis (v1.1, integrasi API)
- Portal/login untuk orang tua & siswa
- Multi-cabang / multi-tenant
- Mobile app native
- Absensi QR / face recognition
- Sertifikat otomatis (v1.1)
- Akuntansi/laporan keuangan lengkap
---
## 3. Asumsi, Tim & Kapasitas
| Item | Asumsi |
|------|--------|
| Tim | 1 full-stack developer + AI agent (pair) |
| Desainer | 1 part-time (audit visual di M1 & M7) |
| Stack | Sesuai AGENTS.md §2 (Next.js 15 + Prisma + Postgres) |
| Kapasitas | ~5 hari kerja/minggu, ~6 jam efektif/hari |
| Lingkungan | Dev lokal + 1 staging (Vercel + Neon/Supabase) |
| Bahasa | UI Bahasa Indonesia |
| Data | Mulai dari `seed.example.ts`, direset tiap sprint |
**Definition of Ready (DoR):** task punya deskripsi, acceptance criteria, dan file/lokasi yang dituju.
**Definition of Done (DoD):** kode + test + lint/typecheck hijau, UI sesuai DESIGN.md, 4 state (loading/empty/error/success), sudah di-review agent/manusia.
---
## 4. Ringkasan Timeline
```
Minggu 1 2 3 4 5 6 7 8 9 10
M0 Setup ██
M1 Fondasi ████
M2 Siswa & ████
Follow Up
M3 Kelas & ████
Kehadiran
M4 Pembayaran ████
M5 Jurnal ████
M6 Raport & ████
Placement
M7 Dashboard & ████
Right Rail
M8 Hardening ████
M9 UAT & Launch ████
```
| Milestone | Nama | Estimasi | Dependency | Requirement |
|-----------|------|:--------:|------------|:-----------:|
| M0 | Setup & Scaffolding | 34 hari | — | — |
| M1 | Fondasi: Auth + Shell + Schema + Seed | 1 minggu | M0 | — |
| M2 | Siswa & Follow Up | 1,5 minggu | M1 | #1, #7 |
| M3 | Kelas, Enrollment & Kehadiran | 1,5 minggu | M1, M2 | #5, #4 |
| M4 | Pembayaran Prorata | 1 minggu | M3 | #3 |
| M5 | Jurnal Aktivitas + Upload Foto | 1 minggu | M3 | #6 |
| M6 | Raport & Placement Test | 1 minggu | M3 | #4, #8 |
| M7 | Dashboard & Right Rail | 1 minggu | M2M6 | #2, #7 |
| M8 | Hardening, QA & Polish | 1 minggu | M0M7 | — |
| M9 | UAT & Launch | 1 minggu | M8 | semua |
---
## 5. Detail Per Milestone
### M0 — Setup & Scaffolding (34 hari)
**Goal:** Repo siap dibangun, konvensi & CI berjalan.
**Tasks**
- [ ] Init Next.js 15 (App Router, TS strict) + pnpm + folder sesuai AGENTS.md §4
- [ ] Tailwind v4 + CSS tokens DESIGN.md §13 + font (Plus Jakarta Sans, Inter, Sora, JetBrains Mono)
- [ ] shadcn/ui + lucide-react + Recharts + TanStack Table + dnd-kit
- [ ] ESLint + Prettier + Husky + lint-staged
- [ ] `.env.example`, `lib/utils.ts` (`cn`, `formatIDR`, `formatDateID`)
- [ ] Prisma init + Postgres lokal (Docker) + script `db:push`/`db:seed`
- [ ] CI dasar (lint + typecheck + test)
- [ ] Halaman `/health` verifikasi deploy
**Deliverable:** `pnpm dev` jalan, tokens tampil di halaman contoh, CI hijau.
**Acceptance:** `pnpm lint && pnpm typecheck && pnpm test` hijau.
---
### M1 — Fondasi: Auth + Shell + Schema + Seed (1 minggu)
**Goal:** Shell 3 kolom + login + database + data contoh.
**Tasks**
- [ ] Finalisasi `prisma/schema.prisma` (AGENTS.md §6) + `db:push`
- [ ] Salin `seed.example.ts``prisma/seed.ts`, verifikasi output seed
- [ ] Auth.js v5 Credentials + session + `hashPassword`/`verify`
- [ ] Middleware proteksi route + `withAuth` + `src/lib/rbac.ts`
- [ ] **AppShell**: `AppSidebar` (248px, item aktif pill gradient, badge follow up), `Topbar` (breadcrumb, search, aksi, notif, avatar), `RightRail` (sticky, toggle)
- [ ] Komponen UI dasar: Button, Card, StatCard, Badge, Chip, Input, Segmented, Dropdown, Modal, Skeleton, EmptyState
- [ ] Halaman `/login`, redirect per role
- [ ] Audit visual desainer (palet, kontras, spacing)
**Deliverable:** Login berfungsi, shell responsif 3 breakpoint, halaman kosong per menu.
**Acceptance:** login admin/teacher sukses; route terproteksi menolak tanpa sesi; nav highlight benar; skeleton tampil.
---
### M2 — Siswa & Follow Up (1,5 minggu) → Req #1, #7
**Goal:** CRUD siswa lengkap + pipeline follow up.
**Tasks**
- [ ] `lib/validators/student.ts` (Zod) + `followUp.ts`
- [ ] API: `/api/students` (GET/POST), `/api/students/[id]` (GET/PATCH/DELETE/archive)
- [ ] Halaman `/students`: tabel + filter status/sumber/kelas + search + toggle tabel⇄kartu
- [ ] Form tambah/edit: foto (dropzone), nama, telepon, email, orang tua, sumber lead (segmented), status (segmented), multi-kelas
- [ ] Detail siswa: header profil + tab Ringkasan / Kelas / Pembayaran / Placement / Raport / Jurnal (tab diisi bertahap)
- [ ] `StudentCard`, `StatusBadge`, `SourceChip`
- [ ] Follow Up: `/follow-up` kanban (dnd-kit) 6 kolom + drag ubah status
- [ ] `FollowUpActivity` timeline + set `nextFollowUpAt` + PIC
- [ ] `lib/follow-up.ts`: query due (`status ∉ ENROLLED/LOST && nextFollowUpAt ≤ endOfToday`)
- [ ] Aksi "Enroll": ubah status → STUDENT, buat `Enrollment` (validasi kapasitas), arahkan ke pembayaran
- [ ] Tombol WhatsApp/Call (deep link `wa.me`, `tel:`)
**Acceptance:**
- CRUD siswa bertahan setelah refresh; foto terupload.
- Kanban drag mengubah status & tersimpan.
- `followUpDue` benar sesuai seed (2 due).
- Status siswa berubah otomatis saat enroll.
- Unit test `follow-up.ts` hijau.
---
### M3 — Kelas, Enrollment & Kehadiran (1,5 minggu) → Req #5, #4
**Goal:** Konfigurasi kelas + pertemuan + absensi.
**Tasks**
- [ ] API `/api/classes` (CRUD) + `/api/classes/[id]/sessions`
- [ ] Halaman `/classes`: grid kartu (strip warna, progress kapasitas, jadwal)
- [ ] Form kelas: nama, kode unik, level, guru, `totalMeetings`, `packagePrice`, `pricePerMeeting` (auto-preview `Rp/pertemuan`), kapasitas, jadwal, warna, status
- [ ] Detail kelas: roster siswa, daftar sesi, tab jurnal
- [ ] Generate `Session` otomatis (weekly) saat kelas diaktifkan; opsi edit/hapus
- [ ] API `/api/attendance` (GET per sesi, bulk upsert)
- [ ] Halaman `/attendance`: pilih kelas → pertemuan → grid siswa + segmented H/T/I/S/A + "Hadir Semua" + progress `12/12 terisi`
- [ ] `lib/attendance.ts`: `attendanceRate`
- [ ] Unit test validasi kapasitas & generate sesi
**Acceptance:**
- Kelas baru muncul & bisa dipilih di form siswa.
- Siswa ke-13 ditolak saat kapasitas 12 (pesan jelas).
- Kehadiran tersimpan per sesi & bisa diedit; rate benar.
---
### M4 — Pembayaran Prorata (1 minggu) → Req #3
**Goal:** Input pembayaran per pertemuan + rekap.
**Tasks**
- [ ] `lib/prorata.ts` (PURE): `pricePerMeeting`, `amount`, `usedMeetings`, `remainingMeetings`, `proratedValue`, `deriveStatus`
- [ ] Unit test lengkap (batas: `totalMeetings=0`, bayar > total, parsial, kehadiran > kuota)
- [ ] API `/api/payments` (GET/POST), `/api/payments/[id]` (PATCH/refund)
- [ ] Halaman `/payments`: tabel invoice (mono), filter siswa/kelas/metode/status
- [ ] Form: pilih siswa → kelas (auto harga) → stepper `meetingsPaid`**kalkulasi prorata live** → metode (Cash/Transfer/QRIS) → tanggal → upload bukti
- [ ] Nomor invoice otomatis (`INV-YYYY-NNNN`)
- [ ] Kartu ringkasan di detail siswa: `Kuota 10 · Terpakai 6 · Sisa 4 · Nilai sisa Rp 800.000`
- [ ] Badge "Perlu Perpanjang" bila sesi terpakai ≥ kuota
**Acceptance:**
- Input 10 pertemuan × Rp 200.000 = Rp 2.000.000.
- Sisa kuota & nilai sisa terhitung benar dari kehadiran.
- Metode tampil sebagai chip berwarna (Cash mint, Transfer sky, QRIS violet).
- Semua unit test prorata hijau.
---
### M5 — Jurnal Aktivitas + Upload Foto (1 minggu) → Req #6
**Goal:** Feed aktivitas kelas dengan dokumentasi foto.
**Tasks**
- [ ] API `/api/uploads` (validasi tipe & ukuran, simpan ke `public/uploads` / S3)
- [ ] API `/api/journals` (GET feed/POST), `/api/journals/[id]` (GET/PATCH/DELETE)
- [ ] Halaman `/journals`: feed kartu (cover foto, judul, kelas, tanggal, tag, author, jumlah siswa)
- [ ] Form jurnal: multi-foto drag-reorder, judul, deskripsi, kelas, sesi, tag, tandai siswa terlibat
- [ ] Lightbox galeri foto
- [ ] Jurnal tampil di detail siswa (tab Jurnal) & detail kelas
- [ ] Empty/loading state sesuai DESIGN.md §8.7
**Acceptance:**
- Upload 4 foto berhasil, urutan tersimpan, tampil di feed & detail.
- Validasi tolak file > 5MB / non-gambar.
- Jurnal terkait siswa yang benar.
---
### M6 — Raport & Placement Test (1 minggu) → Req #4, #8
**Goal:** Penilaian siswa + hasil tes penempatan.
**Tasks**
- [ ] API `/api/report-cards` (GET/POST), `.../[id]/publish`
- [ ] Form raport: aspek (Logika, Computational Thinking, Problem Solving, Kreativitas, Kolaborasi) 0100 → rata-rata, grade otomatis A/B/C/D, catatan guru, ringkasan kehadiran
- [ ] Preview raport bertema (header gradient, tanda tangan guru) + tombol Publish
- [ ] Halaman `/report-cards` (list per kelas/periode)
- [ ] API `/api/placements` (GET/POST)
- [ ] Form placement: siswa, tanggal, pemeriksa, skor kategori → level otomatis + rekomendasi kelas
- [ ] **Kartu Placement Test di detail siswa**: level, skor per kategori (bar), rekomendasi, tanggal, pemeriksa, badge di header
- [ ] Unit test perhitungan grade & level
**Acceptance:**
- Raport Andi (seed) tampil dengan grade benar & bisa dipublish.
- Placement Elsa tampil `Intermediate` + rekomendasi `JavaScript Intermediate`.
- Badge level muncul di header profil siswa.
---
### M7 — Dashboard & Right Rail (1 minggu) → Req #2, #7
**Goal:** Semua grafik & ringkasan.
**Tasks**
- [ ] API `/api/dashboard/summary` (paralel: counts + trend + leadSources + attendance)
- [ ] Hero sapaan + 4 StatCard besar (Siswa Aktif, Perlu Follow Up, Ex Student, Kehadiran %)
- [ ] Right rail widgets (DESIGN.md §9.1): stat stack, donut kehadiran, area tren siswa, bar sumber lead, list follow up hari ini, kelas hari ini
- [ ] Chart components (Recharts): `ActiveStudentsChart`, `AttendanceDonut`, `LeadSourceBar` + legend & tooltip Bahasa Indonesia
- [ ] Warna chart sesuai mapping DESIGN.md §3.5
- [ ] Responsif: rail jadi drawer < 1280px
- [ ] Animasi masuk 250ms + chart 400ms, hormati `prefers-reduced-motion`
**Acceptance:**
- Angka dashboard cocok dengan seed (4 aktif, 2 ex, 2 due).
- Bar chart sumber lead menampilkan WhatsApp/Referral/Banner/Social dengan angka.
- Rail tetap fungsional di tablet (drawer).
---
### M8 — Hardening, QA & Polish (1 minggu)
**Goal:** Stabil, aman, cepat, aksesibel.
**Tasks**
- [ ] Audit RBAC semua route + test unauthorized
- [ ] Validasi Zod di semua boundary; sanitasi upload
- [ ] Optimasi query (index, hindari N+1) + `loading.tsx`/Suspense
- [ ] Aksesibilitas: fokus, label, kontras AA, target sentuh 44px
- [ ] Audit visual final (desainer) + konsistensi token
- [ ] Error boundary + toast + halaman 404/500
- [ ] E2E Playwright flow utama
- [ ] Dokumentasi singkat (README: setup & peran)
**Acceptance:**
- `pnpm lint && typecheck && test && test:e2e` hijau.
- Lighthouse mobile ≥ 90 performance/accessibility untuk dashboard.
- Tidak ada error di console.
---
### M9 — UAT & Launch (1 minggu)
**Goal:** Rilis ke pengguna nyata.
**Tasks**
- [ ] Deploy staging + migrasi data contoh
- [ ] Sesi UAT dengan admin & 1 guru (skenario tasks)
- [ ] Perbaiki temuan blocker/high
- [ ] Backup & restore DB terdokumentasi
- [ ] Deploy production + domain + monitoring error (Sentry)
- [ ] Pelatihan singkat + panduan penggunaan
- [ ] Retrospective & susun backlog v1.1
**Acceptance:** Admin & guru menyelesaikan 8 skenario UAT tanpa bantuan; data produksi aman.
---
## 6. Backlog Prioritas (MoSCoW)
**Must (v1.0):** semua requirement #1#8, auth/RBAC, seed, deploy.
**Should:** dark mode, export CSV siswa/pembayaran, filter lanjutan, audit log, konfeti enroll.
**Could:** notifikasi WhatsApp otomatis, sertifikat PDF, portal ortu, absensi QR, laporan pendapatan.
**Won't (kini):** payment gateway, multi-cabang, mobile native.
---
## 7. Risiko & Mitigasi
| Risiko | Dampak | Prob. | Mitigasi |
|--------|:------:|:-----:|----------|
| Scope melebar (fitur baru saat coding) | Tinggi | Sedang | Kunci v1.0 ke Must; fitur baru masuk backlog v1.1 |
| Logika prorata ambigu (refund/rollover) | Tinggi | Sedang | Kunci aturan di AGENTS.md §7.1 + unit test sebelum UI |
| Desain tidak konsisten antar halaman | Sedang | Sedang | Wajib pakai token DESIGN.md; audit di M1 & M8 |
| Upload foto besar bikin lambat/biaya | Sedang | Sedang | Batasi 5MB, kompres (sharp), lazy-load |
| Kapasitas kelas & enrollment bentrok | Sedang | Rendah | Validasi server-side + test |
| Database drift schema | Sedang | Rendah | Migrasi Prisma, staging sebelum prod |
| Estimasi molor karena 1 dev | Sedang | Sedang | Prioritaskan Must tiap sprint; cut Should bila perlu |
---
## 8. Tracking & Ritual
- **Papan:** GitHub Projects / Linear — kolom `Backlog · Ready · In Progress · Review · Done`.
- **Sprint:** 1 minggu, demo di akhir sprint (per milestone).
- **Definition of Ready/Done:** §3.
- **Branch:** `feat/…`, `fix/…`; PR wajib lulus CI + review.
- **Commit:** Conventional Commits.
---
## 9. Setelah v1.0 (v1.1+)
1. Notifikasi WhatsApp otomatis (reminder follow up, jadwal, tagihan).
2. Export laporan (CSV/PDF) & sertifikat siswa.
3. Portal orang tua/siswa (lihat raport, jadwal, tagihan).
4. Absensi QR + rekap otomatis.
5. Laporan pendapatan & aging piutang.
6. Multi-cabang + dashboard per cabang.
7. Dark mode & PWA.
---
## 10. Checklist Ringkas Per Requirement
| Req | Fitur | Milestone | Status |
|:---:|-------|:---------:|:------:|
| 1 | CRUD follow up siswa baru (field lengkap + status) | M2 | ⬜ |
| 2 | Right rail dashboard (siswa aktif, kehadiran, bar sumber lead) | M7 | ⬜ |
| 3 | Pembayaran prorata + Cash/Transfer/QRIS | M4 | ⬜ |
| 4 | Guru input jurnal, raport, kehadiran | M3, M5, M6 | ⬜ |
| 5 | Konfigurasi kelas + pilih kelas saat input siswa | M3 | ⬜ |
| 6 | Jurnal aktivitas + upload foto | M5 | ⬜ |
| 7 | Dashboard: perlu follow up & ex student | M2, M7 | ⬜ |
| 8 | Placement test tampil di info siswa | M6 | ⬜ |