Files
flowdeck/ROADMAP.md
T

76 KiB
Raw Blame History

Roadmap FlowDeck — Notion Clone

Vision: Copie conforme de l'UI/UX Notion, intégrée à Gitea/GitHub. MVP en production : v4.0.0 — authentification locale/OAuth, pages blocs, sidebar, library, share/publish, intégrations. Branche principale : main (production) · develop (intégration) · feat/* (features).

🏗️ Stratégie de branches

main       ──●────────────●────── production (tags vX.Y.Z)
              \          /
develop       ●──●──●──●────── intégration continue
                  \  \  \
feat/xxx          ●  ●  ●──── feature branches
  • main : code en production, déploiement Docker automatique
  • develop : branche d'intégration, merges des feat/*
  • feat/<nom> : une branche par feature/fix, PR → code review → merge dans develop
  • Tags vX.Y.Z sur main pour chaque release

Workflow :

git checkout -b feat/mon-truc develop
# ... coder, commit, push ...
# Créer une PR feat/mon-truc → develop sur Gitea
# Après review + CI verte → merge
# Pour release: PR develop → main + tag vX.Y.Z

Règles :

  • Ne jamais commiter directement sur main
  • Une branche = une feature / un fix
  • Tests passent avant merge (CI Gitea Actions)
  • Commit + push après chaque modification significative

Completed

v0.2.0 ✅ — Base

Dashboard + Board Kanban + Gitea sync + Notes + Docker

v0.3.0 ✅ — Auth

OAuth2 Gitea, token par utilisateur, CSRF, rate limiting, webhooks

v0.4.0 ✅ — UI Notion

Layout 3 zones (sidebar 240px + topbar 44px), dark mode, CSS 31KB, Alpine.js

v0.5.0 ✅ — Kanban

Colonnes, groupes, cartes enrichies, drag&drop, modale détail, checklists, commentaires

v0.6.0 ✅ — Table View

6 colonnes triables, groupes rétractables

v0.7.0 ✅ — Filtres & Tri

Filtres cumulables AND, status dropdown, sort multi-critères

v0.8.0 ✅ — Vues Spéciales

Status Overview (donut SVG), Team Load (barres), Detailed Board

v0.9.0 ✅ — Backend

Propriétés custom, AI keywords, sync API, 12 tables DB

v1.0.0 ✅ — Production

  • FastAPI lifespan (deprecation fix)
  • 28 tests — 5 vues, filtres, tris, APIs, CSRF, CORS, DB
  • CI/CD Gitea Actions (.gitea/workflows/ci.yml)
  • CHANGELOG.md, ARCHITECTURE.md à jour
  • Version 1.0.0 partout (main.py, api.py, health)
  • Tag git v1.0.0

v1.1.0 ✅ — Pages & Sidebar

  • Pages Markdown avec arbre imbriqué (parent_id, sort_order)
  • Block editor mode (content_format='blocks', JSON storage)
  • Soft delete → Trash → Restore → Permanent delete
  • Drag & drop réorganisation pages
  • Sidebar Notion-style avec sections Recents/Private/Shared
  • "+ New page" footer button
  • Workspace header avec avatar + chevron toggle

v1.2.0 ✅ — Éditeur Notion

  • Slash menu (/) 15 commandes fonctionnelles
  • Navigation clavier (flèches, Enter, Escape)
  • Placeholders Notion-style (Heading 1/2/3/4, Toggle, Quote, Code)
  • Suppression outline blanc sur les blocs
  • Heading 4 support
  • Breadcrumbs contextuels (workspace > projet > page)

v1.3.0 ✅ — Database Concept

  • Tables collections, collection_pages, collection_views
  • Rétrocompatibilité Gitea via GiteaBoardCompat
  • Router /db — API CRUD collections + pages (12 endpoints)
  • 34/34 tests passent

v1.4.0 ✅ — Propriétés Avancées

  • Table collection_properties — 21 types Notion
  • Service property_types.py — validation, formatage, auto-values
  • 38/38 tests passent

v1.5.0 ✅ — Relations & Rollups

  • Type relation — lien bidirectionnel entre collections
  • Type rollup — aggregation via relation (COUNT, SUM, AVG, etc.)
  • Type formula — moteur d'expressions (19 fonctions)
  • Formula engine + Rollup engine
  • 43/43 tests passent

v1.6.0 ✅ — Vues Manquantes

  • Calendar, Gallery, List, Timeline, Table views
  • View tabs navigation
  • 49/49 tests passent

v1.7.0 ✅ — Vues Améliorées

v1.8.0 ✅ — Sub-items & Dépendances

  • View config API, Save view as
  • Sub-items (parent_id auto-référence)
  • Status aggregate, Dependencies (blocking constraint)
  • 56/56 tests passent

v1.9.0 ✅ — My Tasks & Dashboard Unifié

  • Vue /my-tasks — agrège pages assignées à l'utilisateur
  • Groupement par collection, filtres globaux
  • 60/60 tests passent

v2.0.0 ✅ — Éditeur Complet & Multi-Utilisateurs

  • Workspaces, Comments, Page History, Favorites
  • Database Templates, Page Templates, CSV Import/Export
  • Public Sharing
  • 67/67 tests passent

v2.1.0 ✅ — Workspace Local & Arborescence

v2.2.0 ✅ — Tags & Recherche Avancée

v2.3.0 ✅ — Multi-Vues Workspace & Preview Panel

v2.4.0 ✅ — Tags Personnalisés par Utilisateur

v2.5.0 ✅ — Administration Avancée

v2.6.0 ✅ — My Account & Auth Locale

v2.7.0 ✅ — Intégration Gitea Phase 1

v2.7.1 ✅ — Private Pages Gitea

v2.8.0 ✅ — Gitea Phase 2

  • Créer fichiers dans le repo (New file UI + API PUT)
  • Upload fichiers binaires (POST /upload, drag-drop)
  • Syntax highlighting via Prism.js CDN
  • Labels Gitea → tags FlowDeck (POST /sync-labels, 16 labels importés)
  • Historique commits par fichier (GET /commits?path=)

v2.9.0 ✅ — GitHub OAuth Provider

  • GitHubProvider dans app/auth/providers.py
  • GitHubAdapter dans app/services/github_adapter.py
  • Config GitHub dans .env.example

v3.0.0 ✅ — UX Professionnelle

  • Multi-sélection (checkboxes + Shift/Ctrl-click dans le sidebar)
  • Raccourcis clavier (Ctrl+N, F2, Delete, Escape, Ctrl+S)
  • Inline rename (double-clic → champ inline)
  • Loading skeletons (animations pulse dans workspaces + file viewer)
  • Grid/card view (mode grille/vignettes)
  • Table sorting (tri par colonnes)
  • Sélecteur de vue: Tree, List, Details, Title, Content (5 modes)
  • Preview Panel latéral (contenu, métadonnées, tags, actions)
  • Tri par date (Oldest/Newest)

v4.0.0 ✅ — Accounts, Integrations & Sharing (MVP)

  • auth_method sur users (local/gitea/github)
  • Badge OAuth dans sidebar
  • Settings page avec Connect/Disconnect Gitea + GitHub
  • Sidebar rules (Private = distant seulement, Trash local-only)
  • Library page avec tabs + filtres source (All/Local/Gitea/GitHub)
  • Modale Share (2 tabs: Share + Publish)
  • Page publique /p/<slug> (no auth, rendu HTML)
  • Table page_shares, colonnes is_published, is_shared, share_mode
  • Table recents — tracking automatique
  • Édition unifiée local/distant (même UI, bouton Commit pour Gitea)
  • 133 tests passent

🔜 Prochaines versions

v4.0.1 — Onboarding & Polish ✅ (2026-07-18)

