DavMelchi commited on
Commit
f68be5e
·
1 Parent(s): 67209eb

Add GitHub Actions workflow for Panel app deployment to Hugging Face Spaces with path-based triggers, VS Code project color customization, and comprehensive KPI health check drill-down documentation including group-based filtering, SLA benchmarking, timeline visualization, and complaint sites roadmap

Browse files
.github/workflows/kpi_analysis.yml ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync Panel (kpi_analysis) to Hugging Face
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "panel_app/**"
8
+ - "process_kpi/**"
9
+ - "utils/**"
10
+ - "data/**"
11
+ - "physical_db/**"
12
+ - "hf_spaces/kpi_analysis/**"
13
+ - ".github/workflows/kpi_analysis.yml"
14
+
15
+ workflow_dispatch:
16
+
17
+ jobs:
18
+ sync-panel-to-hub:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ fetch-depth: 0
24
+ lfs: false
25
+
26
+ - name: Build Space bundle
27
+ run: |
28
+ rm -rf hf_space
29
+ mkdir -p hf_space
30
+
31
+ # Space root files
32
+ cp -r hf_spaces/kpi_analysis/* hf_space/
33
+
34
+ # App code + shared modules
35
+ cp -r panel_app hf_space/
36
+ cp -r process_kpi hf_space/
37
+ cp -r utils hf_space/
38
+
39
+ # Data files needed by the app
40
+ cp -r data hf_space/
41
+ cp -r physical_db hf_space/
42
+
43
+ - name: Push bundle to Hugging Face Space
44
+ env:
45
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
46
+ run: |
47
+ cd hf_space
48
+ git init
49
+ git config user.name "github-actions"
50
+ git config user.email "[email protected]"
51
+ git add -A
52
+ git commit -m "Deploy Panel Space" || true
53
+ git branch -M main
54
+ git remote add hf https://DavMelchi:[email protected]/spaces/DavMelchi/kpi_analysis
55
+ git push --force hf main
.github/workflows/main.yml CHANGED
@@ -2,6 +2,22 @@ name: Sync 2 to Hugging Face hub
2
  on:
3
  push:
4
  branches: [main]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  # to run this workflow manually from the Actions tab
7
  workflow_dispatch:
 
2
  on:
3
  push:
4
  branches: [main]
5
+ paths:
6
+ - "app.py"
7
+ - "apps/**"
8
+ - "assets/**"
9
+ - "queries/**"
10
+ - "utils/**"
11
+ - "process_kpi/**"
12
+ - "data/**"
13
+ - "physical_db/**"
14
+ - ".streamlit/**"
15
+ - "requirements.txt"
16
+ - "README.md"
17
+ - "!.github/workflows/kpi_analysis.yml"
18
+ - "!hf_spaces/**"
19
+ - "!panel_app/**"
20
+ - "!process_kpi/kpi_health_check/**"
21
 
22
  # to run this workflow manually from the Actions tab
23
  workflow_dispatch:
.vscode/settings.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "projectColors.mainColor": "#1e22fa",
3
+ "window.title": "${rootName}${separator}${profileName}${separator}${appName}${separator}${activeEditorShort}${dirty}",
4
+ "workbench.colorCustomizations": {
5
+ "statusBarItem.warningBackground": "#1e22fa",
6
+ "statusBarItem.warningForeground": "#ffffff",
7
+ "statusBarItem.warningHoverBackground": "#1e22fa",
8
+ "statusBarItem.warningHoverForeground": "#ffffff90",
9
+ "statusBarItem.remoteBackground": "#1e22fa",
10
+ "statusBarItem.remoteForeground": "#ffffff",
11
+ "statusBarItem.remoteHoverBackground": "#1e22fa",
12
+ "statusBarItem.remoteHoverForeground": "#ffffff90",
13
+ "statusBar.background": "#1e22fa",
14
+ "statusBar.foreground": "#ffffff",
15
+ "statusBar.border": "#1e22fa",
16
+ "statusBar.debuggingBackground": "#1e22fa",
17
+ "statusBar.debuggingForeground": "#ffffff",
18
+ "statusBar.debuggingBorder": "#1e22fa",
19
+ "statusBar.noFolderBackground": "#1e22fa",
20
+ "statusBar.noFolderForeground": "#ffffff",
21
+ "statusBar.noFolderBorder": "#1e22fa",
22
+ "statusBar.prominentBackground": "#1e22fa",
23
+ "statusBar.prominentForeground": "#ffffff",
24
+ "statusBar.prominentHoverBackground": "#1e22fa",
25
+ "statusBar.prominentHoverForeground": "#ffffff90",
26
+ "focusBorder": "#1e22fa99",
27
+ "progressBar.background": "#1e22fa",
28
+ "textLink.foreground": "#5e62ff",
29
+ "textLink.activeForeground": "#6b6fff",
30
+ "selection.background": "#1115ed",
31
+ "list.highlightForeground": "#1e22fa",
32
+ "list.focusAndSelectionOutline": "#1e22fa99",
33
+ "button.background": "#1e22fa",
34
+ "button.foreground": "#ffffff",
35
+ "button.hoverBackground": "#2b2fff",
36
+ "tab.activeBorderTop": "#2b2fff",
37
+ "pickerGroup.foreground": "#2b2fff",
38
+ "list.activeSelectionBackground": "#1e22fa4d",
39
+ "panelTitle.activeBorder": "#2b2fff",
40
+ "activityBar.activeBorder": "#1e22fa",
41
+ "activityBarBadge.foreground": "#ffffff",
42
+ "activityBarBadge.background": "#1e22fa"
43
+ },
44
+ "projectColors.isActivityBarColored": false,
45
+ "projectColors.isProjectNameColored": false,
46
+ "projectColors.isStatusBarColored": false,
47
+ "projectColors.isTitleBarColored": false,
48
+ "projectColors.setWindowTitle": false,
49
+ "projectColors.name": "OML_DB",
50
+ "projectColors.isActiveItemsColored": true
51
+ }
documentations/kpi_health_check_drilldown_graphs_plan.md ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # KPI Health Check – Plan final UX Drill-down (Graphes / Groupes KPI / SLA) – V2
2
+
3
+ ## Objectifs
4
+
5
+ - Rendre le drill-down **plus lisible** pour analyser rapidement un site.
6
+ - Permettre une vue “site” où les KPI sont **regroupés par nature** (success rate, fails, throughput, traffic, availability, etc.).
7
+ - Garder une interaction **Plotly native**: légende cliquable pour masquer/afficher des KPI individuellement.
8
+ - Ajouter un **benchmark** basé sur les SLA/règles (quand c’est pertinent) sans mélanger des KPI hétérogènes.
9
+
10
+ ## Non-objectifs (scope control)
11
+
12
+ - Pas de clustering/ML automatique des KPI.
13
+ - Pas de refonte globale de l’UI (on reste dans la section drill-down existante).
14
+ - Pas de comparaison multi-sites sur cette itération (site unique, plus lisible).
15
+
16
+ ## Contraintes / invariants
17
+
18
+ - Ne pas casser les fonctionnalités existantes:
19
+ - sélection KPI (`kpi_select`), comparaison multi-KPI (`kpi_compare_select`), normalisation, export drill-down.
20
+ - cache des figures et guard anti-récursion déjà en place.
21
+ - Les KPI n’ont pas tous la même unité: éviter les graphes qui mélangent des échelles incompatibles.
22
+ - Modularité: éviter d’alourdir `panel_app/kpi_health_check_panel.py`. La logique “métier” de drill-down (groupes, sélection KPI, benchmark, figures) doit être extraite en modules.
23
+
24
+ ## Modularité / architecture (production)
25
+
26
+ Objectif: garder `panel_app/kpi_health_check_panel.py` comme couche d’orchestration (widgets + callbacks) et déplacer la logique testable dans des modules dédiés.
27
+
28
+ Découpage proposé:
29
+
30
+ - `process_kpi/kpi_health_check/kpi_groups.py`
31
+ - classification KPI -> groupe
32
+ - résolution collisions + règles de priorité
33
+ - sélection top-N (perfs)
34
+
35
+ - `process_kpi/kpi_health_check/benchmarks.py`
36
+ - calcul des métriques SLA (median_recent, %BAD recent)
37
+ - calcul quantiles population (si bonus)
38
+
39
+ - `panel_app/kpi_health_check_drilldown_plots.py`
40
+ - construction des figures Plotly (trend annoté, timeline BAD)
41
+ - conventions `legendgroup` + styles
42
+
43
+ Note: le découpage exact peut être ajusté selon ce qui est le plus simple à tester, mais la contrainte “pas un gros fichier” est un invariant.
44
+
45
+ ## Définitions
46
+
47
+ - **KPI “tracé”**: KPI qui apparaît comme une trace Plotly (ligne/markers).
48
+ - **Groupe KPI**: catégorie sémantique (success rate / fails / traffic / etc.) utilisée pour filtrer/organiser.
49
+ - **Benchmark SLA**: comparaison au seuil `sla` des rules, alignée avec la logique `is_bad()`.
50
+
51
+ ## 1) Groupes KPI “par nature” (meilleure option)
52
+
53
+ ### Proposition retenue
54
+
55
+ - Ajouter un widget: **`kpi_group_select`** (Select / Autocomplete / Radio) avec:
56
+ - `All (selected KPIs)`
57
+ - `Success rate (>= SLA / proche 100%)`
58
+ - `Fails / Drop / Block (<= SLA / proche 0)`
59
+ - `Throughput / Debit`
60
+ - `Traffic / Volume`
61
+ - `Availability / Dispo`
62
+ - `Latency / Delay`
63
+ - `Other`
64
+
65
+ - Ajouter un widget: **`kpi_group_mode`** (Select):
66
+ - `Filter KPI list only (recommended)`
67
+ - `Add top-N KPIs from group to compare`
68
+
69
+ ### Comment on conserve la sélection individuelle via Plotly
70
+
71
+ - Le graphe “Trend (site)” affichera plusieurs traces (1 trace = 1 KPI).
72
+ - Les traces seront **groupées** dans la légende via `legendgroup`.
73
+ - La légende Plotly permet:
74
+ - click: hide/show trace
75
+ - double-click: isolate trace
76
+
77
+ => L’utilisateur peut afficher un groupe complet puis isoler un KPI d’un click.
78
+
79
+ ### Méthode de classification (règles)
80
+
81
+ #### Source of truth + résolution des collisions (production-grade)
82
+
83
+ - **Priorité 1 (future-proof)**: overrides explicites (si on ajoute plus tard un mapping KPI->groupe dans un fichier/profil).
84
+ - **Priorité 2**: indices issus des rules (direction + présence SLA) quand disponibles.
85
+ - **Priorité 3**: heuristiques sur le nom du KPI (regex).
86
+
87
+ Règle: **un KPI appartient à 0..1 groupe**. Si plusieurs regex matchent, on prend le premier match selon l’ordre de priorité défini ci-dessous.
88
+
89
+ Patterns initiaux (ajustables):
90
+
91
+ - Success rate: `cssr|success|attach|setup|erab|rrc|\basr\b|\bsr\b`
92
+ - Fails/Drop/Block: `drop|fail|block|reject|deny|accessibility.*fail|retention.*fail`
93
+ - Throughput/debit: `throughput|thp|debit|dl.*rate|ul.*rate|bitrate`
94
+ - Traffic: `traffic|volume|erl|payload|gbytes|gb`
95
+ - Availability: `availability|avail|unavailability|unavail|dispo|disponibil|uptime`
96
+ - Latency: `latency|delay|\brt\b|rtt`
97
+
98
+ Note: on évite de matcher `sr` trop largement (trop de faux positifs). `sr` est uniquement accepté sous forme de mot (`\bsr\b`).
99
+
100
+ ## 1.1) Garde-fous performance (obligatoire en prod)
101
+
102
+ - Ajouter un paramètre interne `max_kpis_in_plot` (recommandé: 12).
103
+ - Si la liste de KPI à tracer dépasse `max_kpis_in_plot`:
104
+ - on réduit à top-N selon `% BAD days (recent)` calculé via `is_bad()`.
105
+ - si égalité, tri secondaire: variance recent ou `anomaly_score` si disponible.
106
+
107
+ ## 2) Trend “annoté” (lisibilité)
108
+
109
+ ### Ajouts sur le graphe trend
110
+
111
+ Pour le KPI sélectionné (ou pour chaque KPI tracé quand affichage en groupe):
112
+
113
+ - **Baseline médiane** (ligne horizontale)
114
+ - **Bande de seuil relatif** (baseline ± `rel_threshold_pct`)
115
+ - **SLA** si présent (ligne horizontale)
116
+ - **Points colorés** par jour:
117
+ - OK vs BAD selon `is_bad()`
118
+ - **Shading des fenêtres**:
119
+ - baseline window
120
+ - recent window
121
+
122
+ Règle: le status OK/BAD doit être **strictement cohérent** avec l’engine (utiliser `is_bad()` et les mêmes paramètres `rel_threshold_pct`, `sla`, `direction`).
123
+
124
+ ### Mode groupe
125
+
126
+ - Si le groupe contient plusieurs KPI:
127
+ - par défaut (recommended): le groupe **filtre** la liste de KPI proposée à l’utilisateur; le graphe trace `kpi_select` + `kpi_compare_select`.
128
+ - option alternative: `Add top-N KPIs from group to compare` ajoute automatiquement top-N KPI au `kpi_compare_select` (avec limite `max_kpis_in_plot`).
129
+
130
+ ## 3) Timeline “BAD days / streak”
131
+
132
+ - Ajouter un sous-graphe (subplot) ou un second panneau:
133
+ - une barre par jour: 0/1 BAD
134
+ - annotations: longueur de streak et seuil `min_consecutive_days`
135
+
136
+ Objectif: expliquer rapidement le passage DEGRADED -> PERSISTENT.
137
+
138
+ ## 4) Benchmark basé sur SLA (et option population)
139
+
140
+ ### Benchmark SLA (demandé)
141
+
142
+ - Pour chaque KPI tracé:
143
+ - afficher la **ligne SLA** si `sla` est un nombre.
144
+ - afficher une métrique synthèse (annotation ou mini-table):
145
+ - `% BAD days (recent)` basé sur `is_bad()`.
146
+ - `median_recent` vs `sla`.
147
+
148
+ Cas direction:
149
+
150
+ - `higher_is_better`: BAD si (valeur trop basse vs baseline et/ou < SLA selon la règle `is_bad`).
151
+ - `lower_is_better`: BAD si (valeur trop haute vs baseline et/ou > SLA selon la règle `is_bad`).
152
+
153
+ ### Option “population benchmark” (bonus)
154
+
155
+ - Afficher `p50` et `p90` (ou p10/p90 selon direction) sur l’ensemble des sites (ou sur la même City)
156
+ - Important:
157
+ - uniquement pour un KPI à la fois (ou normalisation obligatoire)
158
+
159
+ ## 5) UX / Layout proposé
160
+
161
+ Dans la section Drill-down:
162
+
163
+ - Ligne 1: `site_select`, `rat_select`
164
+ - Ligne 2: `kpi_select`, `kpi_compare_select`, `kpi_compare_norm`
165
+ - Ligne 3 (nouveau): `kpi_group_select`, `kpi_group_mode`, (option) `benchmark_mode`
166
+ - Plots:
167
+ - Trend annoté (grand)
168
+ - Timeline BAD (petit, dessous)
169
+ - Heatmap / Histogram (déjà existants)
170
+
171
+ ## 6) Impact code (zones à modifier)
172
+
173
+ - `panel_app/kpi_health_check_panel.py`
174
+ - Ajout widgets (group + benchmark options)
175
+ - Orchestration `_update_site_view`:
176
+ - récupérer les dataframes filtrées
177
+ - appeler les fonctions des modules (group selection / benchmark / plot building)
178
+ - pousser les figures dans les panes
179
+ - Cache: intégrer les nouveaux paramètres dans `_drilldown_cache_key`.
180
+
181
+ - `process_kpi/kpi_health_check/kpi_groups.py`
182
+ - nouvelle logique de groupe KPI + top-N
183
+
184
+ - `process_kpi/kpi_health_check/benchmarks.py`
185
+ - nouveaux calculs benchmark SLA (+ population optionnel)
186
+
187
+ - `panel_app/kpi_health_check_drilldown_plots.py`
188
+ - builders Plotly (trend annoté + timeline BAD)
189
+
190
+ Paramètres à ajouter dans la cache key:
191
+
192
+ - `kpi_group_select.value`
193
+ - `kpi_group_mode.value`
194
+ - `benchmark_mode.value`
195
+ - `max_kpis_in_plot`
196
+
197
+ Persistance profil (si on valide):
198
+
199
+ - `kpi_group_selected`
200
+ - `kpi_group_mode`
201
+ - `benchmark_mode`
202
+ - `max_kpis_in_plot` (si exposé)
203
+
204
+ - Optionnel (si on veut isoler la logique):
205
+ - nouveau module utilitaire `process_kpi/kpi_health_check/kpi_groups.py` (mais on peut rester inline pour v1).
206
+
207
+ ## 7) Critères d’acceptation
208
+
209
+ - Quand je sélectionne un site/RAT:
210
+ - je vois un trend lisible avec baseline/seuil/SLA
211
+ - je peux masquer/afficher des KPI dans la légende
212
+ - Quand je choisis un groupe:
213
+ - le graphe affiche les KPI du groupe (selon mode)
214
+ - la légende permet d’isoler un KPI
215
+ - Le benchmark SLA apparaît seulement si SLA existe.
216
+ - Aucun effet de bord sur export / cache / callbacks.
217
+
218
+ ## 7.1) Risques & mitigations
219
+
220
+ - Noms KPI hétérogènes (vendors) => fallback `Other` + regex ajustables.
221
+ - Trop de KPI à tracer => `max_kpis_in_plot` + top-N.
222
+ - SLA incohérents (NaN/texte) => ignorer SLA et afficher seulement baseline/seuil.
223
+
224
+ ## 8) Ordre de livraison (recommandé)
225
+
226
+ 1. Ajouter widgets groupes + logique de sélection KPI (garde-fous perf)
227
+ 2. Trend annoté (baseline + seuil + SLA)
228
+ 3. Timeline BAD/streak
229
+ 4. Population benchmark (optionnel)
230
+
231
+ ## Definition of Done (DoD)
232
+
233
+ - Démo: 1 site 2G + 1 site 3G + 1 site LTE.
234
+ - Vérifier que:
235
+ - double-clic tables => drill-down OK.
236
+ - cache drill-down fonctionne (pas de lag, pas de rerender inutile).
237
+ - export drill-down OK.
238
+
239
+ ## Questions à valider
240
+
241
+ - Quels groupes minimum tu veux (liste finale) ?
242
+ - En mode groupe, tu veux:
243
+ - tracer tous les KPI du groupe ? ou
244
+ - limiter à ceux cochés dans `Compare KPIs` ? (recommandé)
245
+ - Pour le benchmark:
246
+ - SLA uniquement (demandé)
247
+ - +option population (bonus) ?
documentations/kpi_health_check_improvement_roadmap.md ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # KPI Health Check (Panel) — Plan d’amélioration (Roadmap)
2
+
3
+ ## 0) Objectif
4
+
5
+ Consolider l’app **KPI Health Check** pour une utilisation “NPO / exploitation” plus fluide et plus actionnable.
6
+
7
+ Axes demandés:
8
+
9
+ - **[A] Exploitation / priorisation** (alert pack, ops queue, snapshot/delta, RCA hints)
10
+ - **[B] Visualisation** (map des sites, corrélation KPI)
11
+
12
+ Décision prise:
13
+
14
+ - **“Complaint sites only” = UI + export Excel (les deux)**
15
+
16
+ Non-scope:
17
+
18
+ - Génération PDF / evidence pack (optionnel, non prioritaire).
19
+
20
+ ## 0.1) Principes (invariants)
21
+
22
+ - **Compatibilité**: ne pas casser l’existant (tables, drill-down, export principal).
23
+ - **Performance**: éviter les recalculs inutiles (réutiliser caches/versions déjà en place dans l’UI).
24
+ - **Robustesse données**: gérer proprement `NO_DATA`, colonnes manquantes, coordonnées absentes.
25
+ - **Export Excel**: garder des noms d’onglets **stables** (important pour les utilisateurs qui automatisent).
26
+
27
+ ---
28
+
29
+ ## 1) État actuel (déjà en place)
30
+
31
+ ### 1.1 Flux de l’app
32
+
33
+ - Upload KPI **2G/3G/LTE** (CSV/ZIP)
34
+ - Normalisation `date_only`, `site_code`, enrichissement éventuel `City/Lat/Lon`
35
+ - Construction + édition des **rules** (`direction`, `sla`)
36
+ - Health-check: `OK / DEGRADED / PERSISTENT_DEGRADED / RESOLVED / NO_DATA`
37
+ - Synthèses:
38
+ - `Site_Summary`
39
+ - `MultiRAT_Summary` (score criticité)
40
+ - `Top_Anomalies` (score anomaly)
41
+ - Drill-down: trend + heatmap + histogram
42
+ - Export Excel (Datasets / KPI Rules / Summary / Status / MultiRAT / Top)
43
+ - Gestion: presets + profiles
44
+ - Filtre existant: checkbox **Only complaint sites** (filtre les tables multi-rat / top anomalies)
45
+
46
+ ### 1.2 Fichiers “source of truth”
47
+
48
+ - UI:
49
+ - `panel_app/kpi_health_check_panel.py`
50
+ - Export:
51
+ - `process_kpi/kpi_health_check/export.py`
52
+ - Calculs:
53
+ - `process_kpi/kpi_health_check/engine.py`
54
+ - `process_kpi/kpi_health_check/multi_rat.py`
55
+
56
+ ---
57
+
58
+ ## 2) Roadmap (ordre recommandé)
59
+
60
+ ### Phase 1 — Complaint sites only (UI + Export) (priorité haute)
61
+
62
+ #### 2.1 UI: onglet dédié “Complaint sites only”
63
+
64
+ But: ne plus dépendre d’un filtre à cocher; fournir un écran prêt à l’emploi.
65
+
66
+ Contenu onglet:
67
+
68
+ - `MultiRAT Summary (Complaint)`
69
+ - `Top Anomalies (Complaint)`
70
+ - Optionnel: un petit “mini résumé” (counts)
71
+
72
+ Spécifications:
73
+
74
+ - Les tables doivent être **toujours** filtrées sur `is_complaint_site == True`.
75
+ - Les interactions existantes restent:
76
+ - double-click (ou click) pour appliquer le drill-down (`_handle_double_click` + `_apply_drilldown_selection`).
77
+
78
+ Implémentation (point d’intégration):
79
+
80
+ - Créer 2 nouveaux `Tabulator` dans `kpi_health_check_panel.py`, alimentés par une fonction de refresh dédiée.
81
+ - Réutiliser la logique existante de flag `is_complaint_site` déjà posée dans `_apply_complaint_flags()`.
82
+
83
+ Critères d’acceptation:
84
+
85
+ - Après `Run health check`, l’onglet affiche uniquement les complaint sites.
86
+ - Les filtres “city / min score / top RAT / status” ne doivent pas casser l’onglet.
87
+ - Si la liste plaintes est vide/non trouvée, l’onglet reste vide (ou affiche un message) **sans erreur**.
88
+
89
+ #### 2.2 Export Excel: feuilles “Complaint sites only”
90
+
91
+ But: avoir un export directement partageable “ops / plaintes”.
92
+
93
+ Feuilles proposées:
94
+
95
+ - `Complaint_MultiRAT`
96
+ - `Complaint_Top_Anomalies`
97
+
98
+ Option bonus (si utile):
99
+
100
+ - `Complaint_Ops_Queue` (par site) = tri par criticité pondérée trafic si dispo.
101
+
102
+ Implémentation (point d’intégration):
103
+
104
+ - Étendre `process_kpi/kpi_health_check/export.py`:
105
+ - soit en ajoutant de nouveaux paramètres optionnels,
106
+ - soit en ajoutant des dfs supplémentaires en fin de liste (compatibilité).
107
+ - Dans `kpi_health_check_panel.py`, construire les df “complaint only” à partir de `current_multirat_df` / `current_top_anomalies_df` ou des raw (selon besoin) et les fournir à l’export.
108
+
109
+ Critères d’acceptation:
110
+
111
+ - L’export contient les 2 feuilles complaint.
112
+ - Les feuilles complaint restent vides si aucune liste plaintes n’est chargée et aucun fichier `data/complaint_sites.*` n’est trouvé.
113
+ - Les noms d’onglets restent < 31 caractères et sans caractères invalides (contrainte Excel).
114
+
115
+ ---
116
+
117
+ ### Phase 2 — Ops Queue + Alert Pack (priorité haute)
118
+
119
+ #### 2.3 “Ops Queue” (table unique priorisée)
120
+
121
+ But: une table de travail qui regroupe le besoin exploitation:
122
+
123
+ - 1 ligne par site
124
+ - priorité = criticité (pondérée trafic si dispo)
125
+ - infos clés: `impacted_rats`, `persistent_kpis_total`, `degraded_kpis_total`, `resolved_kpis_total`, `is_complaint_site`, trafic
126
+
127
+ Implémentation:
128
+
129
+ - Construire `ops_queue_df` à partir de `current_multirat_raw` (qui contient déjà scores + flags).
130
+ - Ajouter un onglet UI “Ops Queue” + une feuille Excel.
131
+
132
+ #### 2.4 “Alert Pack” export court
133
+
134
+ But: un export “prêt à envoyer” (résumé + ops queue + top anomalies) sans l’exhaustivité.
135
+
136
+ - Nouveau bouton export, ou une option dans l’export existant.
137
+
138
+ ---
139
+
140
+ ### Phase 3 — Snapshot + Delta (priorité haute)
141
+
142
+ #### 2.5 Snapshot de run
143
+
144
+ But: figer un run (résultats + paramètres + rules) pour audit et comparaison.
145
+
146
+ Format recommandé:
147
+
148
+ - `json` (simple) ou `parquet` (plus robuste pour gros volumes). Pour MVP: JSON.
149
+
150
+ Contenu snapshot (proposition):
151
+
152
+ - `snapshot_version`: int
153
+ - `created_at`: ISO datetime
154
+ - `profile_config`: dict (baseline/recent/thr/min streak + filtres)
155
+ - `rules_df`: list[dict] (records)
156
+ - `multirat_df`: list[dict]
157
+ - `top_anomalies_df`: list[dict]
158
+
159
+ UI:
160
+
161
+ - `FileDownload` “Save snapshot”
162
+ - `FileInput` “Load snapshot”
163
+
164
+ #### 2.6 Delta entre runs
165
+
166
+ But: sortir les variations entre snapshot chargé et run courant:
167
+
168
+ - `New degraded`
169
+ - `Still degraded`
170
+ - `Resolved`
171
+ - `Severity up / down`
172
+
173
+ Sorties:
174
+
175
+ - onglet UI “Delta”
176
+ - feuille Excel “Delta”
177
+
178
+ ---
179
+
180
+ ### Phase 4 — Visualisation (Map + Corrélation) (priorité moyenne)
181
+
182
+ #### 2.7 Map des sites dégradés
183
+
184
+ But: voir des clusters (zone / ville) et naviguer vers le drill-down.
185
+
186
+ Pré-requis:
187
+
188
+ - `Latitude` / `Longitude` disponibles (normalisation ou physical db).
189
+
190
+ Affichage:
191
+
192
+ - Plotly `scatter_mapbox` (style `open-street-map`) ou `scatter_geo`
193
+ - Couleur = status (ou degraded/persistent)
194
+ - Taille = criticité (weighted si dispo)
195
+
196
+ Interaction:
197
+
198
+ - click point => sélection site dans drill-down
199
+
200
+ #### 2.8 KPI Correlation Explorer
201
+
202
+ But: RCA rapide sur un site/RAT.
203
+
204
+ - Matrice corrélation des KPI sélectionnés (Pearson/Spearman)
205
+ - fenêtre: `recent` / `baseline` / `full filtered range`
206
+ - sortie: heatmap Plotly (`px.imshow`)
207
+
208
+ ---
209
+
210
+ ## 3) RCA Hints (bonus mais très utile)
211
+
212
+ Objectif: rendre `Top_Anomalies` plus actionnable.
213
+
214
+ Ajouts colonnes:
215
+
216
+ - `delta_pct`
217
+ - `sla_breached`
218
+ - `reason` (texte)
219
+ - `data_quality_flag`
220
+
221
+ Ces colonnes peuvent être calculées:
222
+
223
+ - lors de la génération de `Top_Anomalies` (dans `multi_rat.py`),
224
+ - ou côté Panel lors du refresh (plus rapide à itérer).
225
+
226
+ ---
227
+
228
+ ## 4) Découpage technique (recommandé)
229
+
230
+ Pour éviter d’alourdir `kpi_health_check_panel.py`:
231
+
232
+ - `process_kpi/kpi_health_check/snapshot.py`
233
+ - save/load snapshot + validation version
234
+ - compute delta
235
+
236
+ - `process_kpi/kpi_health_check/ops_queue.py`
237
+ - build ops queue df
238
+
239
+ - `panel_app/kpi_health_check_maps.py`
240
+ - build map figure
241
+
242
+ - `process_kpi/kpi_health_check/correlation.py`
243
+ - build correlation matrix
244
+
245
+ ---
246
+
247
+ ## 4.1) Qualité des données & garde-fous (à intégrer dès Sprint 1)
248
+
249
+ - **Validation d’inputs**:
250
+ - dataset vide / pas de `date_only` / pas de `site_code`
251
+ - aucun point dans la `analysis_range`
252
+ - **Validation complaint list**:
253
+ - parsing robuste (csv/txt/xlsx déjà prévu)
254
+ - normalisation des codes site (cast int + extraction regex si besoin)
255
+ - **Fail-safe**: si `is_complaint_site` n’existe pas, ne pas crasher (considérer `False`).
256
+
257
+ ## 4.2) Performance / mémoire (à surveiller)
258
+
259
+ - Limiter le volume affiché dans les tables (ex: top N) quand nécessaire.
260
+ - Éviter les copies inutiles de DataFrames lors des refresh.
261
+ - Garder les calculs lourds dans `process_kpi/*` et l’UI comme orchestration.
262
+
263
+ ## 4.3) Tests rapides (smoke tests) / DoD
264
+
265
+ Minimum avant de considérer une phase “done”:
266
+
267
+ - Charger un petit sample 2G/3G/LTE et exécuter `Load` + `Run` sans erreur.
268
+ - Vérifier:
269
+ - export Excel principal
270
+ - export complaint
271
+ - double-click tables => drill-down
272
+ - aucun crash si complaint list absente
273
+
274
+ ---
275
+
276
+ ## 5) Critères de réussite globaux
277
+
278
+ - **Exploitation**: obtenir une liste priorisée + top anomalies complaint en < 1 minute.
279
+ - **Partage**: export Excel avec onglets complaint + delta.
280
+ - **Visualisation**: map cliquable et corrélation sur drill-down.
281
+
282
+ ---
283
+
284
+ ## 6) Plan de livraison (sprints)
285
+
286
+ - Sprint 1: Complaint UI tab + Export complaint sheets
287
+ - Sprint 2: Ops Queue + Alert Pack
288
+ - Sprint 3: Snapshot + Delta
289
+ - Sprint 4: Map + Correlation explorer
290
+ - Sprint 5 (option): RCA hints (reason/tags)
291
+
292
+ ---
293
+
294
+ ## 7) Risques & mitigations
295
+
296
+ - **Volumes importants** (beaucoup de sites/KPI/jours):
297
+ - mitigation: top-N dans certaines vues + pagination Tabulator + éviter les figures avec trop de traces.
298
+ - **Coordonnées manquantes** (pas de Lat/Lon):
299
+ - mitigation: la map doit être optionnelle et afficher un message clair si données insuffisantes.
300
+ - **Excel / automatisation utilisateur** (noms d’onglets attendus):
301
+ - mitigation: ajouter les nouveaux onglets sans renommer les existants.
documentations/kpi_health_check_map_v2_plan.md ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # KPI Health Check – Map v2 (Mode exploitation + recherche)
2
+
3
+ ## Objectif
4
+
5
+ Améliorer l’onglet **Map** pour l’exploitation quotidienne (≈ 0–3000 sites) avec:
6
+
7
+ - Vue géographique lisible immédiatement (zoom/centrage automatique)
8
+ - Encodage visuel orienté actions (status + criticité)
9
+ - Recherche rapide (site_code / City) + navigation vers le drill-down
10
+ - Performance stable (pas de lag, pas de sur-affichage de labels)
11
+
12
+ ## Non-objectifs
13
+
14
+ - RCA hints / tags automatiques (Sprint 5)
15
+ - Clustering avancé “maison” (geohash/grid) si non indispensable
16
+ - Historique temporel sur la map
17
+
18
+ ## UX / Fonctionnel
19
+
20
+ ### A. Encodage visuel
21
+
22
+ - **Taille**: criticité (déjà en place)
23
+ - **Couleur**: status dominant du site (ex: `PERSISTENT_DEGRADED`, `DEGRADED`, `RESOLVED`, `NO_DATA`)
24
+ - **Label**: `site_code` (déjà en place) limité à un Top-N configurable
25
+
26
+ ### B. Fit bounds (centrage auto)
27
+
28
+ - Bouton (ou comportement automatique) “Fit to points”
29
+ - À chaque refresh map, centrer/zoomer sur l’ensemble des points affichés (après filtres)
30
+
31
+ ### C. Filtres Map (mode exploitation)
32
+
33
+ Widgets simples dans l’onglet Map:
34
+ - **Top N sites** (par score) + option “All”
35
+ - **Only complaint sites** (reprend le bool déjà existant dans le sidebar)
36
+ - **RAT impacted** (2G/3G/LTE/Any) basé sur `impacted_rats`
37
+ - Option: “Only persistent” (status)
38
+
39
+ ### D. Recherche (rapide)
40
+
41
+ - Champ `Search` (texte):
42
+ - accepte `site_code` (entier) ou `City` (substring)
43
+ - résultat:
44
+ - si `site_code` trouvé: centre la map sur le site + sélectionne le site (drill-down)
45
+ - si `City`: filtre/centre sur les sites de la ville + propose une petite liste (Top 20) cliquable
46
+
47
+ ### E. Interaction
48
+
49
+ - Click point => drill-down (déjà en place)
50
+ - Option: bouton “Open Drill-down” à côté des infos (si on ajoute un mini panneau résumé)
51
+
52
+ ## Données / Hypothèses
53
+
54
+ - Les coords sont présentes via `Latitude/Longitude` (venant du `physical_db`)
55
+ - `current_multirat_raw` contient:
56
+ - `site_code`
57
+ - scores (`criticality_score_weighted` ou `criticality_score`)
58
+ - `impacted_rats`
59
+ - compteurs persistent/degraded/resolved
60
+ - Les status par RAT existent dans `current_status_df` (par `site_code`, `RAT`, `status`)
61
+
62
+ ## Plan d’implémentation (Map v2)
63
+
64
+ ### 1) Calcul du status dominant
65
+
66
+ - À partir de `current_status_df`, agréger par `site_code`:
67
+ - règle: `PERSISTENT_DEGRADED` > `DEGRADED` > `RESOLVED` > `OK` > `NO_DATA`
68
+ - produire une colonne `dominant_status`
69
+ - Merge dans le DF map
70
+
71
+ ### 2) Color mapping
72
+
73
+ - Définir une palette stable:
74
+ - `PERSISTENT_DEGRADED` -> rouge foncé
75
+ - `DEGRADED` -> rouge/orange
76
+ - `RESOLVED` -> vert
77
+ - `OK` -> bleu
78
+ - `NO_DATA` -> gris
79
+ - Appliquer via `px.scatter_mapbox(..., color='dominant_status')` + `category_orders`
80
+
81
+ ### 3) Fit bounds
82
+
83
+ - Calculer `lat_min/max`, `lon_min/max` sur les points affichés
84
+ - Utiliser `fig.update_layout(mapbox=dict(bounds=...))` ou `center/zoom` estimé
85
+ - Ajouter un bouton “Fit to points” si on veut éviter un recentrage automatique trop agressif
86
+
87
+ ### 4) Recherche
88
+
89
+ - Widget `AutocompleteInput` ou `TextInput` + bouton `Go`
90
+ - Si nombre:
91
+ - set `site_select` + centre map
92
+ - Si texte:
93
+ - filtrer sur `City` et afficher une liste cliquable (Tabulator ou Select)
94
+
95
+ ### 5) Filtres Map
96
+
97
+ - Implémenter filtres (TopN / complaint / RAT impacted / status) avant rendu
98
+ - Ajouter widgets correspondants dans l’onglet Map
99
+
100
+ ### 6) Tests / Critères de réussite
101
+
102
+ - 3000 sites: refresh map < 2s (hors 1er chargement)
103
+ - Search par `site_code`: centre + drill-down correct
104
+ - Search par `City`: restreint l’affichage et fit bounds
105
+ - Les labels restent limités (Top-N)
106
+
107
+ ## Risques / Points d’attention
108
+
109
+ - Trop de texte (labels) => perf (mitigation: Top-N déjà fait)
110
+ - Fit bounds automatique peut “bouger” la map trop souvent (mitigation: bouton / toggle)
111
+ - `dominant_status` doit être robuste même si `current_status_df` vide
112
+
113
+ ## Estimation
114
+
115
+ - Status dominant + colors: 45–90 min
116
+ - Fit bounds: 20–40 min
117
+ - Recherche: 1–2 h
118
+ - Filtres map: 1–2 h
119
+
120
+ Total: ~3–6 h selon niveau de polish.
hf_spaces/kpi_analysis/Dockerfile ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ RUN useradd -m -u 1000 user
4
+ WORKDIR /app
5
+
6
+ COPY --chown=user:user requirements.txt /app/requirements.txt
7
+ RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
8
+
9
+ COPY --chown=user:user . /app
10
+
11
+ USER user
12
+ EXPOSE 7860
13
+
14
+ CMD [
15
+ "panel",
16
+ "serve",
17
+ "panel_app/panel_portal.py",
18
+ "--address",
19
+ "0.0.0.0",
20
+ "--port",
21
+ "7860",
22
+ "--allow-websocket-origin",
23
+ "*",
24
+ "--num-procs",
25
+ "1",
26
+ "--log-level",
27
+ "info"
28
+ ]
hf_spaces/kpi_analysis/README.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: KPI Analysis (Panel)
3
+ emoji: "📊"
4
+ colorFrom: blue
5
+ colorTo: red
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
+ This Space runs the Panel portal located at `panel_app/panel_portal.py`.
hf_spaces/kpi_analysis/requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ panel>=1.4
2
+ bokeh>=3.4
3
+ pandas>=2.0
4
+ numpy>=1.23
5
+ plotly>=5.0
6
+ xlsxwriter>=3.0