135dika / analytics_response.md

Last active 1 month ago

Like 0

135dika revised this gist 1 month ago · 8d49fd6

1 file changed, 130 insertions

analytics_response.md (file created)
@@ -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.