Objectif : rendre l'app utilisable dès la première visite, sans friction. COMPLETED.

  • Landing page / pour visiteurs non-auth — template landing.html, design Notion dark
  • Page /auth/register GET — formulaire d'inscription dédié (tab register actif)
  • Redirection / intelligente — non-auth → landing, auth sans Gitea → local workspace, auth+Gitea → dashboard
  • Empty states — déjà présents dans local workspace (« Welcome to your Workspace »)
  • Page 404 stylisée — thème Notion sombre, JSON pour /api/*, HTML pour le reste
  • Unifier les routes API — /api/pages GET/POST → 307 redirect vers /board/api/pages
  • Page Settings — lien déjà présent dans le menu utilisateur (Settings → /accounts/settings)

v4.0.2 — Qualité & Robustesse ✅ (2026-07-18)

Objectif : zéro crash, zéro regression, DX impeccable.

  • Gestion d'erreurs — try/catch dans create_page, message user-friendly (500 JSON)
  • Validation inputs — login/register déjà validés, titre vide → "Untitled"
  • Rate limiting — 100 req/min/IP déjà en place, testé OK
  • Session expiry UX — redirect avec ?expired=1, bannière sur la page login
  • CSRF token refresh — auto-refresh sur 403, endpoint /api/csrf-token
  • Mobile responsive — sidebar slide-in, modales centrées, landing adaptative
  • Tests de non-régression — +10 tests (landing, register, 404, validation, duplicate, expiry)
  • 143 tests passent

v4.1.0 — Database: Data Sources & Linked Databases ✅ (2026-07-21)

Objectif : Collections multi-sources, databases liées (linked). COMPLETED. Doc : NOTION_DATABASE_TASKS_GUIDE.md Phase 1

  • Table collection_data_sources — multi-sources par collection (FK collection_id + source_collection_id, flag is_linked)
  • API sources — GET /db/{id}/sources/api (liste), POST /db/{id}/sources/api (ajouter), DELETE /db/{id}/sources/{sid}/api (retirer)
  • API linked DB — POST /db/{id}/linked/api (crée une collection liée : copie vues + propriétés + data source is_linked=1)
  • Full-page vs Inline — POST /db/{id}/toggle-inline/api (toggle), POST /db/inline/api (créer inline avec parent_page_id)
  • Règle permissions — linked DB hérite du workspace_id de la source → mêmes ACLs
  • Migration — ajout colonnes workspace_id, created_by sur collections
  • 153 tests passent (+10 nouveaux)

v4.2.0 — Database: Templates & Dashboards ✅ (2026-07-21)

Objectif : Templates réutilisables + dashboards combinant vues/widgets. COMPLETED.

  • Table page_templates enrichie — colonnes description, is_recurring, recurrence_rule (daily/weekly/monthly/yearly)
  • Table collection_dashboards — layout widgets (grille configurable : columns, widgets avec view_id, x, y, width, height)
  • API templates CRUD complet — PUT /workspace/collections/{id}/templates/page/{tid} (update), DELETE (delete)
  • API dashboards CRUD — GET/POST/PUT/DELETE /workspace/collections/{id}/dashboards
  • 159 tests passent (+6 nouveaux)

v4.3.0 — Database Views complètes (10 types) ✅ (2026-07-21)

Objectif : Tous les types de vues Notion avec layouts. COMPLETED.

  • Chart — barres, courbes, camemberts, donuts, scatter (Chart.js CDN)
  • Form — formulaire HTML auto-généré depuis les propriétés → POST création page
  • Map — Leaflet/OSM pour propriété Place (lat,lng parsing)
  • Feed — vue chronologique type fil d'actualité (newest first)
  • Timeline/Gantt — barres horizontales avec group_by et plages de dates
  • View tabs — 11 onglets de navigation (table, board, calendar, gallery, list, timeline, gantt, chart, form, map, feed)
  • Layout options — card_size, chart_type, group_by, place_property via config_json
  • 166 tests passent (+7 nouveaux)

v4.4.0 — Tasks, Sub-items & Dependencies ✅ (2026-07-21)

Objectif : Système complet de tâches Notion-style. COMPLETED.

  • Flag is_task sur collections — PUT /db/{id}/toggle-task/api (Turn into Tasks)
  • Table page_dependencies — bloque/bloqué par/related avec auto_shift
  • API dependencies — GET/POST/DELETE /db/{c}/pages/{p}/dependencies/api
  • Auto-shift dates — POST /db/{c}/pages/{p}/auto-shift/api (skip_weekends option)
  • 171 tests passent (+5 nouveaux)

v4.5.0 — Sprints & My Tasks ✅ (2026-07-21)

Objectif : Sprints agiles + vue My Tasks cross-databases. COMPLETED.

  • Tables sprints, sprint_pages — sprints agiles avec velocity_points
  • API sprints — CRUD + assignation/retrait pages
  • Burndown chart — GET /workspace/collections/{id}/sprints/burndown/{sid} (total/completed/remaining/ideal)
  • My Tasks — agrégation cross-databases avec filtre (all/today/overdue/upcoming)
  • 175 tests passent (+4 nouveaux)

v4.6.0 — Content Blocks enrichis ✅ (2026-09-02)

Objectif : parité d'édition avec Notion.

  • Callout blocks — boîtes colorées avec sélecteur d'emoji/icône
  • Table of contents — auto-généré depuis les headings avec ancres
  • Math equations — LaTeX / KaTeX (self-hosted) block
  • Toggle lists — contenu expandable/collapsible avec enfants
  • Multi-colonnes — layout flexible (2, 3 colonnes) + bouton ajouter/retirer colonne

Détails livrés :

  • 5 types de blocs enrichis dans le slash menu (callout, table_of_contents, math, columns, toggle)
  • Rendu des nouveaux blocs dans les pages publiques (/p/<slug>) — TOC ancré, KaTeX, colonnes, toggle <details>
  • Intégration KaTeX 0.16.11 self-hosté (/static/js/katex.min.js, /static/css/katex.min.css, /static/fonts/)
  • Persistance children (colonnes/toggle) via le format de blocs JSON
  • Export Markdown étendu aux nouveaux blocs
  • 183 tests au total (dont 5 nouveaux tests v4.6.0)

v4.7.0 — Export ✅ (2026-09-03)

Objectif : exporter une page (ou un site) depuis l'éditeur.

  • Export Markdown — avec images et sous-pages (récursif)
  • Export PDF — via xhtml2pdf (fidèle, sans CDN/lib système)
  • Export HTML — site statique standalone (document autonome + site .zip)

Détails livrés :

  • Service serveur app/services/export.py : conversion blocs → Markdown / HTML / PDF
  • 4 formats exposés : /api/export/markdown|html|pdf|site/{page_id}
  • Sous-pages incluses récursivement (Markdown et site)
  • UI : menu « More › Export » dans l'éditeur (Markdown, HTML, PDF, Site .zip)
  • PDF généré via xhtml2pdf (pip) — aucun lib système requise
  • 6 nouveaux tests (Markdown, sous-pages, HTML, PDF, Site, 404)

v4.7.1 — Fix UI Export / Share / More ✅ (2026-09-03)

  • Share / More / Activity / Move-to popovers — rendus sous le viewport (absolute + parent scrollable) → repositionnés fixed sous la topbar
  • Sous-menu Export — l'itém Export fermait le menu More ; devient un toggle, formats accessibles
  • Cache CSS — query string app.css bumpé v4.7.1
  • Vérifié Playwright headless + 190/190 tests

v4.7.2 — Fix Export : contenu absent ✅ (2026-09-03)

  • Export MD/HTML/PDF des documents — le service ne lisait que les pages blocks ; les pages file (upload .md/code, contenu sur disque) et markdown sortaient avec le seul titre. Résolution de la vraie source pour les 3 formats + rendu HTML/PDF correct des headings/listes.
  • 5 nouveaux tests → 195/195 ; vérifié sur les vraies données

v4.7.3 — Fix export PDF/HTML : tableaux + émojis ✅ (2026-09-03)

  • Tableaux — parseur GFM (bloc table) + rendu <table> HTML (thead/tbody, alignements, bordures .ftable) dans les exports HTML/PDF ; roundtrip markdown pipe valide.
  • Émojis PDF — passage du moteur à WeasyPrint (émojis couleur via Pango + fonts-noto-color-emoji dans l'image) ; repli automatique xhtml2pdf si libs natives absentes (dev Windows).
  • Dockerfile : libs pango/harfbuzz/gdk-pixbuf + polices ; requirements : + weasyprint==69.0
  • 4 nouveaux tests → 199/199 ; PDF README.md vérifié : tableau structuré + émojis colorés

v4.8.0 — Bloc Tableau simple ✅ (2026-09-03)

  • Bloc table éditable dans l'éditeur — insertion via /table (commandes slash, section BASIC), tableau 3×3 avec en-tête, cellules éditables au clic, auto-sauvegarde.
  • Lignes — bouton + Row sous le tableau (clic = ajouter) ; clic droit sur une cellule de corps → Insérer dessus/dessous, Dupliquer, Effacer, Supprimer la ligne, Supprimer le tableau.
  • Colonnes — poignée (⋮⋮) au-dessus de chaque colonne → Insérer à gauche/droite, Dupliquer, Effacer le contenu, Supprimer la colonne, Supprimer le tableau.
  • Import Markdown (GFM) — md2b transforme les tableaux pipe en bloc table au lieu de les aplatir en paragraphes ; roundtrip Markdown (JS + export) et sortie MD/HTML/PDF correcte d'un bloc table.

v4.8.1 — Fix bloc Tableau ✅ (2026-09-03)

  • « + Row » (bas) corrigé — l'insertion de ligne utilisait splice(index, ligne) (mauvaise signature) → aucune ligne ajoutée ; désormais splice(index, 0, ligne).
  • Bouton « + » à droite — ajoute une colonne à droite (équivalent « Add column »).
  • Redimensionnement des colonnes — curseur col-resize au survol des bordures d'en-tête, drag = largeur ; persisté via colsW.

v4.9.0 — Collaboration ✅ (2026-09-04)

Objectif : commentaires inline, mentions @, notifications in-app + email. COMPLETED. Doc : docs/Guide_Complet_Notion_sharing_collaborartion.md

  • Inline comments — commentaires sur sélection de texte dans l'éditeur (bouton flottant 💬) ; table comments étendue (target_type/target_id/anchor_block_id/anchor_start/anchor_end) et migrée (FK générique, idempotente) ; panneau de commentaires + résolution/suppression + compteur topbar
  • @mentions — autocomplétion @ (recherche utilisateurs temps réel), insertion @login dans les blocs et commentaires, table notifications ; endpoint POST /api/pages/{id}/mentions (notif des mentions de contenu)
  • Email notifications — service SMTP (app/services/mailer.py + templates HTML) ; préférences email par utilisateur (comments/mentions) ; config .env (SMTP_*, APP_BASE_URL) ; repli no-op sans SMTP
  • Centre de notifications in-app — cloche topbar (badge non-lus, polling 30s), panneau déroulant, mark as read / mark all read
  • Settings — toggles réels dans Settings → Notifications (Commentaires / Mentions)
  • 208 tests passent (+9 v4.9.0)

v4.11.0 — Agent IA : clés API par utilisateur & commandes slash ✅

Livré (2026-09-05) : credentials par utilisateur (table user_llm_keys, plusieurs providers), chargement dynamique des modèles depuis le fournisseur (POST /keys/{p}/models), commandes slash dans le chat (/provider, /model, /keys, … via PATCH conversation), /run utilise la clé de l'utilisateur. 239 tests verts.

v4.10.1 — Agent IA : config LLM dans l'UI ✅

Livré (2026-09-05) : sélecteur provider/modèle dans le panneau agent (persisté par conversation), config runtime DB-backed (llm_config), écran admin Agent & IA avec test de connexion (LLMClient.ping(), sans fallback mock). 232 tests verts.

v4.10.0 — FlowDeck Agent (Agent IA natif) ✅

Livré (2026-09-05) : agent conversationnel complet — boucle ReAct, streaming SSE, 18 outils avec snapshots rollback, ACL par rôle, contexte automatique, custom agents, déclencheurs planifiés + skills, multi-LLM (offline mock + 8 providers). 18 tests dédiés. Voir docs/Flowdeck_Agent_integration.md.

Objectif : Un agent IA intégré à FlowDeck, capable de planifier, rechercher et agir directement sur les workspaces — collections, pages, propriétés, vues, issues Gitea. Inspiré de Notion Agent (2026).

Documentation :

docs/Flowdeck_Agent_integration.md (702 lignes) · docs/Guide_Complet_Notion_Agent_2026.md (464 lignes)

Concept

Là où un assistant IA classique répond (prompt → réponse), FlowDeck Agent réalise :
objectif → planification → collecte contexte → actions API → résultat

Notion AI FlowDeck Agent
Répond, résume, réécrit Planifie, recherche, agit
Bloc de texte Crée collections, pages, propriétés, vues
Sans état Historique conversation + snapshots rollback
Aucune action DB Modifie le workspace via API FastAPI existantes

Fonctionnalités clés

  • Interface conversationnelle — panneau agent dans le sidebar (🤖 Agents) + popup chat
  • Boucle ReAct — Raisonnement → Action → Observation → itération (max 12 tours)
  • Streaming SSE — affichage temps réel du raisonnement et des actions
  • 10+ outils actionnables — search, read/write collections/pages, views, properties, Gitea sync
  • Permissions — même ACL que l'utilisateur (PermissionManager), audit log + rollback
  • Contexte automatique — workspace actif, pages mentionnées, fichiers uploadés
  • Custom agents — instructions, modèle, outils, scope par agent
  • Déclencheurs — planifiés, webhooks, événements workspace
  • Skills réutilisables — templates d'instructions + outils (ex: "Rédiger rapport hebdo")
  • Multi-LLM — GPT, Claude, Gemini, modèles locaux (Ollama), deepseek, qwencloud, Nvidia, openrouter

Architecture (nouveaux composants)

app/
├── routers/agent.py        — /api/agent/* (run, conversations, tools)
├── services/agent_engine.py — Orchestrateur ReAct + boucle tool calls
├── services/llm_client.py   — Abstraction multi-fournisseur LLM
├── services/tool_registry.py — 10+ outils wrappant les API existantes
├── services/context_builder.py — Collecte contexte workspace
└── templates/
    ├── agent_panel.html     — Panneau conversation Alpine.js
    └── agent_message.html   — Fragment message (streaming)

Nouvelles tables

Table Rôle
agents Config agent (nom, instructions, modèle, tools scope)
agent_conversations Sessions (titre, agent, workspace, statut)
agent_messages Messages (role, content, tool_calls, artifacts)
agent_actions Journal d'audit (tool, args, result, undo_snapshot)
agent_skills Skills réutilisables (nom, prompt template, outils)
agent_triggers Déclencheurs (cron, webhook, event, agent cible)

Cas d'usage FlowDeck

  • Créer un CRM complet — agent crée collection, propriétés, vues, exemples
  • Résumer les notes de réunion — lit les pages, synthétise, crée une page résumé
  • Générer des OKR — crée la database OKR avec relations et vues
  • Analyser un repo Gitea — lit les issues, crée un dashboard de suivi
  • Rédiger un rapport hebdomadaire — agrège les pages modifiées, génère le rapport

Plan de migration (5 phases)

  1. Phase 1 — Core Agent ✅ (v4.10.0) : AgentEngine + LLMClient + 3 outils (search, read, create) + SSE streaming
  2. Phase 2 — UI : agent_panel.html, historique conversations, sélecteur de modèle ✅ (v4.10.1)
  3. Phase 3 — Outils avancés ✅ (v4.10.0) : 7 outils supplémentaires (views, properties, Gitea, uploads)
  4. Phase 4 — Autonomie ✅ (v4.10.0) : custom agents, skills, déclencheurs planifiés
  5. Phase 5 — Plateforme ✅ (v6.6.0) : API publique agent → intégrations tierces, marketplace skills

Limitations (v1)

  • Pas de modification concurrente (lock optimiste DB)
  • Pas d'appels API externes non-FlowDeck (sandbox strict)
  • Budget tokens max par conversation (500k tokens)
  • Timeout 5 minutes par run

v5.0.0 — Command Palette & Recherche ✅ (2026-09-06)

Objectif : Ctrl+K / Ctrl+P palette de commandes universelle + recherche full-text. COMPLETED.

  • Command palette — Ctrl+K / Ctrl+P recherche universelle (modale, fuzzy, navigation clavier)
  • Quick actions — navigation, création, commandes
  • Recherche full-text — SQLite FTS5 sur pages + propriétés (prérequis technique de la palette)

v5.1.0 — Automations ✅ (2026-09-07)

Objectif : moteur de règles if-this-then-that + boutons cliquables. COMPLETED.

  • Database automations — moteur de règles if-this-then-that (trigger + condition + action)
    • Déclencheurs : événement (page.created/updated/deleted/moved, collection.*) / cron (*/N, minute fixe, @hourly, @daily) / bouton
    • Conditions combinables : eq, neq, contains, not_contains, is_empty, is_not_empty, changed
    • Actions : webhook (X-FlowDeck-Secret), set_property (validé), create_page (interpolation [[prop]]/{{title}}), notify
    • Tables automations + automation_runs (migration v5), scheduler de fond (60 s), historique des exécutions
  • Buttons — boutons cliquables déclenchant des actions
    • Bloc button dans l'éditeur (menu slash) + picker d'automation inline
    • Endpoint /api/automations/{id}/run (exempt CSRF) + UI Settings → Automations
  • Hooks événements dans collections.py / board.py / workspace.py (apply_page_template)
  • 11 tests tests/test_automations.py ; suite complète 289 verte

