| @@ -0,0 +1,130 @@ | |||
| 1 | + | # Analytics — Perubahan untuk Tim Frontend | |
| 2 | + | ||
| 3 | + | Commit: `aca7870` (branch `dev`). Semua perubahan di tiga layar analytics. **Angka desimal sekarang 2 angka di belakang koma** (integer ter-render tanpa koma, tipe tetap number). | |
| 4 | + | ||
| 5 | + | --- | |
| 6 | + | ||
| 7 | + | ## 1. Analytics Action Plan (project) | |
| 8 | + | ||
| 9 | + | `GET /api/action-plans/projects/:projectId/analytics` | |
| 10 | + | ||
| 11 | + | ### Query params | |
| 12 | + | ||
| 13 | + | | Param | Status | Nilai | Default | | |
| 14 | + | |---|---|---|---| | |
| 15 | + | | `layout` | — | `detailed` \| `simplified` | `detailed` | | |
| 16 | + | | `granularity` | — | `daily` \| `weekly` \| `monthly` | `weekly` | | |
| 17 | + | | `percentage_by` | **BARU** | `work_weight` \| `completion_of_work` \| `duration_day` | `work_weight` | | |
| 18 | + | | `search`, `activityName`, `startDate`, `endDate` | — | sama seperti sebelumnya | — | | |
| 19 | + | ||
| 20 | + | ### Response | |
| 21 | + | ||
| 22 | + | - **BARU** echo `data.percentageBy` (camelCase di layar project). | |
| 23 | + | - Semua angka (cards, tabular, s-curve) kini **round 2 desimal** (sebelumnya 3). | |
| 24 | + | ||
| 25 | + | ### Semantik `percentage_by` | |
| 26 | + | ||
| 27 | + | | Mode | Cara hitung | | |
| 28 | + | |---|---| | |
| 29 | + | | `work_weight` | Rupiah `workWeight` sebagai bobot — leaf `workWeight` kosong/0 **tetap tidak dihitung** (perilaku lama) | | |
| 30 | + | | `completion_of_work` | Semua leaf bobot sama (1) — murni rata-rata % progress | | |
| 31 | + | | `duration_day` | Bobot = jumlah hari `startDate`→`endDate` (ceil, min. 1 hari) — leaf tanpa tanggal tidak dihitung | | |
| 32 | + | ||
| 33 | + | > Leaf dengan `workWeight` kosong tapi `startDate`+`endDate` terisi = **work berbasis durasi/timeline** (penanda: weight 0/kosong). Data `workWeight` tidak di-unpack dari durasi — hitungannya derived on-the-fly di backend. | |
| 34 | + | ||
| 35 | + | --- | |
| 36 | + | ||
| 37 | + | ## 2. Analytics Agenda | |
| 38 | + | ||
| 39 | + | `GET /api/agendas/:agendaId/analytics` | |
| 40 | + | ||
| 41 | + | ### Query params | |
| 42 | + | ||
| 43 | + | | Param | Status | Nilai | Default | | |
| 44 | + | |---|---|---|---| | |
| 45 | + | | `granularity` | **DIUBAH** | hanya `weekly` \| `monthly` (⚡ `daily` dihapus → 400) | `weekly` | | |
| 46 | + | | `start_date`, `end_date` | — | RFC date string, snake_case | tanpa batas | | |
| 47 | + | | `project_type` | **BARU** | `all` \| `self_managed` \| `consultant` | `all` | | |
| 48 | + | | `percentage_by` | **BARU** | `work_weight` \| `completion_of_work` \| `duration_day` | `work_weight` | | |
| 49 | + | | `program_name` | **BARU** | string; mempersempit SELURUH report (cards + curve + tabel) ke program yang cocok | — | | |
| 50 | + | | `activity_name` | **BARU** | string; khusus memfilter `data.action_plan_tabular` saja | — | | |
| 51 | + | | `q` | **DIHAPUS** | → diganti `activity_name` / `program_name` | — | | |
| 52 | + | ||
| 53 | + | ### Response | |
| 54 | + | ||
| 55 | + | ```jsonc | |
| 56 | + | data: { | |
| 57 | + | "scope": { "id": "...", "name": "...", "type": "agenda" }, | |
| 58 | + | "percentage_by": "work_weight", // 🆕 echo (camelCase island ada di project analytics) | |
| 59 | + | "project_type": "all", // 🆕 echo | |
| 60 | + | "overview": { "total_children", "total_action_plan", "total_plan", "total_realization", "overall_deviation" }, | |
| 61 | + | "s_curve": { "granularity": "weekly", "plan": [...], "realization": [...] }, | |
| 62 | + | "tabular": { | |
| 63 | + | "unit": "program", | |
| 64 | + | "total": { "plan", "realization", "deviation" }, | |
| 65 | + | "rows": [ // ⚠️ SEMANTIK BARU: lihat §4 | |
| 66 | + | { "id", "name", "plan", "realization", "deviation", "total_action_plan" } | |
| 67 | + | ] | |
| 68 | + | }, | |
| 69 | + | "action_plan_tabular": [ // 🆕 KHUSUS agenda (undefined di program) | |
| 70 | + | { | |
| 71 | + | "name": "Pondasi", | |
| 72 | + | "plan": 25.2, "realization": 18.3, "deviation": -6.9, | |
| 73 | + | "total_action_plan": 22, | |
| 74 | + | "tasks": [ { "name", "plan", "realization", "deviation", "total_action_plan" } ] | |
| 75 | + | } | |
| 76 | + | ] | |
| 77 | + | } | |
| 78 | + | ``` | |
| 79 | + | ||
| 80 | + | - `action_plan_tabular` = action plan 2 level (activity → task), sama seperti tabular di analytics action plan. `activity_name` hanya memfilter tabel ini; activity yang match membawa semua task-nya. | |
| 81 | + | - `tabular.total` / `overview` = weighted mean 0–100 seluruh node; `action_plan_tabular` tidak punya baris Total — Total-nya itu (`overview.total_plan` dst.), jangan cari di dalam tabel. | |
| 82 | + | ||
| 83 | + | --- | |
| 84 | + | ||
| 85 | + | ## 3. Analytics Program | |
| 86 | + | ||
| 87 | + | `GET /api/programs/:programId/analytics` | |
| 88 | + | ||
| 89 | + | Sama seperti agenda, dengan perbedaan: | |
| 90 | + | ||
| 91 | + | | Perbedaan | Nilai | | |
| 92 | + | |---|---| | |
| 93 | + | | Filter nama | `project_name` (whole-report) menggantikan `program_name` | | |
| 94 | + | | Tabular | 1 baris per **project** (`unit: "project"`) — seperti sebelumnya | | |
| 95 | + | | `action_plan_tabular` | **tidak ada** (dan `activity_name` tidak berlaku) | | |
| 96 | + | ||
| 97 | + | `granularity=weekly|monthly` (serupa agenda, `daily` dihapus), `start_date`/`end_date`, `project_type`, `percentage_by` sama. | |
| 98 | + | ||
| 99 | + | --- | |
| 100 | + | ||
| 101 | + | ## 4. ⚠️ Perubahan semantik tabular (BREAKING) | |
| 102 | + | ||
| 103 | + | **Tabular agenda & program sekarang PRORATA (kontribusi)**, seperti tabular project-tier: | |
| 104 | + | ||
| 105 | + | - Sebelumnya: tiap baris = weighted mean 0–100 leaves program/project itu sendiri (Σ baris bisa melebihi 100). | |
| 106 | + | - Sekarang: tiap baris = **share kontribusi terhadap total node** (bobot baris ÷ total bobot seluruh node). **Σ baris = `total`**, tidak akan lebih dari 100 — mengakumulasi kumulatif aman. | |
| 107 | + | - `deviation` tetap dihitung dari operand RAW lalu di-round. | |
| 108 | + | - Baris child tanpa action plan → `plan/realization/deviation = null` (bukan `0`). | |
| 109 | + | ||
| 110 | + | Jika layar lama menganggap row `plan` sebagai progress 0–100 child, harus disesuaikan (atau render share). | |
| 111 | + | ||
| 112 | + | ### Contoh | |
| 113 | + | ||
| 114 | + | Node dengan 2 program masing-masing leaf 100% : baris kini `50 / 50` (bukan `100 / 100`), dan `total = 100`. | |
| 115 | + | ||
| 116 | + | --- | |
| 117 | + | ||
| 118 | + | ## 5. Ringkasan breaking changes | |
| 119 | + | ||
| 120 | + | 1. `q` pada agenda/program analytics **dihapus** → pakai `activity_name` (agenda) / `program_name` (agenda) / `project_name` (program). | |
| 121 | + | 2. `granularity=daily` di agenda/program → sekarang **400**. Gunakan `weekly`|`monthly`. | |
| 122 | + | 3. Nilai `tabular.rows` agenda/program berubah makna (kontribusi, bukan 0–100). | |
| 123 | + | 4. Semua angka rounded 2 desimal (sebelumnya 3). | |
| 124 | + | 5. Echo baru: `data.percentageBy` (project tier), `data.percentage_by` + `data.project_type` (agenda/program). | |
| 125 | + | 6. Field baru: `data.action_plan_tabular` (agenda). | |
| 126 | + | ||
| 127 | + | ## 6. Referensi | |
| 128 | + | ||
| 129 | + | - Contoh payload lengkap per endpoint: `.markdown/ANALYTICS_RESPONSE_SHAPES.md` | |
| 130 | + | - Query params ditulis snake_case di agenda/program (`start_date`, `percentage_by`, `project_type`) dan camelCase di project analytics (`startDate`, `percentage_by`→`percentage_by` snake juga tapi `activityName`/`search` camelCase) — perhatikan beda konvensi antar endpoint. | |
135dika / analytics_response.md
Last active 1 month ago
135dika revised this gist 1 month ago · 8d49fd6
1 file changed, 130 insertions