# Changelog ## 0.5.2 — 2026-10-11 ### Correctif - **L'indice « Glissez une carte ici » restait affiché après un dépôt dans une colonne vide** : il est rendu par le serveur pour les colonnes vides au chargement, et le glisser-déposer ne le retirait jamais du DOM. `refreshEmptyHints()` recalcule désormais l'indice d'après le contenu réel de chaque colonne après tout déplacement (et après un retour arrière en cas d'échec) : retiré dès qu'une carte est présente, rétabli quand la dernière carte part. SortableJS est en outre restreint aux seules cartes (`draggable: '.kanban-card'`), l'indice n'est plus un élément déplaçable parasite. ## 0.5.1 — 2026-10-11 ### Correctif critique - **Les boards étaient vides contre un vrai Gitea** : l'API Gitea (1.27.3 vérifié) renvoie la clé `"pull_request": null` sur les issues ordinaires ; le filtre `_is_issue` testait la *présence* de la clé (`"pull_request" not in item`), donc chaque vraie issue était classée « pull request » et écartée. Board, vue Focus et briefing ne montraient aucune carte (le dashboard, qui lit les compteurs des dépôts, semblait normal). Corrigé : le filtre teste la *valeur* (`not item.get("pull_request")`). - Le faux Gitea des tests omettait la clé, ce qui masquait le bug : il reproduit désormais fidèlement le payload réel (clé toujours présente, `null` sur les issues), plus 4 tests de régression dédiés (88 tests au total). Smoke test réel : le board `bruno/flowdeck` passe de 0 à 6 cartes, dont l'issue de test « test d'ajout ! ». ## 0.5.0 — 2026-10-11 « Palier 3 » (points 7 à 9) + board enrichi. ### Ajouts - **Recherche globale** (`/search`) : recherche d'issues dans tous les projets via l'API Gitea, résultats groupés par projet avec la colonne Kanban de chaque issue. **Mes issues** (`/my`) : les issues ouvertes assignées à l'utilisateur du jeton, tous projets confondus. - **Briefing quotidien** : page `/briefing` (encours, activité 24 h, cartes vieillissantes, milestones proches), `GET /api/briefing`, et envoi **ntfy** manuel (`POST /api/briefing/send`) ou automatique à `KANBANTE_BRIEFING_TIME` via un planificateur interne (mémoire d'envoi en base, aucun doublon après redémarrage). - **Serveur MCP** (lecture seule) : JSON-RPC 2.0 sur `POST /mcp` (initialize, tools/list, tools/call, ping) avec 7 outils — `list_projects`, `get_board`, `get_issue`, `get_focus`, `search_issues`, `get_activity`, `get_metrics`. Aucune écriture, conformément au principe « lectures d'abord ». `GET /mcp` décrit le serveur. - **Gestion des étiquettes sur le board** : modale de gestion (lister / créer avec palette de couleurs / supprimer les étiquettes du dépôt dans Gitea) et, dans le panneau détail, ajout / retrait d'étiquettes sur l'issue en un clic, avec mise à jour immédiate de la carte. API : `GET|POST /api/repos/{o}/{r}/labels`, `DELETE /api/repos/{o}/{r}/labels/{id}`, `POST /api/issues/{o}/{r}/{n}/labels`. ### Améliorations - **Panneau Notes du projet** : repliable (bouton ⤢, état mémorisé par projet), **largeur ajustable** par glisser (mémorisée), et **sauvegarde automatique** après 1,2 s sans frappe avec indicateur d'état (le bouton manuel reste). Le formulaire quitte HTMX pour le même `board.js` que le reste du board. - Navigation unifiée enrichie sur toutes les pages : Mes issues, Briefing, Recherche. ### Tests - 19 tests ajoutés (84 au total) : recherche et mes issues, briefing (page, API, envoi ntfy, format), protocole MCP, API étiquettes, marqueurs du board. Un doublon de déclaration JS attrapé par `node --check` avant livraison. ## 0.4.0 — 2026-10-11 « Palier 2 » : temps réel et visible dans Gitea — plus une refonte complète de l'interface. ### Ajouts - **Webhooks Gitea + rafraîchissement en direct** : `POST /webhooks/gitea` (signature HMAC-SHA256 vérifiée quand `KANBANTE_WEBHOOK_SECRET` est défini) invalide le cache de lecture, applique les fermetures / réouvertures faites dans Gitea (idempotent : l'écho de nos propres appels ne double jamais le journal) et pousse un événement SSE sur `GET /api/stream`. Le navigateur se recharge en douceur quand c'est sûr (onglet visible, pas de panneau ouvert, pas de saisie en cours, pas de drag) ; sinon une pastille « Nouvelle activité » propose l'actualisation. - **Synchro par étiquettes** : les colonnes intermédiaires sont reflétées dans Gitea par des étiquettes `kanban:todo`, `kanban:in_progress`, `kanban:review` (créées au besoin, ajout / retrait granulaires — les étiquettes de l'utilisateur ne sont jamais touchées ; backlog et done = aucune étiquette). Désactivable : `KANBANTE_SYNC_LABELS=0`. - **Boards par milestone** : `GET /board/{owner}/{repo}?milestone=` filtre le board, avec bandeau d'échéance et progression (issues fermées du milestone / total). Sélecteur de milestones au-dessus du board. ### Interface (refonte complète) - Nouveau design system : en-tête vitré sticky avec navigation en pastilles (état actif), halos d'ambiance, cartes projets qui se soulèvent au survol, barres de progression, coins plus doux, anneau de focus visible partout, `prefers-reduced-motion` respecté. - Dashboard : hero avec tuiles de synthèse (projets actifs, issues fermées et déplacements sur 30 jours, temps de cycle moyen — depuis le journal), états vides guidés pour chaque onglet, raccourci `/` pour la recherche (aussi sur le filtre du board). - Board : pastille « live » en cas d'activité externe, colonnes à défilement indépendant, placeholders de colonnes vides, panneau de notes explicité, drawer animé. - Cohérence : même navigation sur les 5 pages, responsive retravaillé. ### Tests - 13 tests ajoutés (65 au total) : hub SSE et générateur de flux, webhooks (transition, idempotence, signature, JSON invalide), synchro d'étiquettes, boards par milestone, marqueurs de la refonte. ## 0.3.0 — 2026-10-11 « Palier 1 » : voir ce qui se passe sur les boards. ### Ajouts - **Journal d'événements** (`board_events`, append-only) : chaque création, déplacement, fermeture, réouverture et commentaire est horodaté. Il alimente la page **`/activity`** (fil tous projets), `GET /api/events` et `GET /api/metrics` (débit par type et temps de cycle moyen : entrée en « En cours » → fermeture). Les fermetures détectées lors de la réconciliation avec Gitea sont aussi journalisées (source `gitea`). Un reclassement dans la même colonne n'écrit pas d'événement. - **Panneau détail de carte** : un clic sur une carte ouvre un panneau latéral avec le corps de l'issue rendu en markdown (marked + DOMPurify, vendorés), ses commentaires, assignés, milestone et échéance ; on peut **commenter directement dans Gitea** depuis le panneau (`GET /api/issues/{owner}/{repo}/{n}`, `POST .../comments`, 404 propre si l'issue n'existe pas). - **Vieillissement des cartes** : badge « ⏳ N j » dès qu'une carte reste dans sa colonne au-delà de `KANBANTE_AGING_DAYS` (défaut 7, rouge au double). Le temps en colonne vient du journal, avec repli sur `board_state.updated_at` puis sur la date de création de l'issue. - **Limites WIP** : `KANBANTE_WIP_LIMITS="in_progress:5,review:3"` — l'en-tête de colonne affiche `n/limite`, passe en rouge en dépassement et un toast avertit au dépôt. Limites souples : jamais bloquantes. ### Tests - 16 tests ajoutés (52 au total) : journal et métriques, détail et commentaires, vieillissement, WIP. ## 0.2.0 — 2026-10-11 Consolidation complète à partir d'un audit du code 0.1.0 (chaque correctif marqué « confirmé » avait été reproduit par un test avant correction). ### Critiques corrigés - **Perte de données en Docker** : `KANBANTE_DB_PATH` est enfin lue par le code — la base SQLite atterrit dans le volume `/data` comme prévu. - **Authentification** : Basic Auth optionnelle mais recommandée (`KANBANTE_AUTH_USER` / `KANBANTE_AUTH_PASSWORD`, `KANBANTE_REQUIRE_AUTH=1` pour refuser de servir sans), protection CSRF (double-submit) sur tous les POST, avertissement bruyant au démarrage quand l'auth est absente. - **Synchro bidirectionnelle** : déplacer une carte vers « Terminé » ferme l'issue dans Gitea, la ressortir la rouvre (`KANBANTE_SYNC_GITEA=0` pour désactiver). L'état local est réconcilié à chaque chargement de board (fermées → Terminé, supprimées → purgées). ### Importants corrigés - Classification des projets : fenêtre d'activité glissante configurable (`KANBANTE_ACTIVE_WINDOW_DAYS`, défaut 365) et vrai drapeau `archived` de Gitea — fini l'année codée en dur et l'onglet « Archivés » mensonger. - Pagination complète des appels Gitea (le plafond serveur de 50 réponses par page ne tronque plus les dépôts ni les issues, en silence). - `get_board_state` ne plante plus sur une colonne inconnue ; migration automatique des bases 0.1.0 (colonne `position`, `notes.updated_at`, nettoyage des lignes invalides). - Gitea injoignable → page d'erreur 502 propre (JSON pour l'API) au lieu d'un 500 brut ; `/api/readiness` teste réellement SQLite et Gitea, `/api/health` reste un liveness sans dépendance. - Dockerfile : installation après copie du code (le package installé n'est plus vide), utilisateur non-root, `HEALTHCHECK`, `.dockerignore`. ### Ajouts - **Ordre des cartes persisté** dans chaque colonne (aller-retour glisser-déposer → rechargement). - **Création d'issues** depuis le board (`POST /api/issues`). - **Vue Focus** (`/focus`) : tout ce qui est En cours / En révision, tous projets actifs confondus. - Filtres par texte et par étiquette sur le board ; les cartes lient vers l'issue Gitea ; les pull requests ne sont plus affichées comme des issues. - Suite de tests `pytest` (modèles, client Gitea, API, auth/CSRF) et CI Gitea Actions (`.gitea/workflows/ci.yml`). - Fichier `LICENSE` (MIT, annoncé par le README depuis la 0.1.0). ### Détails - Client Gitea entièrement asynchrone (les routes ne bloquent plus la boucle d'événements), cache mémoire court des listes, en-tête `Authorization` seulement si un jeton est configuré, uid résolu via `/user` (plus de `uid=1` ni d'utilisateur codés en dur), `.env` chargé depuis la racine du projet seulement. - Bibliothèques JS (HTMX, Alpine, SortableJS) **vendorées** dans `static/vendor/` : plus aucune dépendance CDN à l'exécution. - Glisser-déposer : en cas d'échec serveur, la carte est replacée et le toast d'erreur est rouge ; les déplacements envoient l'ordre complet des colonnes source et destination. - API : codes HTTP corrects (400 colonne invalide, 403 CSRF, 413 note trop longue — limite configurable), `lifespan` FastAPI à la place de `on_event` déprécié, imports nettoyés. - CSS : fond des badges corrigé (`color-mix()` remplace l'invalide `var(--accent)20`). - Recherche du dashboard : le nom des dépôts passe par un attribut `data-search` échappé, plus aucune interpolation dans du JS. - `docker-compose.yml` : clé `version:` obsolète retirée, variables d'auth exposées, healthcheck. ## 0.1.0 — 2026-07-07 Version initiale : dashboard des projets Gitea, board Kanban 5 colonnes par dépôt (glisser-déposer SortableJS), notes par projet, état local SQLite, thème sombre, Dockerfile + docker-compose.