65 KiB
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 automatiquedevelop: branche d'intégration, merges desfeat/*feat/<nom>: une branche par feature/fix, PR → code review → merge dansdevelop- Tags
vX.Y.Zsurmainpour 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_methodsur 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, colonnesis_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 — templatelanding.html, design Notion dark - Page
/auth/registerGET — 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/pagesGET/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.mdPhase 1
- Table
collection_data_sources— multi-sources par collection (FKcollection_id+source_collection_id, flagis_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 sourceis_linked=1) - Full-page vs Inline —
POST /db/{id}/toggle-inline/api(toggle),POST /db/inline/api(créer inline avecparent_page_id) - Règle permissions — linked DB hérite du
workspace_idde la source → mêmes ACLs - Migration — ajout colonnes
workspace_id,created_bysurcollections - 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_templatesenrichie — colonnesdescription,is_recurring,recurrence_rule(daily/weekly/monthly/yearly) - Table
collection_dashboards— layout widgets (grille configurable :columns,widgetsavecview_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_tasksur 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 pagesfile(upload.md/code, contenu sur disque) etmarkdownsortaient 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
+ Rowsous 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) —
md2btransforme les tableaux pipe en bloctableau lieu de les aplatir en paragraphes ; roundtrip Markdown (JS + export) et sortie MD/HTML/PDF correcte d'un bloctable.
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ésormaissplice(index, 0, ligne). - Bouton « + » à droite — ajoute une colonne à droite (équivalent « Add column »).
- Redimensionnement des colonnes — curseur
col-resizeau survol des bordures d'en-tête, drag = largeur ; persisté viacolsW.
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@logindans les blocs et commentaires, tablenotifications; endpointPOST /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, … viaPATCHconversation),/runutilise 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)
- Phase 1 — Core Agent : AgentEngine + LLMClient + 3 outils (search, read, create) + SSE streaming
- Phase 2 — UI : agent_panel.html, historique conversations, sélecteur de modèle ✅ (v4.10.1)
- Phase 3 — Outils avancés : 7 outils supplémentaires (views, properties, Gitea, uploads)
- Phase 4 — Autonomie : custom agents, skills, déclencheurs planifiés
- Phase 5 — Plateforme : 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+Ppalette 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
- Déclencheurs : événement (
- Buttons — boutons cliquables déclenchant des actions
- Bloc
buttondans l'éditeur (menu slash) + picker d'automation inline - Endpoint
/api/automations/{id}/run(exempt CSRF) + UI Settings → Automations
- Bloc
- 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èsapp.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, tableapi_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+ runnerapp/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 checketeslintsans erreur - Tests parallèles — pytest-xdist (
pytest -n autoen 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) —
GitHubAdapterviahttpx.MockTransport - Tests multi-user (permissions croisées) —
PermissionManagerowner/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 passedruff check app tests→ All checks passed! ·eslint static/js→ 0 problème- CI Gitea (commit
ba363ea; run push #1412 + PR #15 run #1413) → success surpushetpull_request: jobslint(≈43 s),test(-n auto, ≈4 min),dockermulti-stage (≈1 min) - Docker : stages
builder+runtimevérifiés par le job CIdocker(from app.main import appOK)
Complétion du 2026-09-11 :
- Isolation des tests corrigée :
tests/conftest.pymute le singletonsettings(au lieu de le remplacer), sinon les modules ayant importésettingsau 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 aussiwebhook_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 → blocembed_type:'collection'rendu parFlowDeckDB - 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/apiacceptenttemplateet 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_headerdéfaut actif + nouveaufirst_col_header), persistés + rendu<th>en preview et exports Markdown/HTML - Intégration realtime —
syncNow()poussé après chaque mutation programmatique ; 9 teststests/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 teststests/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 collectionsPOST /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(); endpointPOST /board/api/embed/resolve - Service
app/services/og_fetcher.py: parseur OG robuste (ordre d'attributs libre), favicon, repli sans réseau ; endpointPOST /board/api/og/metadata - Endpoints
POST/DELETE /board/api/pages/{id}/cover(JSON URL ou upload image) etPOST /board/api/pages/{id}/icon - Éditeur : résolution d'embed à la saisie (URL d'origine conservée +
embed_srcmis 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/bookmarkavecembed_srcré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 checkOK
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, viaimport_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ésrelation(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, listeerrors) ; 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_bycâblés : auto-valeurs calculées serveur (apply_auto_properties) à la création/mise à jour, sélecteurperson(membres du workspace viaGET /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) etPOST /db/{id}/property-groups/api - Vues sauvegardées par utilisateur —
collection_views.created_by;GET /db/{id}/views/apifiltre par propriétaire (les vues partagéesNULLrestent 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_limitspar colonne, alerte visuelle au dépassement (wip-exceeded) - Cartes configurables —
card_properties,card_size(compact/détaillé), couverturecover_mode(none/icon/color/property) viacover_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(), validationpersoncollections.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,viewsexposées danstable-dataet le contexte de page_database_table_scripts.htmlréé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 checkOK
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/apiavec 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 dansproperty_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 viaGET /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édupreminder_log, notifie les personnes assignées (repli admin), in-app + email (prefreminders) ; stockés dansproperty_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 parnotify_assignment()surPUT /db/pages/{id}/api(comparaison avant/après des propriétésperson) - Template Meeting Notes — propriétés
AgendaetNotesajouté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 checkOK - 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 auTab, rejet àEscape - AI properties — bouton ✨ par ligne de la table database :
POST /api/agent/writing/propertiespropose 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)
v5.11.0 — Wiki-links & mentions de page ✅ (2026-09-14)
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) ; moduleWMdans_page_editor_scripts.html; tokens[[fdpage:ID]]stockés dans le texte des blocs et relus intacts pargtTok()(autosave, drag, undo/redo préservés) - Mention de page
@— le menu@(utilisateurs v4.9.0) gagne la section « Pages » :@nomcherche les pages et insère le chip inline - Mention de date
@— section « Date » :@today,@tomorrow,@hierou@YYYY-MM-DDinsè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/titlesré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_publicrend les chips en page publiée (HTML échappé) ; serviceapp/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_templatesexistent (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 parcreated_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 surPUT /api/pages/{id}etPOST /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— tablesynced_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-Signaturesur 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) - 21 tests
tests/test_webhooks_v2.py(HMAC, retries, événements, intégration)
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+ colonnessync_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, E2Ee2e/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_permissionsrole 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}/apimasqué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/apifiltré parget_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 pargroup_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, auditGET /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 colonnespermission_type+ indexes (idempotent) - Tests —
tests/test_v60_granular_permissions.py21 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.zipservi à/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 → tokenfd_…montré une fois),GET /devices,DELETE /devices/{id}+ page HTMLGET /extensions; auth triple (session OU Bearerapi_tokensOU Bearerextension_devicesOU legacyuser_tokens), rate-limit 50/h/device - Tables migration 19 —
extension_devices,extension_clips+ indexidx_ext_* - Settings UI — onglet Extensions (devices, clips count, revoke)
- 16 tests
tests/test_web_clipper.py;VERSION6.2.0 ; wiringapp/main.py:50,158
v6.2.1 — Web Clipper polish ✅ (2026-09-20)
- Bouton flottant rond transparent draggable — toggle d'affichage persistant,
clipper:clippedrefresh auto sidebar - Fix bloc bookmark —
create_page_from_clip()émet un blocbookmarkfidèle (OG +embed_srcrésolu), rendu/correct en éditeur +/p/<slug>+ exports - Fix
duplicate innerSyntaxError dans_page_editor_scripts.html flowdeck-clipper.zipré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érarchiquesread < 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: colonnesscopes 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_atapi_audit_log:id, user_id, token_id, action, resource_type, resource_id, ip, created_atidempotency_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-keyaccepté seulement siTrue(dev local)app/services/api_v2_helpers.py:parse_pagination()(+X-Total-Count),to_iso8601(), handler RFC 7807application/problem+json,require_scope()(hiérarchieadmin ⊇ 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_tokenssupportés) ; handler d'erreurs unifié surStarletteHTTPException
Phase 3 — Tokens CRUD v2 ✅
POST /api/v2/tokens(name, scopes, expires_at) →fd_{urlsafe(32)}hashé, montré une foisGET /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", tagapi-v2) —GET /collections,GET /collections/{id},GET /pages/{id},GET /collections/{id}/pages?filter[]=&sort=&fields=&query=,GET /search?query=&workspace_id=&type=(FTS5), headerX-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) : signature HMAC
X-FlowDeck-Signature, retry 2s/10s/60s, +20 events
Phase 7 — Forges & ressources restantes ✅
- Sprints, dashboards, templates, export/import, workspaces/members, users, admin
- Forges :
GET /projects,/projects/{owner}/{repo}/tree(best-effort viagitea_client) - (reporté) : migration de
sync.pyvers Bearer (reste session, CSRF-exempt)
Phase 8 — OpenAPI, tests & docs ✅
docs_url="/docs"+redoc_url="/redoc"activés ;docs/openapi-v2.jsongé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.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) — voir v5.13.0 (curseurs + présence déjà avancés ici) ; reste en v6 : conflits avancés, édition large échelle
- Synced blocks (production) — voir v5.14.0 (bloc de base) ; reste en v6 : syncing côté databases/vues
✅ 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)
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)v5.0.0 → Command palette + FTS5✅ livré (palette Ctrl+K +GET /api/search)v5.3.0 → Inline databases + templates + validation✅ livré (slash/database, 6 templates, validation propriétés)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)v5.10.0 → Interactions de bloc✅ livré (drag&drop multi, undo/redo, duplicate, menu ⋮, en-têtes de tableau, 9 tests)v5.4.0 → Expérience éditeur✅ livré (backlinks, page/collection duplicate, corbeille globale + purge 30 j, historique de version UI, import Markdown/CSV/Notion)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)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)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)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)v5.11.0 → Wiki-links & mentions de page✅ livré (picker[[, mentions@pages/date, chips atomiques, renommage propagé, backlinks wiki, chips en page publique)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)- 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-21 — **v6.3.0 API publique complète v2 COMPLETED** (~100 endpoints `/api/v2`, scopes hiérarchiques `read<write<admin`, RFC 7807, idempotence, audit, webhooks CRUD, OpenAPI 402 chemins, 24 tests, suite 668 verte) + **v6.2.1 Web Clipper COMPLETED**. Reste: SSO/SAML, realtime production, synced blocks prod, webhooks HMAC/retry.*