Les boards montrent l'état ; cette page montre la santé : quelle colonne accumule (temps médian passé dans chaque colonne, d'après le journal) et quelles cartes sont devenues des zombies (aucune activité depuis le seuil configuré).
{{ health.column_labels[row.column] }}{% if health.slowest and row.column == health.slowest.column %} 🐌{% endif %}
+
{{ row.count }}
+
{{ row.median_days }} j
+
{{ row.avg_days }} j
+
+ {% endfor %}
+
+
+ {% if health.slowest %}
+
🐌 Goulot : {{ health.column_labels[health.slowest.column] }} — c'est là que les cartes dorment le plus longtemps (médiane {{ health.slowest.median_days }} j).
+ {% endif %}
+ {% else %}
+
Pas encore de séjours mesurables dans le journal de ce projet — il faut des déplacements journalisés pour calculer les temps de colonne.
+ {% endif %}
+
+
+
+
🧟 Cartes zombies — aucune activité depuis ≥ {{ health.zombie_days }} jours
« Fermer » déplace la carte en Terminé (l'issue est fermée dans Gitea par la synchro habituelle). « Toujours pertinent ? » poste un commentaire du même texte sur l'issue.
+ {% else %}
+
Aucune carte zombie. Le flux est propre. ✨
+ {% endif %}
+
+ {% endif %}
+
+
+ {% include "_palette.html" %}
+
+
+
+
diff --git a/app/templates/my.html b/app/templates/my.html
index 346534c..d035dac 100644
--- a/app/templates/my.html
+++ b/app/templates/my.html
@@ -24,6 +24,7 @@
🧠 Digest🔮 Prévisions⚙️ Règles
+ 🩺 Santé🖥️ Wallboard
diff --git a/app/templates/search.html b/app/templates/search.html
index 3796f4a..0dca2b3 100644
--- a/app/templates/search.html
+++ b/app/templates/search.html
@@ -24,6 +24,7 @@
🧠 Digest🔮 Prévisions⚙️ Règles
+ 🩺 Santé🖥️ Wallboard
diff --git a/app/templates/sprint.html b/app/templates/sprint.html
index 87d38bd..a3088b7 100644
--- a/app/templates/sprint.html
+++ b/app/templates/sprint.html
@@ -17,6 +17,7 @@
🌅 Aujourd'hui🔮 Prévisions⚙️ Règles
+ 🩺 Santé
diff --git a/app/templates/today.html b/app/templates/today.html
index c304d01..addfcfc 100644
--- a/app/templates/today.html
+++ b/app/templates/today.html
@@ -23,6 +23,7 @@
🧠 Digest🔮 Prévisions⚙️ Règles
+ 🩺 Santé🖥️ Wallboard
diff --git a/app/templates/triage.html b/app/templates/triage.html
index 8182e32..c93977a 100644
--- a/app/templates/triage.html
+++ b/app/templates/triage.html
@@ -23,6 +23,7 @@
🧠 Digest🔮 Prévisions⚙️ Règles
+ 🩺 Santé🖥️ Wallboard
diff --git a/static/js/health.js b/static/js/health.js
new file mode 100644
index 0000000..90820c0
--- /dev/null
+++ b/static/js/health.js
@@ -0,0 +1,45 @@
+/**
+ * Kanbante — Flow health (issue #9): quick actions on zombie cards.
+ * Close/backlog reuse /api/move; the nudge reuses the comments API.
+ */
+(function () {
+ var csrf = (document.querySelector('meta[name="csrf-token"]') || {}).content || '';
+
+ function post(url, fields) {
+ var data = new FormData();
+ Object.keys(fields).forEach(function (k) { data.append(k, fields[k]); });
+ data.append('csrf_token', csrf);
+ return fetch(url, { method: 'POST', body: data }).then(function (r) {
+ return r.json().catch(function () { return {}; }).then(function (body) {
+ if (!r.ok || body.ok === false) throw new Error(body.error || ('HTTP ' + r.status));
+ return body;
+ });
+ });
+ }
+
+ document.addEventListener('click', function (e) {
+ var btn = e.target.closest('[data-zombie]');
+ if (!btn) return;
+ var repo = btn.getAttribute('data-repo');
+ var number = btn.getAttribute('data-number');
+ var column = btn.getAttribute('data-column');
+ var action = btn.getAttribute('data-zombie');
+ var parts = repo.split('/');
+ btn.disabled = true;
+ var done = function () { location.reload(); };
+ var fail = function (err) { btn.disabled = false; alert(err.message); };
+ if (action === 'comment') {
+ post('/api/issues/' + parts[0] + '/' + parts[1] + '/' + number + '/comments', {
+ body: '🧟 Cette carte est inactive depuis un moment — toujours pertinent ?'
+ }).then(done).catch(fail);
+ } else {
+ post('/api/move', {
+ repo_full_name: repo,
+ issue_number: number,
+ from_column: column,
+ to_column: action === 'close' ? 'done' : 'backlog',
+ to_order: number
+ }).then(done).catch(fail);
+ }
+ });
+})();
diff --git a/static/js/palette.js b/static/js/palette.js
index 8370613..107f2fb 100644
--- a/static/js/palette.js
+++ b/static/js/palette.js
@@ -17,6 +17,7 @@
{ icon: '🔮', label: 'Prévisions — on finit quand ?', href: '/forecast' },
{ icon: '🗣️', label: 'Standup automatique — hier, aujourd\'hui, blocages', href: '/standup' },
{ icon: '⚙️', label: 'Règles d\'automatisation', href: '/rules' },
+ { icon: '🩺', label: 'Santé du flux — goulots et zombies', href: '/health' },
{ icon: '👤', label: 'Mes issues', href: '/my' },
{ icon: '📰', label: 'Activité — journal des événements', href: '/activity' },
{ icon: '📊', label: 'Briefing quotidien', href: '/briefing' },