9 Commits
Author SHA1 Message Date
Spark 851a7b17d2 7.80.0 — Émission d'événements vers le journal du service d'agents (Lot 2)
FlowDeck CI / lint (push) Failing after 1m29s
FlowDeck CI / test (push) Failing after 29m9s
FlowDeck CI / docker (push) Skipped
2026-10-22 20:25:36 +00:00
Spark f6782ee5b3 7.77.0 — corbeille réparée (FK favorites/recents) + MCP workspaces
FlowDeck CI / lint (push) Failing after 1m28s
FlowDeck CI / docker (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 2h18m54s
- detach_page_references : nettoyage des références NO ACTION avant
  toute suppression définitive (unitaire, Empty Trash, purge 30 j)
- MCP : list_workspaces / get_workspace ; descriptions collections
  clarifiées (bases de données, pas des workspaces)
- 96 tests verts sur le périmètre (MCP, trash, cohérence)
2026-10-22 09:03:43 -04:00
Spark d8548eede9 feat: Fusion bloc 1 — barre d'apps commune (ACC-1.1, #17) et références croisées external_ref (ACC-1.3, #18)
FlowDeck CI / lint (push) Failing after 2m33s
FlowDeck CI / test (push) Failing after 30m3s
FlowDeck CI / docker (push) Skipped
2026-10-20 23:17:18 -04:00
bruno d95178156f feat: sidebar Repository identique au Workspace-local, pages forge unifiees, GC miroirs vides
FlowDeck CI / lint (push) Successful in 1m37s
FlowDeck CI / test (push) Successful in 25m11s
FlowDeck CI / docker (push) Successful in 1m32s
2026-10-09 22:33:34 -04:00
bruno 0218d8f5e5 fix: /local-workspace — chemin du header + clic sur un dossier du sidebar (v7.69.9)
FlowDeck CI / lint (push) Successful in 1m37s
FlowDeck CI / test (push) Failing after 24m19s
FlowDeck CI / docker (push) Skipped
Corrige deux régressions de /local-workspace :

- le chemin du header restait bloqué sur « Home / <workspace> » quel que
  soit le dossier affiché : la route rend désormais breadcrumb_items
  (Home / <workspace> / <dossier> / <sous-dossier>, niveaux cliquables,
  collapse « … » au-delà de 4) et la navigation sans rechargement recalcule
  le chemin via l'event flowdeck:breadcrumb-changed ;
- le clic sur un dossier du sidebar affichait TOUS les composants à la
  fois : Alpine.data('wsInitData') retournait le même objet singleton, le
  2e montage (navigation partielle) levait « Cannot redefine property:
  \ » et initTree abandonnait, laissant tout le contenu au state
  brut. La factory retourne désormais une enveloppe fraîche par montage
  qui délègue à l'état réactif partagé. #lw-config est aussi relu à chaque
  exécution (le 2e montage gardait le folder_id du 1er chargement).

Inclus également le travail en cours de l'arbre : Library (colonnes Last
visited/Source, ordre d'en-tête, favoris à icônes Workspace), Meeting
Notes (bloc, CSS, routes, docs), coloration de code hljs, badges
favori/publié dans l'arbre local-workspace, docs (DATA_MODEL,
architectures) et tests associés.
2026-10-09 16:58:04 -04:00
bruno a68e8848ea feat: menu + — Design System – Canevas — phase 3/8 (v7.53.0)
FlowDeck CI / lint (push) Successful in 2m12s
FlowDeck CI / test (push) Failing after 14m56s
FlowDeck CI / docker (push) Skipped
- Section « Design System – Canevas » : liste des canevas (intégrés +
  personnels, GET /board/api/page-templates) puis page de détail avec
  « Créer une page à partir du canevas », « Insérer dans le document ouvert »
  (désactivé sans document ouvert) et « Enregistrer le document ouvert comme
  canevas ».
- GET /board/api/page-templates/{id}/blocks (nouvelle route) : blocs d'un
  canevas — intégré via template_id=0&key=, sinon id ; 404 clé/id inconnu.
  Insertion côté front via ensureBlockIds() global + concat dans E.blocks
  + autoSave/render.
- Canevas « Design System » ajouté aux builtins (callout tokens, TOC, toggles
  composants, grille, checklist revue UI, citation).
- Fix : le front du panneau appelait /api/page-templates (404 silencieux) —
  le router est sous prefix=/board → /board/api/page-templates.
- Piège : pour /use la clé builtin se passe DANS LE BODY (body.key), pas en
  query string — test garde-fou ajouté.
- Tests : tests/test_v753_canvases.py (5) + test_v751 adapté. Suite complète
  1285 verts (-n auto), ruff 0, eslint 0 problème. OpenAPI 516 chemins.
2026-10-06 21:59:34 -04:00
bruno 1d1cdbd618 fix: side peek des bases repasse en vanilla JS + largeur 1100px standard (v7.49.0)
FlowDeck CI / test (push) Failing after 3h13m58s
FlowDeck CI / lint (push) Successful in 2m12s
FlowDeck CI / docker (push) Skipped
- Panneau peek: les bindings Alpine (x-data absent du conteneur) rendaient
  loovverture et le redimensionnement inoperants -> cblage direct sur le document.
