> ## 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 generate (job queue)

> Sequence diagram dari klik Generate sampai file DOCX/PPTX siap diunduh.

Halaman ini fokus pada **alur teknis job generate** — antrian, worker, renderer. Detail prompt & composer: [Alur generate dokumen](/ai/overview).

## Sequence end-to-end

```mermaid theme={null}
sequenceDiagram
  participant U as Peserta
  participant Web as AI Workspace
  participant API as Generation API
  participant Boss as PgBoss
  participant Worker as Generation Worker
  participant AI as DeepSeek
  participant R as Renderer Worker
  participant R2 as R2 / storage

  U->>Web: Klik Generate (documentTypes[])
  Web->>API: POST /documents/:id/generate
  API->>API: validasi ownership + rate limit
  API->>Boss: enqueue job
  API-->>Web: jobId (queued)
  Web->>API: poll GET /generation-jobs/:id

  Boss->>Worker: deliver job
  Worker->>Worker: load canonical state + registry
  Worker->>AI: enrich / section generate (per doc)
  Worker->>Worker: Zod validate payload
  Worker->>R: POST render DOCX/PPTX
  R-->>Worker: buffer file
  Worker->>R2: upload generated file
  Worker->>API: job status completed

  Web->>API: GET generated files
  U->>Web: Download dari sidebar
```

## Endpoint utama

| Method | Path                                            | Fungsi                                |
| ------ | ----------------------------------------------- | ------------------------------------- |
| `POST` | `/documents/:documentId/generate`               | Enqueue multi-doc (max 20 types)      |
| `POST` | `/documents/:documentId/generate/:documentType` | Satu dokumen                          |
| `GET`  | `/generation-jobs/:jobId`                       | Status job                            |
| `POST` | `/generation-jobs/:jobId/retry`                 | Retry job gagal (rate limit 10/15min) |
| `GET`  | `/documents/:documentId/generated-files`        | List file + stale detection           |

Kode: `apps/api/src/generation/generation.routes.ts`, `generation-worker.service.ts`

## Status job

```mermaid theme={null}
stateDiagram-v2
  [*] --> queued
  queued --> active: worker pickup
  active --> completed: semua doc OK
  active --> failed: error / parse fail
  failed --> queued: retry
  completed --> [*]
```

Worker membungkus `generateFromJob()` dalam try/catch — kegagalan update status `failed` + pesan error (tidak stuck `active`).

## Rate limiting

| Endpoint            | Limit             |
| ------------------- | ----------------- |
| `POST .../generate` | 20 req / 15 menit |
| `POST .../retry`    | 10 req / 15 menit |

## Retry behavior

Tombol **Retry** di frontend memanggil `handleGenerate()` dengan `documentTypes` yang benar per flow (master `bukti-1..8`, trainer 14 types) — bukan reuse job lama dengan tipe salah.

## Renderer

Service terpisah (`apps/renderer`) — menerima payload + template, mengembalikan DOCX/PPTX.

```bash theme={null}
DOCX_RENDERER_URL=http://127.0.0.1:8787   # dev
```

Production: Cloudflare Worker renderer.

## Sidebar UI states

| Komponen                | Kondisi                                      |
| ----------------------- | -------------------------------------------- |
| `SidebarSedangGenerate` | Job `queued` / `active`                      |
| `SidebarGenerateGagal`  | Job `failed` + tombol retry                  |
| `SidebarSiapDiunduh`    | File ready — detect trainer vs master labels |

## Env AI

```bash theme={null}
DEEPSEEK_API_KEY=sk-...
AI_PROVIDER=deepseek
AI_MODEL=deepseek-v4-flash
DOCX_RENDERER_URL=...
```

## Halaman terkait

* [AI overview & pipeline](/ai/overview)
* [Katalog dokumen](/ai/katalog-dokumen)
* [Prompt master](/ai/prompt-master)
* [Prompt trainer](/ai/prompt-trainer)
