# Daily Report — Kanban di FE, skema `reports.body` (opsional BE)

Halaman **`FE/pages/report.vue`** memakai **papan Kanban** (drag-and-drop) untuk tugas, sementara **blockers** dan **rencana besok** tetap teks. Data tugas disimpan di kolom **`reports.body`** sebagai **JSON** — **tidak perlu migrasi DB** selama tipe kolom tetap `TEXT` (cukup panjang untuk JSON).

---

## Ringkasan

| Pertanyaan | Jawaban |
|------------|---------|
| Apakah BE wajib diubah untuk Kanban? | **Tidak wajib** untuk MVP: `POST/PATCH /api/v1/reports` sudah menerima **`body`** string; FE menaruh JSON dengan schema di bawah. |
| Kapan BE perlu diperluas? | Jika ingin **query / indeks** per tugas (mis. “semua tugas status Done hari ini”), **notifikasi** per kartu, atau **validasi server** struktur — pertimbangkan kolom **`JSONB`** baru atau tabel **`report_tasks`**. |
| Kompatibilitas mundur | Laporan lama dengan `body` teks bebas (bukan JSON) tetap valid; FE memperlakukannya sebagai **tanpa tugas Kanban** (form kosong + pengguna bisa tambah kartu). |

---

## Schema JSON (`workpulse.report.v1`)

Disimpan utuh di **`reports.body`** (string JSON satu root object).

```json
{
  "schema": "workpulse.report.v1",
  "workHours": "08:00 - 17:00",
  "blockers": "Teks bebas…",
  "tomorrow": "Rencana besok…",
  "tasks": [
    { "id": "uuid-v4", "title": "Ringkas tugas", "column": "todo" },
    { "id": "…", "title": "…", "column": "doing" },
    { "id": "…", "title": "…", "column": "done" }
  ]
}
```

| Field | Wajib | Keterangan |
|-------|--------|------------|
| `schema` | Ya | Harus persis **`workpulse.report.v1`** agar FE mem-parse sebagai Kanban. |
| `workHours` | Tidak | String satu baris. |
| `blockers` | Tidak | Teks panjang. |
| `tomorrow` | Tidak | Teks panjang. |
| `tasks` | Ya (array, boleh kosong) | Setiap item: **`id`** unik (string), **`title`** non-kosong, **`column`** ∈ `todo` \| `doing` \| `done`. |

**Judul laporan (`reports.title`):** FE memakai judul tetap human-readable, mis. `Daily report · YYYY-MM-DD`, tetap memenuhi **`title` required** di BE.

**Divisi (`reports.division`):** tetap string / kode master seperti kontrak laporan yang ada (`normalizeReportDivision` di BE).

---

## Endpoint yang dipakai (tanpa ubah kontrak)

| Metode | Path | Catatan |
|--------|------|---------|
| `GET` | `/api/v1/reports` | Muat draf terbaru (urut `updated_at`); FE memilih baris `status === 'draft'`. |
| `GET` | `/api/v1/reports/:id` | Opsional: muat ulang satu laporan. |
| `POST` | `/api/v1/reports` | Buat draf pertama kali (`body` = JSON string). |
| `PATCH` | `/api/v1/reports/:id` | Autosave: `body`, `title`, `division`; submit: `status` non-`draft` (mis. `submitted`) selaras kebijakan BE/analytics. |

---

## Peningkatan BE (opsional — backlog produk)

1. **`reports.body_json JSONB`** + trigger sinkron dari `body` teks, atau isi langsung dari FE dengan `Content-Type` terpisah — untuk query GIN.
2. **Tabel `report_tasks`** + foreign key `report_id` — sumber kebenaran per kartu, audit trail, assignment.
3. **Validasi PATCH**: tolak `body` jika JSON tidak valid / schema tidak dikenal (saat ini BE menyimpan apa pun).

---

## File terkait

| Repo | Path |
|------|------|
| FE | `FE/pages/report.vue`, `FE/utils/report-kanban-payload.ts`, `FE/composables/useWorkpulseReports.ts` |
| BE | `BE/internal/api/rest.go` (`createReport`, `patchReport`, `getReport`, `listReports`) |

---

*Dokumen ini mendampingi kontrak laporan umum di kode BE; tidak mengganti aturan `division` / master organisasi.*
