Files
Amadea 61ce9d7926 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
2026-09-18 19:24:59 +07:00

361 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 | ⬜ |