# Dashboard beranda (Home) — data nyata & handoff BE

**Status FE:** `FE/pages/index.vue` sudah memanggil API dashboard (ringkas): `GET /me`, `GET /me/summary?period=week&includeToday=1`, `GET /me/focus-preview`, `GET /me/activity`, `GET /analytics/trends?align=week`, `GET /teams` + `GET /teams/:id/summary?period=week` (tim pertama). **Polling** ~90 detik. Lihat composable: `useWorkpulseMe`, `useWorkpulseAnalytics`, `useWorkpulseCalendar`.

**Kontrak BE resmi:** [`../BE/docs/BE_SPEC_DASHBOARD_HOME.md`](../BE/docs/BE_SPEC_DASHBOARD_HOME.md) (repo monorepo) atau salinan di `BE/docs` jika checkout terpisah.

**Daily Report (Kanban + JSON `body`):** [`BE_SPEC_REPORT_KANBAN_BODY_SCHEMA.md`](./BE_SPEC_REPORT_KANBAN_BODY_SCHEMA.md).

---

Bagian di bawah mempertahankan **riwayat gap analysis** sebelum endpoint `focus-preview`, `includeToday`, `teams/:id/summary`, dan query `align=week` / `days` pada `analytics/trends` tersedia; beberapa baris tabel di atas mungkin sudah tertutup oleh implementasi terbaru.

**Catatan “real-time”:** BE tidak push khusus dashboard; FE memakai **polling** (lihat atas).

---

## Endpoint BE yang sudah ada (boleh dipakai FE tanpa ubah kontrak)

| Endpoint | Auth | Isi relevan untuk dashboard |
|----------|------|------------------------------|
| `GET /api/v1/me` | Login | `id`, `name`, `email`, `role`, `isActive`, … |
| `GET /api/v1/me/summary?period=week\|month\|all` | Login | `reportsDraft`, `reportsSubmitted`, `reportsTotal`, `productivityScore` / `goalProgressPercent` (rasio submitted vs total di periode), `calendarEventsUpcoming`, `notificationsUnread` |
| `GET /api/v1/me/activity?limit=&offset=` | Login | Timeline: `items[]` dengan `type` (`report` \| `notification`), `title`, `description`, `at` |
| `GET /api/v1/analytics/summary` | Login | `reportsTotal`, `notificationsUnread` (agregat sederhana per user) |
| `GET /api/v1/analytics/trends` | Login | `reportsByDay[]`: `{ date, count }` untuk **user yang login**, ~30 hari terakhir |
| `GET /api/v1/analytics/org/summary?period=` | **Superadmin** | `reportsTotal`, `reportsDraft`, `completionRatePercent`, `distinctReportersInPeriod`, `notificationsUnreadOrgWide`, … — untuk **kartu ringkasan level organisasi** jika role superadmin |

**File referensi BE:** `internal/api/me.go` (`getMe`, `getMeSummary`, `getMeActivity`), `internal/api/rest.go` (`analyticsSummary`, `analyticsTrends`), `internal/api/analytics_org.go` (`analyticsOrgSummary`).

---

## Gap & usulan BE

### 1. Status laporan **hari ini** (Today status)

**Kebutuhan UI:** “Submitted · On time” vs draft vs belum submit.

**Skema saat ini:** tabel `reports` punya `status`, `report_date`, `created_at`, `updated_at` (`000001_init.up.sql`).

**Usulan:** perluas respons (salah satu):

- **Opsi A (minimal):** tambah field pada `GET /api/v1/me/summary` ketika `period=week` atau query terpisah `?includeToday=1`:
  - `todayReport`: `null` | `{ "id", "status", "reportDate", "updatedAt" }` untuk baris yang `report_date = CURRENT_DATE` (atau aturan zona waktu yang diputuskan produk) milik user.
- **Opsi B:** endpoint baru `GET /api/v1/me/dashboard-today` yang hanya mengembalikan status hari ini + ringkasan satu layar.

**Keputusan produk wajib:** definisi “on time” (mis. submit sebelum jam X di hari `report_date`) — jika belum didefinisikan, cukup map `status <> 'draft'` → “Submitted”.

---

### 2. Pending di **tim** (bukan hanya user sendiri)

**Kebutuhan UI:** “12 reports pending” — implikasinya agregat lintas anggota tim.