- Helper unique window.fdWirePeekResize (app.js): pointer capture, 300px-90vw,
  clic=fermer, largeur persiste fd_peek_width partagee entre les 4 peeks.
- database-table-container margin:0 (tableau colle a gauche, marge Library).
- .lib-container remonte dans app.css (trash etait pleine largeur), .db-index 1100px.
- ObsiGate verifie sans code: creation .xlsx OK (openpyxl, #186).
2026-10-05 22:47:36 -04:00
bruno 6582df3bcb feat: poubelle flexible (sélection groupée, purge, tri/filtres, dates) + 4 bugs (v7.45.5)
FlowDeck CI / docker (push) Successful in 1m52s
FlowDeck CI / lint (push) Successful in 2m1s
FlowDeck CI / test (push) Successful in 15m21s
Page /trash alignée sur ce que fait ce type de section :
- sélection multiple (Select all porté au filtre courant) + barre d'actions
  groupées Restore / Delete / Clear ;
- Empty Trash via POST /board/api/trash/empty (purge en masse, 1 requête) ;
- tri Recently deleted / Oldest first / Name et filtre emplacement RÉELS —
  remplacent les deux boutons décoratifs « Last edited by ▾ » et « In ▾ » qui
  ne faisaient rien ;
- date de suppression + jours restants par élément (rétention 30 j alignée sur
  app/services/trash.py, horodatages UTC/ISO gérés) ;
- compteur de résultats, états vides distincts (vide vs filtre sans résultat +
  Clear filters), toasts sur chaque action.

Bugs trouvés en route et corrigés :
1. Restore/Delete de la page ne marchaient JAMAIS : getCsrf() renvoie la chaîne
   du jeton mais le code faisait csrf?.[1] → 2e caractère → 403 CSRF silencieux
   avalé par if (r.ok).
2. « Move to Trash » de l'éditeur = 404 permanent : route appelée
   /board/api/pages/{id}/trash (inexistante) alors que la route réelle est
   /api/pages/{id}/trash, et le .then() naviguait quand même → la page partait
   à l'accueil SANS être mise à la poubelle. URL corrigée + r.ok vérifié.
3. Page restaurée invisible en Library/Recents/Private : la suppression éditeur
   réécrivait parent_section='Trash' et la restauration ne le remettait pas,
   alors que tous les listings filtrent parent_section != 'Trash'. Écriture
   retirée (deleted_at = source de vérité unique) + réparation idempotente au
   boot dans db.init_db + requête sidebar /trash alignée sur deleted_at.
4. Routes trash sans aucune authentification (le CSRF ne protège pas : cookie
   lisible + en-tête forgé) : 401 ajouté sur list/restore/delete/empty et sur
   POST /api/pages/{id}/trash — vérifié anonyme → 401.

Gates : tests/test_trash_api.py (5) · e2e/trash_ui.spec.js (1, avec garde « on
ne vide jamais la poubelle d'autrui ») · pytest 1099 passed · ruff OK ·
e2e probe_nav_perf + partial_nav + editor_mount + logout_dnd + smoke = 10 passed ·
OpenAPI 510 chemins / 7.45.5.
2026-10-03 01:35:26 -04:00
bruno 0bc74ad728 refactor: A28 TERMINÉ — board.py (2 101 L) → package 14 fichiers (v7.32.0)
FlowDeck CI / lint (push) Successful in 2m1s
FlowDeck CI / test (push) Successful in 15m17s
FlowDeck CI / docker (push) Canceled after 0s
Lot 4/4 de l'A28 (god files) : l'ancien app/routers/board.py (2 101
lignes, 53 routes) devient le package `app/routers/board/` :

- 12 modules de routes : pages 271 L (7 r.), page_api 229 (5),
  board_views 223 (8), page_ops 176 (3), sharing 175 (10), synced 144 (8),
  page_media 122 (4), import_ 85 (2), wiki 76 (2), library 66 (1),
  embed 64 (2), sync 51 (1)
- _common.py (878 L) : 23 helpers dont 4 async + les 4 constantes
  (STATUS_COLORS, STATUS_LABELS, AI_KEYWORD_COLORS, _REPO_REF_RE)
- __init__.py : __all__ complet — importateurs inchangés (api.py ×4
  top-level, webhooks top-level, dashboard ×5 lazy, tests ×4)

Preuve contractuelle : docs/openapi-v2.json régénéré = IDENTIQUE
byte-à-byte (509 chemins, ordre préservé).

Pièges rattrapés :
- constantes d'état oubliées dans _common à la 1ʳᵉ passe (F821 +
  ImportError au chargement) → ré-insérées avec les valeurs exactes
- docstring du header copié → F404 → slice [1:21]
- helpers `async def` non détectés par `def ` seul

A28 TERMINÉ en 4 lots : api_v2 (7.29.0), dashboard (7.30.0),
collections (7.31.0), board (7.32.0) — 0 changement d'URL sur les 4.

suite **1091/1091** · ruff OK · OpenAPI 509 identique · docs à jour
2026-10-02 08:27:57 -04:00