v5.2.0 — Infrastructure & Polish ✅ (2026-09-11)

Objectif : fondations de production — design system, sécurité, infra, forge. COMPLETED.

Design system

  • Design tokens — static/css/design-tokens.css (couleurs, espacements, typo, ombres, z-index) chargé après app.css
  • Composants réutilisables — static/css/components.css (btn/input/modal/dropdown/toast/card/badge/empty/table)

Sécurité & Utilisateur

  • API Tokens — générer/lister/révoquer dans Settings → API tokens (app/routers/security.py, table api_tokens, bearer /api/v1)
  • Sessions actives — liste + révocation (user_sessions, SessionManager.list_sessions/revoke_session)
  • Onboarding wizard — /welcome (workspace → forge → premier projet) + welcome.html

Infrastructure

  • 🥇 Migrations versionnées — table schema_version + runner app/migrations.py (baseline v1, indexes v2, FTS5 v3)
  • Backup automatique — snapshot SQLite quotidien (app/services/backup.py, scheduler + API admin, rétention configurable)
  • Index manquants — users.email, user_oauth_tokens(user_id, provider), collections/pages(workspace_id), pages(deleted_at)
  • Linting — ruff (Python, pyproject.toml) + eslint flat (eslint.config.mjs) ; ruff check et eslint sans erreur
  • Tests parallèles — pytest-xdist (pytest -n auto en local et en CI ; DB + dossier backup isolés par test)
  • Build Docker multi-stage — builder + runtime (libs WeasyPrint), image allégée

Forge integration

  • DB: table projects — type (builtin/gitea/github), forge_id, clone_url, default_branch, language
  • Cron: sync périodique des projets — project_sync_scheduler (défaut : chaque heure)
  • GitHubAdapter complet — API GitHub v3 → interface ForgeAdapter

Tests (cibles)

  • 397 tests — dont backups, projets, adapters forge (mock HTTP), OAuth (mock), multi-user ✅
  • Tests d'intégration auth (OAuth mock) — login/callback Gitea + GitHub, mode link, rejet d'état invalide
  • Tests des adapters forge (mock HTTP) — GitHubAdapter via httpx.MockTransport
  • Tests multi-user (permissions croisées) — PermissionManager owner/editor/viewer