**Saat ini:** `me/summary` hanya untuk **`user_id`** pemanggil.

**Usulan:**

- Jika user punya **peran pemimpin tim** (atau superadmin): endpoint baru mis. **`GET /api/v1/teams/:id/dashboard-summary`** atau **`GET /api/v1/me/team-summary`** yang menghitung draft/submitted untuk **semua `user_id` anggota tim** (join `team_members` + `reports` dengan filter `report_date` / periode).
- Superadmin bisa memakai **`GET /api/v1/analytics/org/summary`** sebagai proxy “organisasi”, bukan per tim — beda semantik dengan copy UI “team”.

---

### 3. “Main blocker”

**Skema saat ini:** tidak ada kolom **`blocker`** pada `reports`; `analyticsOrgSummary` mengembalikan `blockerResolutionPercent: 0` (placeholder).

**Usulan (pilih satu arah produk):**

- Tambah kolom / JSON pada laporan (mis. `blockers_json` atau status alur), **atau**
- Turunkan dari **notifikasi** / **judul laporan** terbaru dengan status draft — hanya heuristik, **atau**
- Hapus klaim “blocker” dari dashboard sampai model datanya ada.

---

### 4. KPI: Attendance, on-time completion, task velocity

**Skema saat ini:** tidak ada tabel **absensi** atau **task velocity** terpisah.

**Opsi:**

- **FE + BE ringan:** map ulang kartu ke metrik yang **ada**: mis. `productivityScore` dari `me/summary`, `completionRatePercent` dari `analytics/org/summary` (superadmin), dan **sembunyikan** atau **ganti label** kartu yang tidak punya sumber data.
- **BE lanjutan:** endpoint `GET /api/v1/me/dashboard-kpis` yang menghitung definisi bisnis baru (perlu spesifikasi + migrasi jika perlu field baru).

---

### 5. Grafik **7 hari** (Mon–Sun)

**Saat ini:** `analytics/trends` mengelompokkan per **kalender** `created_at::date`, 30 hari, **per user**.

**Opsi:**

- **FE:** ambil `reportsByDay`, isi 7 slot minggu terakhir dengan 0 jika tidak ada data.
- **BE (opsional):** `GET /api/v1/analytics/trends?granularity=day&days=7&align=week` agar server yang menentukan rentang Senin–Minggu (zona waktu server vs user perlu disepakati).

---

### 6. “Focus Today” (daftar tugas prioritas)

**Usulan tanpa skema baru:** `GET /api/v1/notifications?limit=5` (jika ada) atau cuplikan dari **`me/activity`** difilter ke jenis tertentu.

**Usulan dengan BE baru:** `GET /api/v1/me/focus-items` yang mengembalikan string actionable (query gabungan notifikasi belum dibaca + laporan draft tim, dll.) — perlu aturan prioritas dari produk.

---

### 7. “Team presence” (online sekarang)

Tidak didukung oleh model data saat ini. Opsi: hapus widget, ganti dengan “anggota aktif / laporan minggu ini”, atau **integrasi presence** (WebSocket heartbeat / layanan ketiga) — di luar cakupan CRUD laporan saja.

---

## Checklist implementasi (disarankan)

1. **FE (tanpa BE baru):** wire `index.vue` ke `/me`, `/me/summary`, `/me/activity`, `/analytics/trends`; ganti/hapus widget tanpa sumber data; polling 60s.
2. **BE (minimal):** tambah **status laporan hari ini** pada `me/summary` atau endpoint kecil §1.
3. **BE (tim):** endpoint ringkasan draft tim §2 jika copy UI “team pending” harus akurat.
4. **Produk:** putuskan blocker, attendance, velocity — spesifikasi terpisah atau penyesuaian UI.

---

## Rujukan file

| Layer | Path |
|-------|------|
| UI dummy | `FE/pages/index.vue` |
| Kontrak me / activity | `BE/internal/api/me.go` |
| Kontrak analytics user | `BE/internal/api/rest.go` |
| Kontrak analytics org | `BE/internal/api/analytics_org.go` |
| Skema `reports` | `BE/internal/db/migrations/000001_init.up.sql` |

---

*Dokumen ini memisahkan **wire data nyata ke dashboard** dari **fitur produk baru** yang membutuhkan kolom atau endpoint tambahan.*
