6.1 KiB
6.1 KiB
Brownfield Documentation — LMS-BGN
Ringkasan teknis kondisi kode saat ini (brownfield) untuk LMS-BGN, mencakup arsitektur, endpoint backend aktif, proxy API frontend, perubahan UI Admin, data model yang dipakai, serta runbook pengembangan lokal. Dokumen ini fokus pada konteks yang telah berjalan setelah integrasi CRUD Course, daftar Instructors, dan CourseForm di Admin.
Snapshot Arsitektur
- Frontend: Next.js (App Router) dengan TypeScript; API proxy di
src/app/api/*. - Backend: Express server di
backend/src/server.jsdengan penyimpanan in-memory. - Komunikasi: Frontend memanggil proxy Next → meneruskan ke Backend (
BASEfallbackhttp://localhost:8001). - Media: Upload gambar disimpan ke
public/uploads(lokal) via route Next/api/uploads.
Data Model Utama (In-Memory)
Course:{ id, title, instructor, progress, status, color, thumbnail, duration, modules, enrolled }status:"draft" | "published" | "archived"color: hex#RRGGBBthumbnail: path publik (mis./uploads/<file>.png)duration: menit (integer > 0)
Instructor:{ id, name, email }ExamSession:{ id, examId, userId, answers, score?, startedAt? }(outline)Certificate: data minimal untuk resend (outline)
Backend Endpoints (aktif)
Base dev: http://localhost:8001
- Courses
GET /api/courses— list + pagination + search (q), respon{ data, total, page, pageSize }GET /api/courses/:courseId— detail coursePOST /api/courses— create (validasi:title,instructor,duration,thumbnail,color,status)PUT /api/courses/:courseId— update (validasi serupa)DELETE /api/courses/:courseId— delete (204 jika sukses)
- Instructors
GET /api/instructors— list + optional searchq; respon{ data, total }
- Modules & Assignments
POST /api/modules/:moduleId/progress— update progres modul, body{ progressPercent }POST /api/assignments/:assignmentId/submission— requiresidempotencyKey; 201 jika baru, 409 duplikat
- Exams & Certificates
GET /api/exams— list ujian (pagination + search)POST /api/exam-session— create session (examId,userId)POST /api/exam-session/:sessionId/score— skor jawaban (mode batch), Bearer optional; mendukung MCQ, scenario/video, puzzle, dsb.GET /api/exam-session/:sessionId/summary— ringkasan hasilPOST /api/certificates/:certificateId/resend— resend email (idempotency + rate limit sederhana)
Catatan: Beberapa endpoint berasal dari implementasi awal dan sebagian telah diperluas. Penyimpanan masih in-memory; restart server akan menghapus data.
Frontend API Proxy (Next.js)
BASE fallback: http://localhost:8001
src/app/api/courses/route.tsGET→/api/courses(backend)POST→/api/courses(backend)
src/app/api/courses/[courseId]/route.tsGET→/api/courses/:courseIdPUT→/api/courses/:courseIdDELETE→/api/courses/:courseId
src/app/api/instructors/route.tsGET→/api/instructors?q=<search>
src/app/api/uploads/route.tsPOST— validasi mime image & ukuran (≤ 5MB); simpan kepublic/uploads; balikan path publik untuk preview
Perubahan UI Admin (yang berjalan)
src/components/admin/CourseForm.tsx(client component)- Upload gambar dengan preview (via
/api/uploads) - Input durasi (spinner number)
- Color picker (hex)
- Dropdown Instructor (fetch dari
/api/instructors, dengan search) - Submit create/update ke proxy
/api/coursesatau/api/courses/[courseId]
- Upload gambar dengan preview (via
src/app/admin/courses/create/page.tsx- Menggunakan
CourseFormuntuk pembuatan course; redirect setelah sukses
- Menggunakan
src/app/admin/courses/[id]/edit/page.tsx- Menggunakan
CourseFormuntuk edit; prefill dari API; redirect setelah sukses
- Menggunakan
Runbook Dev Lokal
- Backend
- Jalankan di
backend/: PowerShell →$env:PORT=8001; npm run dev - Health/Smoke: akses
GET http://localhost:8001/api/instructorsatauGET /api/courses
- Jalankan di
- Frontend
- Jalankan di root:
npm run dev(otomatis pindah ke port3001jika3000terpakai) - Preview Admin Create:
http://localhost:3001/admin/courses/create - Preview Admin Edit:
http://localhost:3001/admin/courses/<id>/edit
- Jalankan di root:
- Contoh smoke (PowerShell)
- Create course:
Invoke-RestMethod -Method Post -Uri http://localhost:8001/api/courses -ContentType application/json -Body '{"title":"Knife Basics","instructor":"i1","duration":60,"thumbnail":"/uploads/x.png","color":"#3366FF","status":"draft"}' - Update course:
Invoke-RestMethod -Method Put -Uri http://localhost:8001/api/courses/<id> -ContentType application/json -Body '{"title":"Knife Basics Updated"}' - Delete course:
Invoke-WebRequest -Method Delete -Uri http://localhost:8001/api/courses/<id>(cek status 204)
- Create course:
Batasan Saat Ini
- Penyimpanan in-memory (data hilang saat restart; bukan produksi)
- Validasi sederhana (color hex, status enum, durasi > 0) — belum ada skema terpadu
- Upload lokal ke
public/uploads(tanpa CDN, tanpa antivirus) - Tidak ada autentikasi/otorisasi untuk Admin; proxy terbuka di dev
- Idempotency untuk assignments & rate limit untuk resend sederhana (in-memory)
- Ketergantungan pada BASE
http://localhost:8001untuk dev; environment management minimal
Rekomendasi Next Steps
- Persistensi: migrasi ke DB (PostgreSQL/SQLite dev) + ORM (Prisma)
- Skema & tipe: definisikan tipe terpadu (Zod/TypeScript) untuk API + frontend
- Upload: integrasi storage (S3/MinIO) + validasi server-side kuat
- AuthZ: tambahkan auth (JWT/NextAuth) & guard route Admin
- Observabilitas: logging terstruktur + request tracing sederhana
- Testing: tambah unit/integrasi untuk backend (Jest/Supertest) dan e2e smoke
- Analytics Admin: tambahkan agregasi & export CSV/XLSX, konsisten dengan PRD
Referensi & Jejak
- PRD:
docs/mbg-lms-prd.md - Epic 2:
docs/Epic 2 — Course & Learning Management.md - Tech Spec:
docs/technical/tech-spec-lms-bgn.md - QA Smoke:
docs/qa/assessments/backend-endpoints.http,docs/qa/assessments/curl-examples.md - Proxy & Admin UI:
src/app/api/*,src/components/admin/CourseForm.tsx,src/app/admin/courses/*