✅ Validation (2026-09-11) :

  • pytest tests/test_v52_infra.py -v → 18/18 passed (tokens, sessions, onboarding, backups, projets, adapters forge, OAuth mock, multi-user)
  • pytest -q (suite complète) → 397 passed
  • ruff check app tests → All checks passed! · eslint static/js → 0 problème
  • CI Gitea (commit ba363ea ; run push #1412 + PR #15 run #1413) → success sur push et pull_request : jobs lint (≈43 s), test (-n auto, ≈4 min), docker multi-stage (≈1 min)
  • Docker : stages builder + runtime vérifiés par le job CI docker (from app.main import app OK)

Complétion du 2026-09-11 :

  • Isolation des tests corrigée : tests/conftest.py mute le singleton settings (au lieu de le remplacer), sinon les modules ayant importé settings au chargement (ex. backup.py) gardaient les valeurs par défaut → backups flaky. DB temporaire unique par test, sûr en xdist.
  • Backups réellement testés (snapshot + prune + API admin) : les 2 skips supprimés.
  • init_db() crée désormais aussi webhook_subscriptions (schéma complet sans dépendre du lifespan FastAPI).
  • Tests OAuth mock (flux complet) ajoutés dans tests/test_v52_infra.py.
  • CI : job lint (ruff + eslint) + tests parallèles (-n auto), déclenché sur toutes les branches.

v5.3.0 — Database Avancée ✅ (2026-09-06)

Objectif : databases inline + templates prédéfinis + validation propriétés. COMPLETED.

  • Inline databases dans n'importe quelle page — slash command /database (groupe DATA) → sélecteur de templates → bloc embed_type:'collection' rendu par FlowDeckDB
  • Templates de database prédéfinis — 6 templates seedés (CRM, Project tracker, Task list, Content calendar, Meeting notes, Reading list) + galerie au clic « Database » (Get Started) et /database ; POST /db/api & /db/inline/api acceptent template et matérialisent les propriétés
  • Validation des propriétés (required, unique, min/max) — côté serveur (validate_property_rule, 400 + messages) + UI (modale propriété + erreurs de cellule)

v5.10.0 — Éditeur : interactions de bloc ✅ (2026-09-08)

Objectif : parité de manipulation des blocs avec Notion — les blocs étaient éditables mais statiques (impossible de les déplacer, dupliquer ou annuler une action). COMPLETED.

  • Drag & drop des blocs — poignée ⋮⋮ au survol de chaque bloc, drag vertical pour réordonner, indicateur de drop (ligne bleue) ; multi-sélection (Shift+clic sur poignée → sélection groupée déplacée d'un seul geste, ordre reconstruit depuis le DOM via data-id)
  • Menu contextuel de bloc — clic (ou clic droit) sur ⋮⋮ : Turn into (sous-menu conservant le contenu), Duplicate, Copy link to block (#fdblk-<id> avec re-focus), Move to (recherche de pages + API), Delete, couleurs texte/fond appliquées au bloc ou à la sélection
  • Undo / Redo — Ctrl+Z / Ctrl+Shift+Z/Ctrl+Y, pile de 100 opérations en mémoire du tab, re-focus du bloc restauré, déclencheur sur toutes les mutations (entrée, retour arrière, slash, tableaux, colonnes, toggles…)
  • Duplicate block — Ctrl+D, menu bloc ou slash command « Duplicate » ; copie profonde (enfants columns/toggle) en multi-sélection
  • Slash command étendue — groupe « Actions » : Turn into, Duplicate, Copy link to block, Delete block
  • En-têtes de tableau — toggles « Header row » / « First col » dans la barre du tableau (has_header défaut actif + nouveau first_col_header), persistés + rendu <th> en preview et exports Markdown/HTML
  • Intégration realtime — syncNow() poussé après chaque mutation programmatique ; 9 tests tests/test_block_interactions.py ; suite complète 307 verte (+3 PDF pré-existants)

v5.13.0 — Collaboration temps réel ✅ (2026-09-08)

Objectif : édition collaborative en direct (parité Notion en équipe). COMPLETED. Chantier n°1 de la parité Notion ; socle pour v5.14.0 (synced blocks).

  • WebSocket gateway — endpoint WS /ws/pages/{id}, auth via cookie session (refus 4401), page introuvable/supprimée → 4404 ; rooms par page en mémoire, chargées depuis la base au premier connect, droppées quand vides
  • Présence — avatars des utilisateurs connectés (topbar), couleur par utilisateur, join/leave broadcasté ; welcome = self + peers
  • Curseurs live — position curseur/sélection des autres éditeurs (block + offset), calque dédié, label avec nom, mise à jour à l'édition/au scroll
  • Merge de modifications — diffusion des ops de blocs insert/update/delete/move avec last-write-wins par bloc + version de page (stale → sync complet) ; titre synchronisé (debounce) ; persistance debounce ~1 s + flush à la déconnexion du dernier client
  • Fallback polling — si WS indisponible, rafraîchissement diff toutes les 10 s (adopté seulement sans brouillon local) + reconnexion automatique
  • CSP connect-src étendu à ws: ; 12 tests tests/test_realtime.py ; suite complète 298 verte (+3 PDF pré-existants)

v5.4.0 — Expérience éditeur ✅ (2026-09-11)

Objectif : parité éditeur Notion — backlinks, duplication, corbeille, versions, import. COMPLETED.

  • Backlinks — GET /board/api/pages/{id}/backlinks (scan des liens internes /pages/<id>) + popover « Lié depuis… »
  • Duplicates — POST /board/api/pages/{id}/duplicate (copie profonde des blocs) + POST /db/{id}/duplicate (vues + propriétés + pages) ; entrées « Duplicate » dans les menus ...
  • Corbeille globale améliorée — vue cross-workspace GET /board/api/trash + app/services/trash.py (purge automatique > 30 jours, scheduler quotidien)
  • Historique de version UI — snapshots page_versions à chaque sauvegarde modifiée, GET /api/pages/{id}/versions, POST .../versions/{vid}/restore, popover « Version history »
  • Import — POST /api/pages/import (markdown) + POST /api/pages/import/file (.md/.txt/.zip d'export Notion) ; import CSV collections POST /workspace/collections/{id}/import/csv
  • 17 tests tests/test_v54.py ; suite complète 397 verte

v5.5.0 — Embeds & Média Riche ✅ (2026-09-12)

Objectif : parité avec les 60+ embeds Notion — contenu tiers rendu dans la page. Source : analyse Notion clone (delta v4 → v5.5, 2026-09-04). COMPLETED.

  • Bloc Embed universel — /embed : YouTube (watch/shorts/youtu.be), Vimeo, Figma, Google Maps, Google Docs/Sheets/Slides, Loom, X/Twitter, CodePen, Miro, Spotify, SoundCloud, Twitch, Pinterest, Office…
  • Bookmark cards — aperçu riche des URLs (métadonnées OG : titre, image, description, site, favicon)
  • Image lightbox — clic pour agrandir, navigation clavier (←/→) + plein écran dans l'éditeur et les pages publiques
  • Previews inline — PDF, vidéo, audio rendus directement dans la page
  • Cover & icône de page — upload image de couverture (fichier ou URL) + emoji/icône custom

Détails livrés :

  • Service app/services/embeds.py : détection multi-provider + réécriture d'URL, resolve_embed(), inline_kind(), embed_html() ; endpoint POST /board/api/embed/resolve
  • Service app/services/og_fetcher.py : parseur OG robuste (ordre d'attributs libre), favicon, repli sans réseau ; endpoint POST /board/api/og/metadata
  • Endpoints POST/DELETE /board/api/pages/{id}/cover (JSON URL ou upload image) et POST /board/api/pages/{id}/icon
  • Éditeur : résolution d'embed à la saisie (URL d'origine conservée + embed_src mis en cache), lightbox multi-images navigable, préviews vidéo/audio/PDF
  • Pages publiques /p/<slug> : cover + icône, embed résolu, lightbox clavier
  • Export Markdown/HTML/PDF : nouveau bloc embed/bookmark avec embed_src résolu
  • Fix chemins API : l'éditeur appelait /api/pages/... alors que les routes sont /board/api/pages/... (cover, icon, versions, backlinks, import, move, OG) — corrigé
  • 47 tests tests/test_v55.py ; suite complète 444 verte ; ruff check OK

v5.6.0 — Import de données (étendu) ✅ (2026-09-13)

Objectif : faire de FlowDeck la cible d'import universelle pour les outils réellement utilisés (notes Markdown, bureautique, tableaux, signets, dev), en complétant l'import de base (Markdown/CSV/Notion, déjà dans v5.4.0). COMPLETED. Sources retenues : Obsidian, Notion, Logseq/Roam, Apple Notes/Bear/Ulysses, Google Keep, OneNote, Word, Google Docs, HTML, PDF, CSV/Excel/Sheets/JSON, Gitea/GitHub, Raindrop, Pocket, Readwise, Shaarli, .ics, OPML, Standard Notes. Sources exclues : Confluence, Evernote, Asana, Trello (non utilisées).

Phase 0 — Socle d'import unifié (prérequis) ✅

Toutes les sources partagent le même pipeline ; à livrer avant les imports.

  • Service app/services/importers/ — interface commune (detect(), parse(), to_pages()) + résultat normalisé (ImportResult : pages, pièces jointes, warnings, stats)
  • Pipeline commun — upload → parse → normalisation blocs + métadonnées → création (pages + hiérarchie parent_id) → rapport d'import
  • Pièces jointes — extraction (images/fichiers), upload, réécriture des liens dans les blocs
  • Frontmatter YAML → propriétés (title, tags, dates, champs custom)
  • Assistant UI d'import — choix de la source, mapping colonnes→types, preview/dry-run, barre de progression
  • Import asynchrone (job en arrière-plan + polling) pour les gros volumes (vaults, zips)
  • Idempotence / déduplication + reprise sur erreur partielle
  • Tests — harnais d'import + fixtures par source
  • Réutilise : _md_to_blocks (app/services/export.py), PROPERTY_TYPES + validate_property_rule (property_types.py), db_templates.materialize_properties, endpoints upload/cover existants

Phase 1 — Notes & Markdown (réutilise _md_to_blocks) — faible effort ✅

  • Obsidian (vault .zip/dossier) — frontmatter YAML, [[wikilinks]], ![[embeds]], attachments, hiérarchie de dossiers (prépare v5.11.0)
  • Notion (améliorer l'existant) — hiérarchie complète, databases (CSV) → collections, images
  • Logseq / Roam Research — markdown outliné (puces imbriquées), ((block refs)), pages journal
  • Apple Notes / Bear / Ulysses — import export HTML/Markdown
  • Google Keep — Takeout JSON + HTML
  • OneNote — export HTML/PDF, best-effort (fidélité limitée)

Phase 2 — Données & tableaux (fort ROI databases) — effort faible/moyen ✅

  • CSV/TSV typé — inférence auto (texte/nombre/date/bool/select/multi_select) + UI mapping + options
  • Excel .xlsx (openpyxl) — multi-feuilles → collections
  • Google Sheets — export CSV/XLSX
  • JSON générique — mapping configurable (JSONPath → propriétés)

Phase 3 — Documents & bureautique — effort moyen ✅

  • Word .docx (mammoth/pandoc) — titres, listes, tableaux, images
  • Google Docs — Takeout .docx/HTML
  • HTML (fichiers/dossier, web clipper) — conversion HTML → blocs
  • PDF — extraction texte + images (fidélité limitée)

Phase 4 — Signets, dev & divers ✅

  • Gitea / GitHub issues + labels + milestones → collection (via API — quasi natif)
  • Raindrop.io (CSV/HTML) → bookmark cards (réutilise v5.5.0)
  • Pocket (CSV/HTML)
  • Readwise (highlights CSV/Markdown)
  • Shaarli (API/export JSON) → bookmark cards
  • Calendrier .ics (Google/Outlook/Apple)
  • OPML (flux/outlines)
  • Standard Notes / autres

Phase 5 — Durcissement & finition ✅

Objectif : industrialiser l'import (ré-import, lots, URL, forge, relations, rapports).

  • Import incrémental / re-sync — modes skip / update (upsert des pages + lignes par titre) / duplicate, via import_items
  • Import de dépôt forge — arborescence de fichiers Gitea/GitHub → pages (hiérarchie de dossiers, fichiers texte, code en blocs)
  • Import par URL / web clipper — POST /api/import/url : fetch (garde SSRF) + OG metadata → page (carte bookmark + contenu)
  • Lot multi-fichiers + file d'attente — POST /api/import/run-batch + file d'attente UI (statut par fichier)
  • Relations Notion — POST /api/import/relations/resolve : colonnes texte référençant une autre collection → propriétés relation (ids de pages) ; auto-exécuté après un import Notion
  • Reprise / erreurs partielles + rapport exportable — import qui continue par page en cas d'erreur (status: partial, liste errors) ; rapport JSON téléchargeable (GET /api/import/jobs/{id}/report + bouton UI)
  • Valeurs de propriétés par id — correction : les lignes importées stockent les valeurs par id de propriété (rendu correct dans les vues DB)

Priorisation

Ordre Phase Effort Impact
1 Phase 0 — Socle unifié M 🔴 prérequis
2 Phase 1 — Notes/Markdown S–M 🔴 fort (Obsidian, Notion)
3 Phase 2 — Données/tableaux S–M 🔴 fort (databases)
4 Phase 4 — Signets/dev/divers S 🟠 moyen (Gitea natif, Raindrop)
5 Phase 3 — Documents M 🟠 moyen (docx, HTML)

v5.7.0 — Database Avancée (Pt. 2) ✅ (2026-09-13)

Objectif : compléter la parité sur les propriétés, les vues sauvegardées et le Kanban pro. COMPLETED.

  • Types propriété — person, created_time, created_by, last_edited_time, last_edited_by câblés : auto-valeurs calculées serveur (apply_auto_properties) à la création/mise à jour, sélecteur person (membres du workspace via GET /db/{id}/members/api), rendu chips/avatars et édition dédiée dans l'UI
  • Groupes de propriétés — colonne collection_properties.group_name, header de table avec sections pliables (db-group-row + toggle) et POST /db/{id}/property-groups/api
  • Vues sauvegardées par utilisateur — collection_views.created_by ; GET /db/{id}/views/api filtre par propriétaire (les vues partagées NULL restent visibles), save-as/duplicate/DELETE + renommage
  • Swimlanes Kanban — sub_group_by (2e dimension de groupement) : une rangée de colonnes par lane
  • WIP limits — wip_limits par colonne, alerte visuelle au dépassement (wip-exceeded)
  • Cartes configurables — card_properties, card_size (compact/détaillé), couverture cover_mode (none/icon/color/property) via cover_property
  • Calendar avec drag & drop — grille mensuelle, date_property, navigation mois/Today, drop d'une carte sur un jour = reschedule
  • Gallery avec couvertures — cartes avec vignette (image de propriété, icône, couleur, ou cover de ligne), tailles small/medium/large

Détails livrés :

  • Migration 10 : collection_properties.group_name, collection_views.created_by/updated_at, collection_pages.cover_url
  • app/services/property_types.py : user_ref(), apply_auto_properties(), validation person
  • collections.py : auto-props create/update/sub-item, PATCH partiel fusionné, membres, groupes, vues per-user (list/save/duplicate/delete), config de vue étendue (sub_group_by, wip_limits, card_size, cover_mode, card_properties, date_property, property_groups)
  • dashboard.py : auto-props à la création de ligne, views exposées dans table-data et le contexte de page
  • _database_table_scripts.html réécrit en composant multi-vues (table/board/calendar/gallery/list) + barre de vues, éditeurs de cellules par type, picker personne, popovers de configuration
  • 12 tests tests/test_v57_db_advanced.py ; suite complète 503 verte ; ruff check OK

v5.8.0 — Calendrier & Rappels ✅ (2026-09-13)

Objectif : calendrier complet + notifications proactives. COMPLETED.

  • Vues Jour / Semaine / Mois — sélecteur de mode dans la vue calendar (persisté en config de vue), navigation ‹/› et Today adaptées, vue Jour en agenda horodaté, Semaine en 7 colonnes ; événements servis par GET /db/{id}/calendar/api avec expansion serveur des occurrences
  • Récurrence d'événements — moteur app/services/recurrence.py (daily/weekly/monthly, intervalle, count, until, byweekday lundi=0, timezone) ; règle stockée dans property_values_json.__recurrence__ ; popover événement (double-clic) avec Repeat/Every/Ends ; validation serveur (400)
  • Support timezone — colonne users.timezone + picker dans Settings → Notifications (GET/POST /api/notifications/timezone, zones via GET /db/timezones/api) ; timezone par événement (__timezone__) > règle de récurrence > préférence utilisateur
  • Rappels — app/services/reminders.py : lead minutes/heures/jours avant chaque occurrence, scan toutes les 60 s (reminder_scheduler), dédup reminder_log, notifie les personnes assignées (repli admin), in-app + email (pref reminders) ; stockés dans property_values_json.__reminder__, édités dans le popover événement
  • Centre de notifications — la cloche (v4.9.0) couvre désormais rappels, assignations et commentaires ; nouvelles préférences reminders + assignments ; notification d'assignation émise par notify_assignment() sur PUT /db/pages/{id}/api (comparaison avant/après des propriétés person)
  • Template Meeting Notes — propriétés Agenda et Notes ajoutées au template seed (migration 12, préserve les personnalisations) ; le schéma Attendees/Date/Status/Action items était déjà là

Détails livrés :

  • Migrations 11 (reminder_log, users.timezone) et 12 (template Meeting notes)
  • app/config.py : reminders_enabled, reminder_scan_interval_seconds
  • _database_table_scripts.html : modes jour/semaine/mois, chips d'occurrences (badge ↻ + heure), popover Time/Timezone/Repeat/Remind, badges ↻/🔔 dans les cellules date, drag & drop de reschedule préservé
  • 20 tests tests/test_v58_calendar_reminders.py ; suite complète 523 verte ; ruff check OK
  • Version — 5.11.7

v5.9.0 — AI Writing Assist (éditeur) ✅ (2026-09-10)

Objectif : l'IA Notion dans l'éditeur, au-dessus du moteur v4.10.0 (Agent IA). COMPLETED.

  • Slash AI commands — groupe « AI » dans le menu / : Write with AI, Summarize, Translate, Continue writing (E.aiSlash)
  • Autocomplétion — module AIAC : suggestion courte après ~900 ms d'inactivité, pastille « Tab » ancrée au bloc, insertion au Tab, rejet à Escape
  • AI properties — bouton ✨ par ligne de la table database : POST /api/agent/writing/properties propose Status/Priority/Résumé et applique les valeurs
  • Service app/services/ai_writing.py — 6 actions sans outils, replis déterministes hors-ligne
  • Endpoints — POST /api/agent/writing + POST /api/agent/writing/properties
  • 29 tests tests/test_ai_writing.py ; version 5.9.0

v5.10.0 — Éditeur : interactions de bloc ✅ (livré — voir section Completed)

Objectif : le graphe de connaissances Notion. Complète les backlinks de v5.4.0 (section « Lié depuis ») par la création des liens depuis l'éditeur. COMPLETED.

  • Wiki-links [[ — taper [[ ouvre le picker de pages (GET /board/api/wiki/pages, recherche substring + sous-séquence floue), Entrée insère un lien interne rendu comme chip atomique (icône + titre, cliquable) ; module WM dans _page_editor_scripts.html ; tokens [[fdpage:ID]] stockés dans le texte des blocs et relus intacts par gtTok() (autosave, drag, undo/redo préservés)
  • Mention de page @ — le menu @ (utilisateurs v4.9.0) gagne la section « Pages » : @nom cherche les pages et insère le chip inline
  • Mention de date @ — section « Date » : @today, @tomorrow, @hier ou @YYYY-MM-DD insèrent [[fddate:…]], rendus comme chips de date lisibles (« Fri 25 Dec 2026 »)
  • Renommage propagé — le token ne stocke que page_id ; GET /board/api/wiki/titles résout les libellés au rendu (editeur + page publique) → renommer une page met à jour tous ses liens ; page supprimée → « Deleted page »
  • Bonus — le scanner de backlinks v5.4.0 reconnaît les tokens wiki ; _render_blocks_public rend les chips en page publiée (HTML échappé) ; service app/services/wiki_links.py ; 15 tests dédiés (voir v5.12.0)

v5.12.0 — Templates & verrouillage de page ✅ (2026-09-14)

Objectif : démarrage rapide productif et protection des pages stabilisées. Les page_templates existent (v2.0.0/v4.2.0) mais uniquement côté collections. COMPLETED.

  • Template picker global — « + New page » (sidebar, footer, Ctrl+K) ouvre la galerie : 5 templates built-in (app/services/block_templates.py — Empty, Meeting notes, Weekly report, To-do list, Project doc) + templates custom utilisateur (page_global_templates, migration 13, cloisonnés par created_by)
  • Bouton « Use template » — POST /board/api/page-templates/{id}/use (id 0 = built-in par clé) duplique le contenu des blocs dans une nouvelle page ; « Empty » retombe sur la création classique ; menu « … » → « 📑 Save as template » capture la page courante
  • Page lock — toggle 🔒 dans le menu « … » : bannière sticky read-only, blocs/titre non éditables ; serveur POST /board/api/pages/{id}/lock + garde _ensure_page_editable → 423 sur PUT /api/pages/{id} et POST /api/pages/{id}/blocks ; déverrouillage réservé au poseur du lock (locked_by) ou admin (403 sinon) ; indicateur visuel = bannière en tête de page
  • Full-width mode — toggle dans le menu « … », persisté par page (pages.full_width), POST /board/api/pages/{id}/options, classe CSS .full-width
  • Small text / typo options — toggle « Aa Small text » (pages.font_small), classe .small-text (taille réduite ; serif/mono : non demandé au-delà du compact — volontairement hors scope)

v5.13.0 — Collaboration temps réel ✅ (livré — voir section Completed)

v5.14.0 — Synced blocks ✅ (2026-09-15)

Objectif : avancer depuis v6.0.0 un bloc Notion très utilisé (même contenu dans plusieurs pages, édité une fois). COMPLETED.

  • Bloc synced_block — table synced_blocks (source de vérité) + références par page ; slash command /synced
  • Rendu — ring rouge + badge « Synced » sur le bloc ; édition à un endroit => mise à jour partout (via rooms WS v5.13.0 si actives, sinon au reload)
  • Unsync — action « Unsync » qui convertit l'instance en copie indépendante
  • Copy & sync across pages — copier un bloc dans une autre page avec option « Paste and sync »

v5.15.0 — Webhooks v2 ✅ (2026-09-21)

Objectif : webhooks sécurisés, fiables et complets pour les intégrations tierces. COMPLETED.

  • Signature HMAC SHA-256 — header X-FlowDeck-Signature sur chaque payload, vérification côté receveur
  • Retries avec backoff — 4 tentatives max, délais 2s / 10s / 60s, logs détaillés
  • 20+ nouveaux événements — total ~50 événements (pages, blocs, utilisateurs, collections, workspaces, etc.)
  • API v2 endpoints — /api/v2/webhooks/test-signature (test HMAC), /api/v2/webhooks/retry (relancer les échecs)
  • Tests — 21 dédiés (tests/test_webhooks_v2.py) ; 7 tests d'intégration câblés (retry échec→succès, échec après MAX_ATTEMPTS, event inconnu ignoré, aucun abonné, fan-out wildcard, flow complet signé bout en bout, retry_due_deliveries superseded→delivered) — fixture db = SQLite isolée par test + httpx.MockTransport + RETRY_DELAYS neutralisé ; suite complète 749 verts, 0 skip

v6.0.0 — PWA : Progressive Web App, offline ✅ (2026-09-18)

Objectif : support hors ligne complet (manifest, service worker, IndexedDB, queue de mutations, sync serveur + résolution de conflits). COMPLETED.

  • Manifest & icônes PWA — static/manifest.json, static/icons/*, scripts/generate_pwa_icons.py
  • Service Worker — static/sw.js (precache shell, network-first HTML/API, page offline, Background Sync)
  • IndexedDB client — static/js/offline.js (window.FlowOffline) : queue, delta, flush, marqueurs dirty
  • Endpoints sync — app/routers/sync.py + app/services/sync_engine.py (/api/v2/sync/delta|batch|status)
  • Migrations — table offline_sync_queue + colonnes sync_version (triggers AFTER UPDATE)
  • Conflits — edit-edit (last-write-wins), edit-delete (page orpheline), create-create (« copie offline »)
  • UI — banner offline + pending count, badge de synchronisation, toasts, icône ⟳ sur pages dirty
  • Durcissement — max 100 mutations/batch, timeout 30 s, rétention queue 30 j
  • Tests — test_sync.py, test_sync_migrations.py, test_service_worker.py, test_pwa_offline.py, E2E e2e/pwa_offline.spec.js
  • Doc — section /help « Offline mode (PWA) »

v6.1.0 — Granular Permissions ✅ (2026-09-19)

Objectif : page-level, collection-level & property-level ACL + groupes + audit. COMPLETED.

  • Page permissions — modes inherit|restricted|private (pages.permission_type, collections.permission_type, collection_pages.permission_type), grants explicites user/group (page_permissions role viewer/commenter/editor/owner), héritage page→collection→workspace, 404 masqué pour non-grantees, owner/admin bypass
  • Collection permissions — collection_permissions + permission_type, /db/{id} et /db/{id}/api masqués (404→302), création page et delete collection gatés (viewer 403), editor bypass
  • Property-level visibility — property_permissions (viewer|editor), GET /db/{id}/properties/api filtré par get_visible_properties(), GET /api/v2/collections/{id}/properties/visible (visible/hidden), grant = owner collection uniquement
  • Groupes réutilisables — tables user_groups + group_members (workspace-scoped, UNIQUE(name)), CRUD /api/v2/groups + /groups/{id}/members, grant par group_id (page/collection/property), retrait membre révoque l'accès
  • API — app/routers/permissions.py : pages (list/mine, grant, batch, revoke, permission-type), collections (list/grant/revoke/type + visible), properties (list/grant/revoke), groups (list/create/update/delete + members), users picker, audit GET /api/v2/audit/permissions
  • Guards — board.py (GET/PUT /board/api/pages/{id}) + collections.py (delete collection, GET/PUT/DELETE page, properties), 403/404 conformes, is_admin/owner bypass + _session_user() (no admin fallback)
  • PermissionManager — app/services/permission_manager.py étendu : _explicit_grant_role() (best rank user+groups), get_page/collection_permission(), can_view/edit_page|collection, can_view/edit_property(), get_visible_properties(), groups, log_permission_change(), cache 60s + invalidate()
  • Audit — table permission_audit_log (resource_type, action grant/revoke/type_change/group_*), index, log sur tous les mutateurs, GET /api/v2/audit/permissions (owner/admin only, limit 500)
  • Migration 18 — migrations.py : création 6 tables + 3 colonnes permission_type + indexes (idempotent)
  • Tests — tests/test_v60_granular_permissions.py 21 tests (inherit/restricted/private, grant viewer/editor, revoke, batch, type via API, collection restricted+grant, property visibility/hidden, group inherits + revoke, audit, auth 401, validation 400/404)

v6.2.0 — Web Clipper : extension navigateur ✅ (2026-09-19)

Objectif : capturer n'importe quelle page web en page FlowDeck (article, sélection, bookmark, screenshot) depuis une extension Manifest V3 + API directe. COMPLETED.

  • Extension Manifest V3 — extension/ + static/extension/ (manifest, background.js, content.js, popup.html/js, clipper.css, icônes 16/32/48/128, flowdeck-clipper.zip servi à /static/extension/)
  • 4 types de capture — article (HTML complet → sanitize_html + html_to_blocks), sélection, bookmark (carte OG v5.5.0), screenshot (base64) ; cap 10 MB / 200 blocs
  • Serveur — POST /api/v2/web-clipper/clip, GET /status, POST /auth/verify (register device → token fd_… montré une fois), GET /devices, DELETE /devices/{id} + page HTML GET /extensions ; auth triple (session OU Bearer api_tokens OU Bearer extension_devices OU legacy user_tokens), rate-limit 50/h/device
  • Tables migration 19 — extension_devices, extension_clips + index idx_ext_*
  • Settings UI — onglet Extensions (devices, clips count, revoke)
  • 16 tests tests/test_web_clipper.py ; VERSION 6.2.0 ; wiring app/main.py:50,158

v6.2.1 — Web Clipper polish ✅ (2026-09-20)

  • Bouton flottant rond transparent draggable — toggle d'affichage persistant, clipper:clipped refresh auto sidebar
  • Fix bloc bookmark — create_page_from_clip() émet un bloc bookmark fidèle (OG + embed_src résolu), rendu/correct en éditeur + /p/<slug> + exports
  • Fix duplicate inner SyntaxError dans _page_editor_scripts.html
  • flowdeck-clipper.zip régénéré

v6.3.0 — API publique complète v2 ✅ (2026-09-21)

Objectif : REST API documentée OpenAPI, CRUD complet, un seul chemin de code (wrappers sur les services internes). Parité docs/API_GUIDE_V6.md §4 (~80 endpoints) + scopes hiérarchiques read < write < admin. COMPLETED. Route : feat/v6-api-v2 → develop → main — livraison en une fois (tous domaines). Doc : docs/API_GUIDE_V6.md · OpenAPI : /docs + docs/openapi-v2.json (402 chemins)

Phase 0 — Roadmap & doc catch-up ✅

  • Tagguer v6.2.0/v6.2.1 dans CHANGELOG.md + ROADMAP.md + docs/V6_Web_Clipper.md → COMPLETED
  • Détailler v6.3.0 phases 1-8 dans ROADMAP.md (plan gelé)

Phase 1 — Migrations socles (v20) ✅

  • api_tokens : colonnes scopes TEXT DEFAULT 'read,write', expires_at TIMESTAMP (idempotent, rétro-compat)
  • webhook_deliveries : id, webhook_id FK, status, http_code, error, duration_ms, attempt, created_at
  • api_audit_log : id, user_id, token_id, action, resource_type, resource_id, ip, created_at
  • idempotency_keys : key TEXT PRIMARY KEY, user_id, response_json, created_at

Phase 2 — Helpers & auth v2 unifiée (scopes hiérarchiques) ✅

  • app/config.py : public_api_insecure_ok: bool = False — fd-public-key accepté seulement si True (dev local)
  • app/services/api_v2_helpers.py : parse_pagination() (+X-Total-Count), to_iso8601(), handler RFC 7807 application/problem+json, require_scope() (hiérarchie admin ⊇ write ⊇ read), resolve_bearer_token() / get_bearer_user() (hash sha256, revoked + expires_at + scopes, last_used_at, extension_devices)
  • Auth Bearer unifié partagé (clipper + legacy user_tokens supportés) ; handler d'erreurs unifié sur StarletteHTTPException

Phase 3 — Tokens CRUD v2 ✅

  • POST /api/v2/tokens (name, scopes, expires_at) → fd_{urlsafe(32)} hashé, montré une fois
  • GET /api/v2/tokens (prefix only), DELETE /api/v2/tokens/{id} (revoke), POST /api/v2/tokens/{id}/rotate

Phase 4 — Wrappers read (pagination/filtres/tri/fields) ✅

  • app/routers/api_v2.py (prefix="/api/v2", tag api-v2) — GET /collections, GET /collections/{id}, GET /pages/{id}, GET /collections/{id}/pages?filter[]=&sort=&fields=&query=, GET /search?query=&workspace_id=&type= (FTS5), header X-Total-Count, filter[] AND, sort=prop/-prop

Phase 5 — Wrappers write critiques (Idempotency-Key) ✅

  • Collections : POST/GET/PATCH/DELETE /collections/{id} + /linked, /task, /sources
  • Pages : POST/GET/PATCH/DELETE /pages/{id} + /restore, /move, /sub-items, /dependencies
  • Properties : GET/POST /collections/{id}/properties, PATCH/DELETE /properties/{id}, POST .../relation, evaluate-formula, compute-rollup
  • Views/Dashboards/Comments/Notifications/Favorites/Tags/Recents/Sharing/History/Sprints/Templates/Export/Workspaces/Users/Admin — regroupés par ressource

Phase 6 — Webhooks v2 — CRUD simple ✅

  • GET/POST/PATCH/DELETE /api/v2/webhooks, POST /api/v2/webhooks/{id}/test (ping)
  • GET /api/v2/webhooks/{id}/deliveries (journal basique)
  • (reporté v6.4, livré plus tôt) v5.15.0 : signature HMAC X-FlowDeck-Signature, retry 2s/10s/60s, +20 events (Webhooks v2)

Phase 7 — Forges & ressources restantes ✅

  • Sprints, dashboards, templates, export/import, workspaces/members, users, admin
  • Forges : GET /projects, /projects/{owner}/{repo}/tree (best-effort via gitea_client)
  • (reporté, livré v6.4.0) : migration de sync.py vers Bearer — auth Authorization: Bearer (scopes read/write) via get_bearer_user() + repli cookie session conservé pour compat PWA offline (app/routers/sync.py)

Phase 8 — OpenAPI, tests & docs ✅

  • docs_url="/docs" + redoc_url="/redoc" activés ; docs/openapi-v2.json généré (402 chemins)
  • tests/test_public_api_v2.py — 24 tests (auth scopes, pagination, filtres, RFC 7807, idempotency, webhooks deliveries, CRUD multi-domaines)
  • Vérif ruff check app tests + pytest -n auto → 668 verte

v6.4.0 — Realtime editing (production) ✅ (2026-09-22)

Objectif : passer le realtime v5.13.0 en « production » — résolution de conflits au-delà du last-write-wins + édition à grande échelle (broadcast non bloquant, plusieurs rooms/pages, observabilité). COMPLETED.

Conflits au-delà du LWW

  • Merge à 3 voix (diff3-lite) — nouveau service app/services/realtime_merge.py : merge_text_3way() (merge de caractères) + merge_block_3way() (merge champ-par-champ), fonctions pures et testées sans WebSocket ni base
  • Régions disjointes conservées — deux utilisateurs tapant à des endroits différents du même bloc voient leurs deux saisies survivre (au lieu d'écraser l'une par l'autre) ; ordre d'arrivée indifférent
  • Chevauchement réel → LWW par champ + drapeau — un conflit n'est plus « tout le bloc perdu » mais limité au champ concerné ; conflict: true renvoyé dans l'ack et le broadcast
  • Protocole base — le client embarque dans chaque update la version du bloc dont dérive sa saisie ; le serveur fait merge_block_3way(base, current, incoming) ; sans base → LWW historique (rétro-compat ancien client)
  • Adoption côté client — l'ack renvoie le bloc fusionné ; le client met à jour sa base, adopte le résultat (hors bloc en cours d'édition) et affiche un toast en cas de conflit
  • Broadcast du résultat fusionné — le serveur diffuse toujours le bloc final fusionné (jamais la proposition brute) pour convergence garantie de tous les clients

Échelle & robustesse

  • Broadcast non bloquant — chaque connexion a une file sortante (asyncio.Queue) + une tâche _writer dédiée ; _broadcast() fait put_nowait et n'attend plus le socket → un client lent ne fige plus la room
  • Coalescence des curseurs — le writer réduit les messages sel empilés à la position la plus récente (seule la dernière compte), tout en préservant l'ordre des messages importants
  • Déconnexion des clients trop lents — file pleine (MAX_OUT_QUEUE=512) → fermeture 4413 + compteur slow_disconnects (évite qu'une room entière stagne sur un pair mortel)
  • Anti-flood — budget d'opérations par connexion (OP_WINDOW_MAX=400 / 10 s) ; au-delà, réponse ack stale sans application
  • Fix fuite de rooms — une connexion 4404 n'enregistre plus de Room orpheline en mémoire ; room_state() sur page inexistante retourne un dict vide au lieu de planter sur None
  • Observabilité — GET /api/realtime/stats (authentifié) : rooms, connexions, ops, merges, conflits, déconnexions lentes + détail par page

Détails livrés :

  • app/services/realtime_merge.py — merge 3-voix (nouveau, ~170 lignes)
  • app/services/realtime_server.py — RTConn (file + writer + budget), _apply() avec merge, _evict_slow(), stats(), fix fuites
  • app/routers/realtime.py — endpoint GET /api/realtime/stats
  • app/templates/_page_editor_realtime.html — envoi de base, adoption du bloc fusionné, toast de conflit
  • 26 tests tests/test_realtime_v64.py (merge purs, protocole WS, convergence 2 clients, rétro-compat LWW, fuite 4404, coalescence, stats, anti-flood) ; 14 tests tests/test_realtime.py préservés
  • ruff check app tests OK · eslint static/js 0 problème
  • Version — 6.4.0

v6.6.0 — Agent phase 5 : API publique agent & skill marketplace ✅ (2026-09-24)

Objectif : dernière étape du plan d'igration en 5 phases de l'agent — « Plateforme » : exposer l'agent en API publique pour les intégrations tierces et rendre les skills partageables (marketplace). COMPLETED. Voir docs/API_GUIDE_V6.md §2.4.

  • API publique agent — app/routers/api_v2_agent.py (15 routes /api/v2/agents/*, Bearer + scopes read/write, rate limit par token, idempotence Idempotency-Key, api_audit_log) :
    • agents CRUD, conversations + messages, run synchrone JSON (le flux SSE reste réservé à l'UI), journal agent_actions + POST /agents/actions/{id}/undo, POST /agents/{id}/trigger
    • propriété des conversations vérifiée par user_id : un token tiers reçoit 404 (pas de fuite)
    • réponse de run : {status, final, error, reasoning[], actions[], events[], duration_ms}
  • Marketplace skills — app/services/skill_gallery.py (source unique interne + v2) :
    • export portable {format: "flowdeck-skill", version: 1, skill{name, description, prompt_template, allowed_tools}} (aucun id/workspace/auteur local ne fuit) + import avec contrôle de collision (409, overwrite: true pour écraser)
    • galerie de 6 presets installables : rapport hebdo, CR de réunion, base CRM, OKR, analyse repo Gitea, résumé de document (GET /api/v2/skills/gallery, POST /api/v2/skills/gallery/{slug}/install)
    • routes jumelles côté session : GET /api/agent/skills/gallery, POST .../gallery/{slug}/install, POST /api/agent/skills/import, GET /api/agent/skills/{id}/export, DELETE /api/agent/skills/{id} (comble le trou CRUD : pas de suppression de skill avant)
    • UI branchée : section « Galerie » dans la palette / du panneau agent → installation + épinglage automatique du chip
  • Webhooks de cycle de vie agent — agent.run.started et agent.run.failed émis pour la 1re fois (seul agent.run.finished l'était) ; les 3 sont dans le catalogue webhook_outbound → abonnement agent.*
  • Docs — docs/API_GUIDE_V6.md (§2.4 + correction du nom d'événement agent.run.completed → agent.run.finished), OpenAPI régénéré : docs/openapi-v2.json → 427 chemins, info.version = 6.6.0
  • Tests — tests/test_v66_agent_api.py : 15 tests (auth/scopes, CRUD agents, run synchrone, ownership 404, trigger, export/import/validation, galerie + outils valides, routes internes, cycle de vie webhooks)
  • Version — 6.6.0 · ruff check app tests OK · eslint static/js 0 problème · suite 764 verts, 0 skip

v6.5.0 — Synced blocks production (databases & vues) ✅ (2026-09-24)

Objectif : passer les synced blocks en « production » (résolution + propagation fiables partout) et les faire vivre dans les databases/vues — le « reste en v6 » du point v5.14.0. COMPLETED.

Contenu des lignes de database (le point « databases »)

  • Migration 22 — pages.collection_row_id INTEGER REFERENCES collection_pages(id) ON DELETE CASCADE + index partiel ; chaque ligne de database gagne une page contenu (page blocks standard) portant son éditeur complet
  • Service app/services/row_pages.py — ensure_row_page() : création lazy/réparation (page trashée restaurée, parent_section='DbRow'), workspace hérité de la page hôte (DB full-page → page parente inline → collections.gitea_owner/repo), collection_id hérité pour que les ACL de collection s'appliquent au contenu
  • Endpoint GET /db/pages/{row_id}/open/api — renvoie {page_id} (garde _require_view de la collection) ; utilisé par le peek de toute vue (table/board/gallery/list/calendar)
  • Fix bug d'ouverture de ligne — le peek appelait /pages/{rowId} qui lit la table pages → avec des ids croisés il ouvrait une page au hasard (ligne id 5 « Ask AI » → page id 5 « Données ») ; désormais résolution via l'endpoint puis iframe /pages/{pageId}
  • Titres synchronisés bidirectionnellement — renommer la ligne (PUT /db/pages/{id}/api) → page contenu ; renommer dans l'éditeur (PUT /board/api/pages/{id}, POST .../blocks, PUT /api/pages/{id}/rename) → ligne
  • Cascade — supprimer une ligne supprime sa page contenu (FK ON DELETE CASCADE, refs page_synced_blocks en cascade)
  • Exclusions des listings — AND collection_row_id IS NULL sur : arbre sidebar (_build_page_tree), racines workspace (_load_workspace_pages), liste des pages du board, projets builtins, arbre Library (_build_tree_children + API tree), page_count des workspaces ; parent_section='DbRow' les tient hors des sections Private/Trash

Résolution serveur + propagation (le point « production »)

  • Résolution à chaque lecture — resolve_content_json() (app/services/synced_blocks.py) appliqué sur : les 2 routes de rendu /pages/{id} (dashboard + board, dual-route), GET /api/pages/{id}/content, GET /api/local-workspace/page-content/{id}, page publique /p/{slug}, GET /api/v2/pages/{id}, et les rooms realtime (load_room) → le cache _synced_content périmé n'est plus jamais servi
  • Propagation écrite réelle — PUT /api/synced-blocks/{id} réécrit le contenu stocké de chaque page référente (sync_synced_blocks_in_page, jusqu'ici jamais appelé = code mort depuis v5.14.0) avant le broadcast WS ; récursif dans les children (colonnes, toggles)
  • Suppression de source — ids des pages référentes collectés avant la cascade FK, mark_synced_block_deleted() marque _synced_deleted dans le stocké, broadcast dédié manager._broadcast_synced_to()
  • État « deleted » — resolve_synced_block() marque _synced_deleted (source absente) ; rendu dédié dans l'éditeur (« Deleted synced block » au lieu d'un cache fantôme / « Loading… » éternel)
  • Rendu public des synced blocks — branche synced ajoutée à _render_blocks_public (avant : JSON brut en <p>) + état deleted
  • API v2 — content_page_id sur GET /api/v2/pages/{id} pour une ligne (sans création lazy en lecture)

Tests

  • tests/test_v65_synced_db.py — 17 tests (migration, création/idempotence/cascade/restauration de la page contenu, sync des titres, exclusions de listings, résolution lecture éditeur/content/public, propagation écrite + récursivité + deleted, synced block dans une ligne de DB de bout en bout, content_page_id v2)
  • Suite complète 742 verts (pytest -n auto) · ruff check app tests OK · eslint static/js 0 problème
  • Version — 6.5.0 (VERSION + app/main.py)

v6.0.0 — Pro (futur)

  • PWA — Progressive Web App, offline support ✅ (livré) — 📄 Conception détaillée
  • Granular permissions — page-level, property-level access control ✅ (livré v6.1.0) — 📄 Conception détaillée
  • Web Clipper — extension navigateur ✅ (livré v6.2.0/6.2.1) — 📄 Conception détaillée
  • API publique complète — REST API documentée (OpenAPI) ✅ (livré v6.3.0) — 📄 API Guide v2 · 📄 OpenAPI
  • SSO/SAML — enterprise authentication — 📄 Conception détaillée
  • Realtime editing (production) ✅ livré v6.4.0 (merge 3-voix au-delà du LWW, broadcast non bloquant) ; voir v5.13.0 pour le socle (curseurs + présence)
  • Synced blocks (production) ✅ livré v6.5.0 (page contenu par ligne de database, résolution serveur à chaque lecture, propagation écrite réelle, état deleted, rendu public) ; socle : v5.14.0 (bloc de base)

✅ Fonctionnalités livrées hors roadmap (bonus détectés dans le code)

Feature Fichiers Note
Webhooks sortants services/webhook_outbound.py, routers/workspace.py (/workspace/webhooks) CRUD + dispatch d'événements — base pour automations/API publique
API publique + tokens routers/public.py / public_api.py, test test_public_api_token À formaliser dans v5.2.0 et documenter pour v6.0.0

🎯 Ordre de priorité recommandé (état 2026-09)

  1. v5.2.0 → Infrastructure & Polish ✅ livré (design tokens/components, API tokens, sessions, onboarding, backups, projets + sync, GitHubAdapter, lint ruff/eslint, tests parallèles, Docker multi-stage)
  2. v5.0.0 → Command palette + FTS5 ✅ livré (palette Ctrl+K + GET /api/search)
  3. v5.3.0 → Inline databases + templates + validation ✅ livré (slash /database, 6 templates, validation propriétés)
  4. v5.13.0 → Realtime (WS + présence) ✅ livré (app/services/realtime_server.py + WS /ws/pages/{id}, présence, curseurs live, merge LWW, 12 tests)
  5. v5.10.0 → Interactions de bloc ✅ livré (drag&drop multi, undo/redo, duplicate, menu ⋮, en-têtes de tableau, 9 tests)
  6. v5.4.0 → Expérience éditeur ✅ livré (backlinks, page/collection duplicate, corbeille globale + purge 30 j, historique de version UI, import Markdown/CSV/Notion)
  7. v5.5.0 → Embeds & Média riche ✅ livré (embed universel 15 providers, bookmark cards OG, lightbox clavier, préviews PDF/vidéo/audio, cover & icône ; 47 tests dédiés)
  8. v5.6.0 → Import de données (6 phases) ✅ livré — Phase 0 socle unifié · Phase 1 notes/Markdown (Obsidian, Notion, Logseq/Roam, Apple Notes/Bear, Google Keep, OneNote) · Phase 2 données/tableaux (CSV typé, Excel, Sheets, JSON) · Phase 3 documents (Word, Google Docs, HTML, PDF) · Phase 4 signets/dev/divers (Gitea/GitHub, Raindrop, Pocket, Readwise, Shaarli, .ics, OPML, Standard Notes) · Phase 5 durcissement (re-sync, dépôt forge, URL/web clipper, lot multi-fichiers, relations Notion, rapports exportables)
  9. v5.7.0 → Database Avancée (Pt. 2) ✅ livré (person + auto-propriétés, groupes de propriétés, vues sauvegardées par utilisateur, swimlanes, WIP limits, cartes configurables, calendar drag & drop, gallery couvertures ; 12 tests dédiés)
  10. v5.8.0 → Calendrier & Rappels ✅ livré (vues jour/semaine/mois, récurrences RRULE expandues serveur, rappels in-app + email avec dédup, fuseaux par utilisateur/événement, notifications d'assignation, template Meeting notes enrichi ; 20 tests dédiés)
  11. v5.11.0 → Wiki-links & mentions de page ✅ livré (picker [[, mentions @ pages/date, chips atomiques, renommage propagé, backlinks wiki, chips en page publique)
  12. v5.12.0 → Templates & verrouillage de page ✅ livré (template picker global 5 built-in + templates perso, use-template, page lock 423, full-width, small text)
  13. v5.14.0 → v5.14.0 COMPLETED ✅ (synced blocks)

Résumé des phases

v0.x–v1.x ✅          v2.x ✅              v3.0.0 ✅       v4.0.0 ✅    v4.0.1 ✅
Base + Kanban         Éditeur + Gitea      UX Pro          MVP          Onboarding
+ DB + Auth           + Workspaces         + Multi-select  Accounts     & Polish
+ UI Notion           + Tags + Admin                       + Sharing    COMPLETED
                      + GitHub OAuth                       + Library

v4.0.2 ✅     v4.1–4.9 ✅     v4.10 ✅     v5.0–5.3 ✅     v5.13 ✅ · v5.10 ✅   v5.5 ✅ · v5.7 ✅   v5.14 ✅ · v6.0 ✅
Quality      DB views,      Agent IA     Palette →       Realtime +          Embeds &      Synced      PWA · Perms
& Tests      Templates &    COMPLETED    Automations     Interactions       Média riche   blocks      Clipper · API v2
             Collaboration               Realtime,      de bloc (undo/     (embed,       + DB
                                         DB avancée,    redo, drag&drop,   bookmark,     avancée
                                         Calendrier, AI duplicate)        lightbox…)    (Pt.2)      v6.1 ✅ v6.2 ✅ v6.3 ✅

*Dernière mise à jour: 2026-09-24 — **v6.6.0 Agent phase 5 : API publique agent & skill marketplace COMPLETED** (`/api/v2/agents/*` en Bearer+scopes avec run synchrone JSON + audit/undo, export/import de skills + galerie de 6 presets, entrée « Galerie » branchée dans la palette `/` du panneau, webhooks `agent.run.started`/`failed` enfin émis, OpenAPI régénéré 427 chemins ; 15 tests dédiés) + **v6.5.1** webhooks_v2 (749 verts) + **v6.5.0** synced blocks + **v6.4.0** realtime + **v6.3.0** API v2 → **suite 764 verts, 0 skip**. Les 5 phases du plan agent sont ✅. Reste: **SSO/SAML**.*