# Kalender: tim, divisi, & organisasi — implementasi BE

Spesifikasi / konteks FE: [`../FE/docs/BE_SPEC_CALENDAR_TEAMS_AND_DIVISIONS.md`](../FE/docs/BE_SPEC_CALENDAR_TEAMS_AND_DIVISIONS.md).

---

## `GET /api/v1/teams`

Tidak diubah — daftar tim yang diikuti user (`listTeams` di `rest.go`).

---

## `GET /api/v1/calendar/events`

Query **wajib:** `from`, `to` (`YYYY-MM-DD` atau RFC3339, diteruskan ke PostgreSQL).

- Kalender **pribadi:** `calendar_events.user_id` = pemilik token.
- **`teamName`** (opsional): dari `LEFT JOIN teams` pada `team_id`.
- **`teamId`** (opsional query): jika diisi, hanya baris dengan `team_id` tersebut (validasi angka).

Respons `data`: array objek; field inti sama seperti sebelumnya + `teamName` bila ada.

**Tugas Daily Report (Kanban):** tidak berasal dari `calendar_events` — lihat [`BE_SPEC_DAILY_REPORT_TASKS_VS_CALENDAR_AND_TEAM.md`](./BE_SPEC_DAILY_REPORT_TASKS_VS_CALENDAR_AND_TEAM.md).

---

## `GET /api/v1/calendar/org-events` *(superadmin)*

**Auth:** `authMiddleware` + **`requireSuperadmin`**.

Query wajib: `from`, `to` (sama).

Opsional:

| Query | Fungsi |
|-------|--------|
| `teamId` | Hanya acara dengan `team_id` tersebut |
| `division` | Hanya user pemilik acara yang punya minimal satu **laporan** (`reports.division`, perbandingan case-insensitive trim) dengan divisi tersebut |
| `userId` | Batasi ke acara milik user id itu |

Respons: array seperti kalender pribadi, plus **`organizerName`** (nama user pemilik acara) dan **`teamName`** opsional.

---

## Realtime

SSE/WebSocket untuk kalender — **belum** diimplementasikan; gunakan polling di FE.

---

## File kode

- `internal/api/rest.go` — `listCalendar`
- `internal/api/calendar_org.go` — `listCalendarOrg`
- `internal/api/router.go` — `/calendar/events`, grup `/calendar` + `/org-events`

Deploy: `go build -o bin/api ./cmd/api/` + restart PM2 `workpulse-api`.
