# Team Monitoring: divisi, pelapor, & tim — kontrak BE

Spesifikasi produk / FE: [`../FE/docs/BE_SPEC_TEAM_MONITORING_DIVISIONS.md`](../FE/docs/BE_SPEC_TEAM_MONITORING_DIVISIONS.md).

---

## Superadmin — analytics organisasi

### `GET /api/v1/analytics/org/by-division`

- **Auth:** `requireSuperadmin`.
- Query: `period` = `7d` \| `30d` (default) \| `90d` \| `all` (sama seperti endpoint org lain).
- Respons `data`: `{ "period", "divisions": [ { "code", "label", "reportCount" } ] }`.
- **`code` / `label`:** `COALESCE(NULLIF(TRIM(r.division), ''), '(none)')` pada **`reports r`** (lihat kode `analytics_org.go`).

### `GET /api/v1/analytics/org/reporters-by-division`

- **Auth:** `requireSuperadmin`.
- Query wajib: **`division`** — string harus **persis** sama dengan `code` dari `by-division` (termasuk `"(none)"` jika divisi kosong).
- Query: `period` (sama seperti di atas).
- Respons `data`: `{ "period", "division", "reporters": [ { "userId", "name", "email", "isActive", "reportCount" } ] }`.
- Filter laporan: `COALESCE(NULLIF(TRIM(r.division), ''), '(none)') = $division` dan rentang waktu `period` pada **`r.created_at`** (bukan `created_at` mentah — hindari ambigu dengan `users.created_at`).

**Kode:** `internal/api/analytics_org.go` — `analyticsOrgByDivision`, `analyticsOrgReportersByDivision`.  
**Router:** `internal/api/router.go` — grup `/analytics/org`.

**Insiden SQL `created_at` ambigu:** [`BE_FIX_ANALYTICS_REPORTERS_BY_DIVISION_AMBIGUOUS_CREATED_AT.md`](./BE_FIX_ANALYTICS_REPORTERS_BY_DIVISION_AMBIGUOUS_CREATED_AT.md) (mirror FE: `FE/docs/BE_FIX_ANALYTICS_REPORTERS_BY_DIVISION_AMBIGUOUS_CREATED_AT.md`).

### `GET /api/v1/analytics/org/reports-by-reporter`

- **Auth:** `requireSuperadmin`.
- Query wajib: **`userId`** (pelapor), **`division`** — sama aturan seperti `reporters-by-division` (termasuk `"(none)"`).
- Query opsional: **`period`** (default `30d`) — filter waktu pada **`r.created_at`**, sama helper `orgReportsTimeFilter` / `orgPeriodLabel`.
- Query opsional: **`include=summary`** (boleh gabung koma, mis. `include=summary,foo` — hanya `summary` yang dipakai). Jika ada, respons memuat **`body` tidak dikirim utuh**; tiap elemen `reports[]` mendapat **`summary`** dari parse `workpulse.report.v1`:
  - `taskCounts`: `{ "todo", "doing", "done" }` — hanya task dengan `id` + `title` non-kosong (selaras FE `parseReportBody`).
  - `blockersPreview`: teks `blockers` dipotong **120 rune** (trim).
  - `workStart`, `workEnd`: string dari JSON jika ada.
  - Bukan schema v1 / bukan JSON → `summary` berisi nol & string kosong.
- Tanpa `include`: SELECT tidak memuat `body` (lebih ringan).
- Respons `data`: `{ "period", "division", "userId", "reports": [ … ] }` (maks. 200 baris, `updated_at` DESC).
- **Drill-down:** daftar ini selaras hitungan `reportCount` di `reporters-by-division` untuk pasangan `(userId, division, period)` yang sama.

**Kode:** `internal/api/analytics_org.go` — `analyticsOrgReportsByReporter`; ringkasan: `internal/api/org_report_body_summary.go`.

### `GET /api/v1/reports/:id` (superadmin baca)

- User **superadmin** boleh **GET** laporan apa pun (baca isi termasuk `body`), tanpa harus pemilik atau anggota tim.
- **`PATCH /reports/:id`** tetap hanya pemilik laporan.

---

## User biasa — tim

### `GET /api/v1/teams`

- Tim yang diikuti user (join `team_members`).

### `GET /api/v1/teams/:id/members`

- Hanya jika caller **anggota** tim tersebut.
- Setiap anggota: `id`, `email`, `name`, `role`, **`isActive`** (kolom `users.is_active`).

**Kode:** `listTeams`, `teamMembers` di `internal/api/rest.go`.

**Tugas Kanban di Daily Report** tidak ditampilkan di Team Monitoring — lihat [`BE_SPEC_DAILY_REPORT_TASKS_VS_CALENDAR_AND_TEAM.md`](./BE_SPEC_DAILY_REPORT_TASKS_VS_CALENDAR_AND_TEAM.md).

---

## Master divisi & anggota (direktori)

Master **`org_divisions`**, **`org_division_members`** (`org_role`), validasi **`reports.division`**, merge **`by-division`**, dijelaskan di [`BE_SPEC_ORG_DIVISIONS_MASTER_AND_CRUD.md`](./BE_SPEC_ORG_DIVISIONS_MASTER_AND_CRUD.md). UI Employees (baca laporan + mutasi master/anggota): [`BE_SPEC_EMPLOYEE_ORG_MANAGEMENT.md`](./BE_SPEC_EMPLOYEE_ORG_MANAGEMENT.md).

**Catatan `reporters-by-division`:** filter laporan memakai **`LOWER(TRIM(...))`** untuk parameter selain `(none)` (lihat kode di `analytics_org.go`), selaras dengan `code` dari `by-division` setelah master aktif dipakai.

---

## Deploy

```bash
cd /var/www/html/wp-system/BE
go build -o bin/api ./cmd/api/
pm2 restart workpulse-api
```
