> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sertifikasitrainer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Alur pembuatan kursus

> Admin membuat course, chapter, lesson, dan mengaitkan ke tier batch.

Kursus (**course**) adalah kontainer pembelajaran: **chapter** → **lesson**. Peserta hanya melihat kursus yang termasuk **akses tier** mereka.

## Model data

```mermaid theme={null}
erDiagram
  courses ||--o{ chapters : has
  chapters ||--o{ lessons : has
  lessons ||--o{ lesson_progress : tracked_by
  batch_tiers }o--o{ courses : courseIds
  enrollments }o--|| batch_tiers : tier
  peserta ||--o{ enrollments : has
  peserta ||--o{ lesson_progress : watches

  courses {
    uuid id
    string title
    string status
  }
  chapters {
    uuid id
    uuid course_id
    int order
  }
  lessons {
    uuid id
    uuid chapter_id
    string video_type
    string mux_playback_id
  }
```

## Alur admin

```mermaid theme={null}
flowchart TD
  A["Admin login\n/admin"] --> B["Manage Kelas\n/admin/.../kelas"]
  B --> C["Buat course baru\njudul, deskripsi, status"]
  C --> D["Tambah chapter\nurutan modul"]
  D --> E["Tambah lesson per chapter\njudul, tipe video"]
  E --> F{Tipe video?}
  F -->|Mux| G["Upload / import URL\nlihat alur video"]
  F -->|YouTube / external| H["Paste URL"]
  F -->|Google Drive| I["Link drive"]
  G --> J["Publish course\nstatus active"]
  H --> J
  I --> J
  J --> K["Hubungkan ke tier\nbatch_tiers.courseIds"]
```

### UI admin

| Layar         | Route (kira-kira)      | File                          |
| ------------- | ---------------------- | ----------------------------- |
| Daftar kursus | `/admin/.../kelas`     | `views/admin/ManageKelas.tsx` |
| Edit kursus   | `/admin/.../kelas/:id` | `views/admin/EditKelas.tsx`   |
| Modal chapter | —                      | `components/ChapterModal.tsx` |
| Modal lesson  | —                      | `components/LessonModal.tsx`  |

Hook data: `views/admin/hooks/useManageKelas.ts`

### API admin (contoh)

| Method   | Endpoint                 | Aksi                           |
| -------- | ------------------------ | ------------------------------ |
| `GET`    | `/api/kelas/courses`     | List (+ progress jika peserta) |
| `POST`   | `/api/kelas/courses`     | Buat course                    |
| `POST`   | `/api/kelas/chapters`    | Buat chapter                   |
| `POST`   | `/api/kelas/lessons`     | Buat lesson                    |
| `PATCH`  | `/api/kelas/lessons/:id` | Update lesson                  |
| `DELETE` | `/api/kelas/courses/:id` | Hapus course                   |

Role: **admin** untuk write; peserta read dengan cek akses.

## Kaitkan kursus ke tier batch

Saat admin mengatur **tier** di batch:

1. Buka tier management → pilih tier (Platinum, Master, …)
2. Set **`courseIds`** — array UUID course yang dibuka untuk tier itu
3. Atau kosongkan → peserta tier tersebut dapat **semua** kursus aktif

Resolusi akses: `apps/api/src/enrollment/resolve-course-access.ts`

```text theme={null}
tier.courseIds ada isinya  → hanya course itu
tier.courseIds kosong      → semua course status active
enrollment harus paymentStatus = paid
```

## Alur peserta belajar

```mermaid theme={null}
sequenceDiagram
  participant P as Peserta
  participant Web as /:slug/kelas
  participant API as KelasService
  participant DB as Postgres

  P->>Web: Buka arsip kursus
  Web->>API: GET courses (dengan hasAccess)
  API->>DB: paid enrollments → courseIds
  P->>Web: Buka course detail
  Web->>API: GET course/:id
  API->>API: Cek accessibleCourseIds
  API-->>Web: chapters + lessons + progress
  P->>Web: Tonton lesson
  Web->>API: GET playback-token
  API-->>Web: Mux JWT (jika mux)
  P->>Web: Update progress
  Web->>API: PATCH lesson progress
```

### Progress lesson

Status: `belum-mulai` → `sedang-diproses` → `selesai`\
Field `videoProgress` 0–100; selesai = 100%.

Endpoint: `PATCH /api/kelas/:courseId/lesson/:lessonId/progress`

## Cek akses di kode

Peserta **tanpa** enrollment paid ke course yang diminta mendapat `403 COURSE_FORBIDDEN`:

* `getCourseDetail`
* `updateLessonProgress`
* `getPlaybackToken`

Admin memanggil API tanpa `pesertaId` → bypass cek (preview).

Kode: `apps/api/src/kelas/kelas.service.ts`

## Lanjut

Setelah lesson pakai Mux → [Alur video](/architecture/alur-video)
