- manifest + icones, service worker (precache, network-first, Background Sync)
- module client FlowOffline (IndexedDB, queue, delta, flush) + hook editeur
- endpoints /api/v2/sync/{delta,batch,status} + moteur de sync (conflits LWW/orpheline/copie offline)
- migrations offline_sync_queue + sync_version (triggers)
- UI offline (banner, badge sync, toasts, icone dirty) + doc /help
- tests pytest (sync, migrations, SW, offline) + E2E Playwright; bump 6.0.0
772 lines
56 KiB
Markdown
772 lines
56 KiB
Markdown
# 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** :
|
||
```bash
|
||
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
|
||
- [x] FastAPI lifespan (deprecation fix)
|
||
- [x] 28 tests — 5 vues, filtres, tris, APIs, CSRF, CORS, DB
|
||
- [x] CI/CD Gitea Actions (`.gitea/workflows/ci.yml`)
|
||
- [x] CHANGELOG.md, ARCHITECTURE.md à jour
|
||
- [x] Version 1.0.0 partout (main.py, api.py, health)
|
||
- [x] Tag git v1.0.0
|
||
|
||
### v1.1.0 ✅ — Pages & Sidebar
|
||
- [x] Pages Markdown avec arbre imbriqué (parent_id, sort_order)
|
||
- [x] Block editor mode (content_format='blocks', JSON storage)
|
||
- [x] Soft delete → Trash → Restore → Permanent delete
|
||
- [x] Drag & drop réorganisation pages
|
||
- [x] Sidebar Notion-style avec sections Recents/Private/Shared
|
||
- [x] "+ New page" footer button
|
||
- [x] Workspace header avec avatar + chevron toggle
|
||
|
||
### v1.2.0 ✅ — Éditeur Notion
|
||
- [x] Slash menu (/) 15 commandes fonctionnelles
|
||
- [x] Navigation clavier (flèches, Enter, Escape)
|
||
- [x] Placeholders Notion-style (Heading 1/2/3/4, Toggle, Quote, Code)
|
||
- [x] Suppression outline blanc sur les blocs
|
||
- [x] Heading 4 support
|
||
- [x] Breadcrumbs contextuels (workspace > projet > page)
|
||
|
||
### v1.3.0 ✅ — Database Concept
|
||
- [x] Tables `collections`, `collection_pages`, `collection_views`
|
||
- [x] Rétrocompatibilité Gitea via `GiteaBoardCompat`
|
||
- [x] Router `/db` — API CRUD collections + pages (12 endpoints)
|
||
- [x] 34/34 tests passent
|
||
|
||
### v1.4.0 ✅ — Propriétés Avancées
|
||
- [x] Table `collection_properties` — 21 types Notion
|
||
- [x] Service `property_types.py` — validation, formatage, auto-values
|
||
- [x] 38/38 tests passent
|
||
|
||
### v1.5.0 ✅ — Relations & Rollups
|
||
- [x] Type `relation` — lien bidirectionnel entre collections
|
||
- [x] Type `rollup` — aggregation via relation (COUNT, SUM, AVG, etc.)
|
||
- [x] Type `formula` — moteur d'expressions (19 fonctions)
|
||
- [x] Formula engine + Rollup engine
|
||
- [x] 43/43 tests passent
|
||
|
||
### v1.6.0 ✅ — Vues Manquantes
|
||
- [x] Calendar, Gallery, List, Timeline, Table views
|
||
- [x] View tabs navigation
|
||
- [x] 49/49 tests passent
|
||
|
||
### v1.7.0 ✅ — Vues Améliorées
|
||
### v1.8.0 ✅ — Sub-items & Dépendances
|
||
- [x] View config API, Save view as
|
||
- [x] Sub-items (parent_id auto-référence)
|
||
- [x] Status aggregate, Dependencies (blocking constraint)
|
||
- [x] 56/56 tests passent
|
||
|
||
### v1.9.0 ✅ — My Tasks & Dashboard Unifié
|
||
- [x] Vue `/my-tasks` — agrège pages assignées à l'utilisateur
|
||
- [x] Groupement par collection, filtres globaux
|
||
- [x] 60/60 tests passent
|
||
|
||
### v2.0.0 ✅ — Éditeur Complet & Multi-Utilisateurs
|
||
- [x] Workspaces, Comments, Page History, Favorites
|
||
- [x] Database Templates, Page Templates, CSV Import/Export
|
||
- [x] Public Sharing
|
||
- [x] 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
|
||
- [x] Créer fichiers dans le repo (New file UI + API PUT)
|
||
- [x] Upload fichiers binaires (POST /upload, drag-drop)
|
||
- [x] Syntax highlighting via Prism.js CDN
|
||
- [x] Labels Gitea → tags FlowDeck (POST /sync-labels, 16 labels importés)
|
||
- [x] Historique commits par fichier (GET /commits?path=)
|
||
|
||
### v2.9.0 ✅ — GitHub OAuth Provider
|
||
- [x] GitHubProvider dans `app/auth/providers.py`
|
||
- [x] GitHubAdapter dans `app/services/github_adapter.py`
|
||
- [x] Config GitHub dans `.env.example`
|
||
|
||
### v3.0.0 ✅ — UX Professionnelle
|
||
- [x] Multi-sélection (checkboxes + Shift/Ctrl-click dans le sidebar)
|
||
- [x] Raccourcis clavier (Ctrl+N, F2, Delete, Escape, Ctrl+S)
|
||
- [x] Inline rename (double-clic → champ inline)
|
||
- [x] Loading skeletons (animations pulse dans workspaces + file viewer)
|
||
- [x] Grid/card view (mode grille/vignettes)
|
||
- [x] Table sorting (tri par colonnes)
|
||
- [x] Sélecteur de vue: Tree, List, Details, Title, Content (5 modes)
|
||
- [x] Preview Panel latéral (contenu, métadonnées, tags, actions)
|
||
- [x] Tri par date (Oldest/Newest)
|
||
|
||
### v4.0.0 ✅ — Accounts, Integrations & Sharing (MVP)
|
||
- [x] `auth_method` sur users (local/gitea/github)
|
||
- [x] Badge OAuth dans sidebar
|
||
- [x] Settings page avec Connect/Disconnect Gitea + GitHub
|
||
- [x] Sidebar rules (Private = distant seulement, Trash local-only)
|
||
- [x] Library page avec tabs + filtres source (All/Local/Gitea/GitHub)
|
||
- [x] Modale Share (2 tabs: Share + Publish)
|
||
- [x] Page publique `/p/<slug>` (no auth, rendu HTML)
|
||
- [x] Table `page_shares`, colonnes `is_published`, `is_shared`, `share_mode`
|
||
- [x] Table `recents` — tracking automatique
|
||
- [x] Édition unifiée local/distant (même UI, bouton Commit pour Gitea)
|
||
- [x] 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**.
|
||
|
||
- [x] **Landing page `/` pour visiteurs non-auth** — template `landing.html`, design Notion dark
|
||
- [x] **Page `/auth/register` GET** — formulaire d'inscription dédié (tab register actif)
|
||
- [x] **Redirection `/` intelligente** — non-auth → landing, auth sans Gitea → local workspace, auth+Gitea → dashboard
|
||
- [x] **Empty states** — déjà présents dans local workspace (« Welcome to your Workspace »)
|
||
- [x] **Page 404 stylisée** — thème Notion sombre, JSON pour `/api/*`, HTML pour le reste
|
||
- [x] **Unifier les routes API** — `/api/pages` GET/POST → 307 redirect vers `/board/api/pages`
|
||
- [x] **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.
|
||
|
||
- [x] **Gestion d'erreurs** — try/catch dans create_page, message user-friendly (500 JSON)
|
||
- [x] **Validation inputs** — login/register déjà validés, titre vide → "Untitled"
|
||
- [x] **Rate limiting** — 100 req/min/IP déjà en place, testé OK
|
||
- [x] **Session expiry UX** — redirect avec ?expired=1, bannière sur la page login
|
||
- [x] **CSRF token refresh** — auto-refresh sur 403, endpoint `/api/csrf-token`
|
||
- [x] **Mobile responsive** — sidebar slide-in, modales centrées, landing adaptative
|
||
- [x] **Tests de non-régression** — +10 tests (landing, register, 404, validation, duplicate, expiry)
|
||
- [x] **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](docs/NOTION_DATABASE_TASKS_GUIDE.md#14-plan-implémentation)
|
||
|
||
- [x] **Table `collection_data_sources`** — multi-sources par collection (FK `collection_id` + `source_collection_id`, flag `is_linked`)
|
||
- [x] **API sources** — `GET /db/{id}/sources/api` (liste), `POST /db/{id}/sources/api` (ajouter), `DELETE /db/{id}/sources/{sid}/api` (retirer)
|
||
- [x] **API linked DB** — `POST /db/{id}/linked/api` (crée une collection liée : copie vues + propriétés + data source `is_linked=1`)
|
||
- [x] **Full-page vs Inline** — `POST /db/{id}/toggle-inline/api` (toggle), `POST /db/inline/api` (créer inline avec `parent_page_id`)
|
||
- [x] **Règle permissions** — linked DB hérite du `workspace_id` de la source → mêmes ACLs
|
||
- [x] **Migration** — ajout colonnes `workspace_id`, `created_by` sur `collections`
|
||
- [x] **153 tests passent** (+10 nouveaux)
|
||
|
||
### v4.2.0 — Database: Templates & Dashboards ✅ (2026-07-21)
|
||
> **Objectif** : Templates réutilisables + dashboards combinant vues/widgets. **COMPLETED**.
|
||
|
||
- [x] **Table `page_templates` enrichie** — colonnes `description`, `is_recurring`, `recurrence_rule` (daily/weekly/monthly/yearly)
|
||
- [x] **Table `collection_dashboards`** — layout widgets (grille configurable : `columns`, `widgets` avec `view_id`, `x`, `y`, `width`, `height`)
|
||
- [x] **API templates CRUD complet** — `PUT /workspace/collections/{id}/templates/page/{tid}` (update), `DELETE` (delete)
|
||
- [x] **API dashboards CRUD** — `GET/POST/PUT/DELETE /workspace/collections/{id}/dashboards`
|
||
- [x] **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**.
|
||
|
||
- [x] **Chart** — barres, courbes, camemberts, donuts, scatter (Chart.js CDN)
|
||
- [x] **Form** — formulaire HTML auto-généré depuis les propriétés → POST création page
|
||
- [x] **Map** — Leaflet/OSM pour propriété Place (lat,lng parsing)
|
||
- [x] **Feed** — vue chronologique type fil d'actualité (newest first)
|
||
- [x] **Timeline/Gantt** — barres horizontales avec group_by et plages de dates
|
||
- [x] **View tabs** — 11 onglets de navigation (table, board, calendar, gallery, list, timeline, gantt, chart, form, map, feed)
|
||
- [x] **Layout options** — card_size, chart_type, group_by, place_property via config_json
|
||
- [x] **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**.
|
||
|
||
- [x] **Flag `is_task`** sur collections — PUT /db/{id}/toggle-task/api (Turn into Tasks)
|
||
- [x] **Table `page_dependencies`** — bloque/bloqué par/related avec auto_shift
|
||
- [x] **API dependencies** — GET/POST/DELETE /db/{c}/pages/{p}/dependencies/api
|
||
- [x] **Auto-shift dates** — POST /db/{c}/pages/{p}/auto-shift/api (skip_weekends option)
|
||
- [x] **171 tests passent** (+5 nouveaux)
|
||
|
||
### v4.5.0 — Sprints & My Tasks ✅ (2026-07-21)
|
||
> **Objectif** : Sprints agiles + vue My Tasks cross-databases. **COMPLETED**.
|
||
|
||
- [x] **Tables `sprints`, `sprint_pages`** — sprints agiles avec velocity_points
|
||
- [x] **API sprints** — CRUD + assignation/retrait pages
|
||
- [x] **Burndown chart** — GET /workspace/collections/{id}/sprints/burndown/{sid} (total/completed/remaining/ideal)
|
||
- [x] **My Tasks** — agrégation cross-databases avec filtre (all/today/overdue/upcoming)
|
||
- [x] **175 tests passent** (+4 nouveaux)
|
||
|
||
### v4.6.0 — Content Blocks enrichis ✅ (2026-09-02)
|
||
> **Objectif** : parité d'édition avec Notion.
|
||
|
||
- [x] **Callout blocks** — boîtes colorées avec sélecteur d'emoji/icône
|
||
- [x] **Table of contents** — auto-généré depuis les headings avec ancres
|
||
- [x] **Math equations** — LaTeX / KaTeX (self-hosted) block
|
||
- [x] **Toggle lists** — contenu expandable/collapsible avec enfants
|
||
- [x] **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.
|
||
|
||
- [x] **Export Markdown** — avec images et sous-pages (récursif)
|
||
- [x] **Export PDF** — via xhtml2pdf (fidèle, sans CDN/lib système)
|
||
- [x] **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)
|
||
- [x] **Share / More / Activity / Move-to popovers** — rendus sous le viewport (absolute + parent scrollable) → repositionnés fixed sous la topbar
|
||
- [x] **Sous-menu Export** — l'itém Export fermait le menu More ; devient un toggle, formats accessibles
|
||
- [x] **Cache CSS** — query string app.css bumpé v4.7.1
|
||
- [x] Vérifié Playwright headless + 190/190 tests
|
||
|
||
### v4.7.2 — Fix Export : contenu absent ✅ (2026-09-03)
|
||
- [x] **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.
|
||
- [x] 5 nouveaux tests → 195/195 ; vérifié sur les vraies données
|
||
|
||
### v4.7.3 — Fix export PDF/HTML : tableaux + émojis ✅ (2026-09-03)
|
||
- [x] **Tableaux** — parseur GFM (bloc `table`) + rendu `<table>` HTML (thead/tbody, alignements, bordures `.ftable`) dans les exports HTML/PDF ; roundtrip markdown pipe valide.
|
||
- [x] **É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).
|
||
- [x] Dockerfile : libs pango/harfbuzz/gdk-pixbuf + polices ; requirements : + weasyprint==69.0
|
||
- [x] 4 nouveaux tests → 199/199 ; PDF README.md vérifié : tableau structuré + émojis colorés
|
||
|
||
### v4.8.0 — Bloc Tableau simple ✅ (2026-09-03)
|
||
- [x] **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.
|
||
- [x] **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.
|
||
- [x] **Colonnes** — poignée (⋮⋮) au-dessus de chaque colonne → Insérer à gauche/droite, Dupliquer, Effacer le contenu, Supprimer la colonne, Supprimer le tableau.
|
||
- [x] **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)
|
||
- [x] **« + Row » (bas) corrigé** — l'insertion de ligne utilisait `splice(index, ligne)` (mauvaise signature) → aucune ligne ajoutée ; désormais `splice(index, 0, ligne)`.
|
||
- [x] **Bouton « + » à droite** — ajoute une colonne à droite (équivalent « Add column »).
|
||
- [x] **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`](docs/Guide_Complet_Notion_sharing_collaborartion.md)
|
||
|
||
- [x] **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
|
||
- [x] **@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)
|
||
- [x] **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
|
||
- [x] **Centre de notifications in-app** — cloche topbar (badge non-lus, polling 30s), panneau déroulant, mark as read / mark all read
|
||
- [x] **Settings** — toggles réels dans Settings → Notifications (Commentaires / Mentions)
|
||
- [x] **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`](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`](docs/Flowdeck_Agent_integration.md) (702 lignes) ·
|
||
[`docs/Guide_Complet_Notion_Agent_2026.md`](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
|
||
- [x] **Interface conversationnelle** — panneau agent dans le sidebar (🤖 Agents) + popup chat
|
||
- [x] **Boucle ReAct** — Raisonnement → Action → Observation → itération (max 12 tours)
|
||
- [x] **Streaming SSE** — affichage temps réel du raisonnement et des actions
|
||
- [x] **10+ outils actionnables** — search, read/write collections/pages, views, properties, Gitea sync
|
||
- [x] **Permissions** — même ACL que l'utilisateur (`PermissionManager`), audit log + rollback
|
||
- [x] **Contexte automatique** — workspace actif, pages mentionnées, fichiers uploadés
|
||
- [x] **Custom agents** — instructions, modèle, outils, scope par agent
|
||
- [x] **Déclencheurs** — planifiés, webhooks, événements workspace
|
||
- [x] **Skills réutilisables** — templates d'instructions + outils (ex: "Rédiger rapport hebdo")
|
||
- [x] **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** : 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** : 7 outils supplémentaires (views, properties, Gitea, uploads)
|
||
4. **Phase 4 — Autonomie** : custom agents, skills, déclencheurs planifiés
|
||
5. **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+P` palette de commandes universelle + recherche full-text. **COMPLETED**.
|
||
|
||
- [x] **Command palette** — Ctrl+K / Ctrl+P recherche universelle (modale, fuzzy, navigation clavier)
|
||
- [x] **Quick actions** — navigation, création, commandes
|
||
- [x] **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**.
|
||
|
||
- [x] **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
|
||
- [x] **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
|
||
- [x] Hooks événements dans collections.py / board.py / workspace.py (apply_page_template)
|
||
- [x] **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**
|
||
- [x] **Design tokens** — `static/css/design-tokens.css` (couleurs, espacements, typo, ombres, z-index) chargé après `app.css`
|
||
- [x] **Composants réutilisables** — `static/css/components.css` (btn/input/modal/dropdown/toast/card/badge/empty/table)
|
||
|
||
**Sécurité & Utilisateur**
|
||
- [x] **API Tokens** — générer/lister/révoquer dans Settings → API tokens (`app/routers/security.py`, table `api_tokens`, bearer `/api/v1`)
|
||
- [x] **Sessions actives** — liste + révocation (`user_sessions`, `SessionManager.list_sessions/revoke_session`)
|
||
- [x] **Onboarding wizard** — `/welcome` (workspace → forge → premier projet) + `welcome.html`
|
||
|
||
**Infrastructure**
|
||
- [x] **🥇 Migrations versionnées** — table `schema_version` + runner `app/migrations.py` (baseline v1, indexes v2, FTS5 v3)
|
||
- [x] **Backup automatique** — snapshot SQLite quotidien (`app/services/backup.py`, scheduler + API admin, rétention configurable)
|
||
- [x] **Index manquants** — `users.email`, `user_oauth_tokens(user_id, provider)`, `collections/pages(workspace_id)`, `pages(deleted_at)`
|
||
- [x] **Linting** — ruff (Python, `pyproject.toml`) + eslint flat (`eslint.config.mjs`) ; `ruff check` et `eslint` sans erreur
|
||
- [x] **Tests parallèles** — pytest-xdist (`pytest -n auto` en local et en CI ; DB + dossier backup isolés par test)
|
||
- [x] **Build Docker multi-stage** — builder + runtime (libs WeasyPrint), image allégée
|
||
|
||
**Forge integration**
|
||
- [x] **DB: table `projects`** — type (builtin/gitea/github), forge_id, clone_url, default_branch, language
|
||
- [x] **Cron: sync périodique des projets** — `project_sync_scheduler` (défaut : chaque heure)
|
||
- [x] **GitHubAdapter** complet — API GitHub v3 → interface `ForgeAdapter`
|
||
|
||
**Tests (cibles)**
|
||
- [x] **397 tests** — dont backups, projets, adapters forge (mock HTTP), OAuth (mock), multi-user ✅
|
||
- [x] Tests d'intégration auth (OAuth mock) — login/callback Gitea + GitHub, mode `link`, rejet d'état invalide
|
||
- [x] Tests des adapters forge (mock HTTP) — `GitHubAdapter` via `httpx.MockTransport`
|
||
- [x] 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**.
|
||
|
||
- [x] **Inline databases dans n'importe quelle page** — slash command `/database` (groupe DATA) → sélecteur de templates → bloc `embed_type:'collection'` rendu par `FlowDeckDB`
|
||
- [x] **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
|
||
- [x] **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**.
|
||
|
||
- [x] **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`)
|
||
- [x] **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
|
||
- [x] **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…)
|
||
- [x] **Duplicate block** — `Ctrl+D`, menu bloc ou slash command « Duplicate » ; copie profonde (enfants columns/toggle) en multi-sélection
|
||
- [x] **Slash command étendue** — groupe « Actions » : Turn into, Duplicate, Copy link to block, Delete block
|
||
- [x] **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
|
||
- [x] **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).
|
||
|
||
- [x] **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
|
||
- [x] **Présence** — avatars des utilisateurs connectés (topbar), couleur par utilisateur, join/leave broadcasté ; `welcome` = self + peers
|
||
- [x] **Curseurs live** — position curseur/sélection des autres éditeurs (block + offset), calque dédié, label avec nom, mise à jour à l'édition/au scroll
|
||
- [x] **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
|
||
- [x] **Fallback polling** — si WS indisponible, rafraîchissement diff toutes les 10 s (adopté seulement sans brouillon local) + reconnexion automatique
|
||
- [x] 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**.
|
||
|
||
- [x] **Backlinks** — `GET /board/api/pages/{id}/backlinks` (scan des liens internes `/pages/<id>`) + popover « Lié depuis… »
|
||
- [x] **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 `...`
|
||
- [x] **Corbeille globale améliorée** — vue cross-workspace `GET /board/api/trash` + `app/services/trash.py` (purge automatique > 30 jours, scheduler quotidien)
|
||
- [x] **Historique de version UI** — snapshots `page_versions` à chaque sauvegarde modifiée, `GET /api/pages/{id}/versions`, `POST .../versions/{vid}/restore`, popover « Version history »
|
||
- [x] **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`
|
||
- [x] **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**.
|
||
|
||
- [x] **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…
|
||
- [x] **Bookmark cards** — aperçu riche des URLs (métadonnées OG : titre, image, description, site, favicon)
|
||
- [x] **Image lightbox** — clic pour agrandir, navigation clavier (←/→) + plein écran dans l'éditeur **et** les pages publiques
|
||
- [x] **Previews inline** — PDF, vidéo, audio rendus directement dans la page
|
||
- [x] **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.
|
||
- [x] **Service `app/services/importers/`** — interface commune (`detect()`, `parse()`, `to_pages()`) + résultat normalisé (`ImportResult` : pages, pièces jointes, warnings, stats)
|
||
- [x] **Pipeline commun** — upload → parse → normalisation blocs + métadonnées → création (pages + hiérarchie `parent_id`) → rapport d'import
|
||
- [x] **Pièces jointes** — extraction (images/fichiers), upload, réécriture des liens dans les blocs
|
||
- [x] **Frontmatter YAML → propriétés** (title, tags, dates, champs custom)
|
||
- [x] **Assistant UI d'import** — choix de la source, mapping colonnes→types, preview/dry-run, barre de progression
|
||
- [x] **Import asynchrone** (job en arrière-plan + polling) pour les gros volumes (vaults, zips)
|
||
- [x] **Idempotence / déduplication** + reprise sur erreur partielle
|
||
- [x] **Tests** — harnais d'import + fixtures par source
|
||
- [x] **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 ✅
|
||
- [x] **Obsidian** (vault `.zip`/dossier) — frontmatter YAML, `[[wikilinks]]`, `![[embeds]]`, attachments, hiérarchie de dossiers *(prépare v5.11.0)*
|
||
- [x] **Notion** (améliorer l'existant) — hiérarchie complète, databases (CSV) → collections, images
|
||
- [x] **Logseq / Roam Research** — markdown outliné (puces imbriquées), `((block refs))`, pages journal
|
||
- [x] **Apple Notes / Bear / Ulysses** — import export HTML/Markdown
|
||
- [x] **Google Keep** — Takeout JSON + HTML
|
||
- [x] **OneNote** — export HTML/PDF, best-effort (fidélité limitée)
|
||
|
||
#### Phase 2 — Données & tableaux (fort ROI databases) — effort faible/moyen ✅
|
||
- [x] **CSV/TSV typé** — inférence auto (texte/nombre/date/bool/select/multi_select) + UI mapping + options
|
||
- [x] **Excel `.xlsx`** (openpyxl) — multi-feuilles → collections
|
||
- [x] **Google Sheets** — export CSV/XLSX
|
||
- [x] **JSON générique** — mapping configurable (JSONPath → propriétés)
|
||
|
||
#### Phase 3 — Documents & bureautique — effort moyen ✅
|
||
- [x] **Word `.docx`** (mammoth/pandoc) — titres, listes, tableaux, images
|
||
- [x] **Google Docs** — Takeout `.docx`/HTML
|
||
- [x] **HTML** (fichiers/dossier, web clipper) — conversion HTML → blocs
|
||
- [x] **PDF** — extraction texte + images (fidélité limitée)
|
||
|
||
#### Phase 4 — Signets, dev & divers ✅
|
||
- [x] **Gitea / GitHub issues + labels + milestones** → collection (via API — quasi natif)
|
||
- [x] **Raindrop.io** (CSV/HTML) → bookmark cards (réutilise v5.5.0)
|
||
- [x] **Pocket** (CSV/HTML)
|
||
- [x] **Readwise** (highlights CSV/Markdown)
|
||
- [x] **Shaarli** (API/export JSON) → bookmark cards
|
||
- [x] **Calendrier `.ics`** (Google/Outlook/Apple)
|
||
- [x] **OPML** (flux/outlines)
|
||
- [x] **Standard Notes / autres**
|
||
|
||
#### Phase 5 — Durcissement & finition ✅
|
||
> **Objectif** : industrialiser l'import (ré-import, lots, URL, forge, relations, rapports).
|
||
- [x] **Import incrémental / re-sync** — modes `skip` / `update` (upsert des pages + lignes par titre) / `duplicate`, via `import_items`
|
||
- [x] **Import de dépôt forge** — arborescence de fichiers Gitea/GitHub → pages (hiérarchie de dossiers, fichiers texte, code en blocs)
|
||
- [x] **Import par URL / web clipper** — `POST /api/import/url` : fetch (garde SSRF) + OG metadata → page (carte bookmark + contenu)
|
||
- [x] **Lot multi-fichiers + file d'attente** — `POST /api/import/run-batch` + file d'attente UI (statut par fichier)
|
||
- [x] **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
|
||
- [x] **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)
|
||
- [x] **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**.
|
||
|
||
- [x] **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
|
||
- [x] **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`
|
||
- [x] **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
|
||
- [x] **Swimlanes Kanban** — `sub_group_by` (2e dimension de groupement) : une rangée de colonnes par lane
|
||
- [x] **WIP limits** — `wip_limits` par colonne, alerte visuelle au dépassement (`wip-exceeded`)
|
||
- [x] **Cartes configurables** — `card_properties`, `card_size` (compact/détaillé), couverture `cover_mode` (`none`/`icon`/`color`/`property`) via `cover_property`
|
||
- [x] **Calendar avec drag & drop** — grille mensuelle, `date_property`, navigation mois/Today, drop d'une carte sur un jour = reschedule
|
||
- [x] **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**.
|
||
|
||
- [x] **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
|
||
- [x] **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)
|
||
- [x] **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
|
||
- [x] **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
|
||
- [x] **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`)
|
||
- [x] **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**.
|
||
|
||
- [x] **Slash AI commands** — groupe « AI » dans le menu `/` : Write with AI, Summarize, Translate, Continue writing (`E.aiSlash`)
|
||
- [x] **Autocomplétion** — module `AIAC` : suggestion courte après ~900 ms d'inactivité, pastille « Tab » ancrée au bloc, insertion au `Tab`, rejet à `Escape`
|
||
- [x] **AI properties** — bouton ✨ par ligne de la table database : `POST /api/agent/writing/properties` propose Status/Priority/Résumé et applique les valeurs
|
||
- [x] **Service** `app/services/ai_writing.py` — 6 actions sans outils, replis déterministes hors-ligne
|
||
- [x] **Endpoints** — `POST /api/agent/writing` + `POST /api/agent/writing/properties`
|
||
- [x] **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**.
|
||
|
||
- [x] **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)
|
||
- [x] **Mention de page `@`** — le menu `@` (utilisateurs v4.9.0) gagne la section « Pages » : `@nom` cherche les pages et insère le chip inline
|
||
- [x] **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 »)
|
||
- [x] **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 »
|
||
- [x] 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**.
|
||
|
||
- [x] **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`)
|
||
- [x] **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
|
||
- [x] **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
|
||
- [x] **Full-width mode** — toggle dans le menu « … », persisté par page (`pages.full_width`), `POST /board/api/pages/{id}/options`, classe CSS `.full-width`
|
||
- [x] **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**.
|
||
|
||
- [x] **Bloc `synced_block`** — table `synced_blocks` (source de vérité) + références par page ; slash command `/synced`
|
||
- [x] **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)
|
||
- [x] **Unsync** — action « Unsync » qui convertit l'instance en copie indépendante
|
||
- [x] **Copy & sync across pages** — copier un bloc dans une autre page avec option « Paste and sync »
|
||
|
||
---
|
||
|
||
## 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**.
|
||
|
||
- [x] **Manifest & icônes PWA** — `static/manifest.json`, `static/icons/*`, `scripts/generate_pwa_icons.py`
|
||
- [x] **Service Worker** — `static/sw.js` (precache shell, network-first HTML/API, page offline, Background Sync)
|
||
- [x] **IndexedDB client** — `static/js/offline.js` (`window.FlowOffline`) : queue, delta, flush, marqueurs dirty
|
||
- [x] **Endpoints sync** — `app/routers/sync.py` + `app/services/sync_engine.py` (`/api/v2/sync/delta|batch|status`)
|
||
- [x] **Migrations** — table `offline_sync_queue` + colonnes `sync_version` (triggers AFTER UPDATE)
|
||
- [x] **Conflits** — edit-edit (last-write-wins), edit-delete (page orpheline), create-create (« copie offline »)
|
||
- [x] **UI** — banner offline + pending count, badge de synchronisation, toasts, icône ⟳ sur pages dirty
|
||
- [x] **Durcissement** — max 100 mutations/batch, timeout 30 s, rétention queue 30 j
|
||
- [x] **Tests** — `test_sync.py`, `test_sync_migrations.py`, `test_service_worker.py`, `test_pwa_offline.py`, E2E `e2e/pwa_offline.spec.js`
|
||
- [x] **Doc** — section `/help` « Offline mode (PWA) »
|
||
|
||
---
|
||
|
||
## v6.0.0 — Pro (futur)
|
||
|
||
- [x] **PWA** — Progressive Web App, offline support ✅ (livré) — [📄 Conception détaillée](/docs/V6_PWA_Progressive_Web_App.md)
|
||
- [ ] **SSO/SAML** — enterprise authentication — [📄 Conception détaillée](/docs/V6_SSO_SAML_Enterprise_Auth.md)
|
||
- [ ] **Granular permissions** — page-level, property-level access control — [📄 Conception détaillée](/docs/V6_Granular_Permissions.md)
|
||
- [ ] **Web Clipper** — extension navigateur — [📄 Conception détaillée](/docs/V6_Web_Clipper.md)
|
||
- [ ] **API publique complète** — REST API documentée (OpenAPI) — [📄 API Guide v2](/docs/API_GUIDE_V6.md) · [📄 Référence des features v6](/docs/API_GUIDE_V6.md#11-documents-de-conception-détaillée-v600)
|
||
- [ ] **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)
|
||
|
||
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 Pro + Agent
|
||
& Tests Templates & COMPLETED Automations Interactions Média riche blocks
|
||
Collaboration Realtime, de bloc (undo/ (embed, + DB
|
||
DB avancée, redo, drag&drop, bookmark, avancée
|
||
Calendrier, AI duplicate) lightbox…) (Pt.2)
|
||
|
||
*Dernière mise à jour: 2026-09-18 — **v6.0.0 PWA (offline support) COMPLETED** (manifest, service worker, IndexedDB, sync `/api/v2/sync/*`, conflits, UI offline, tests + E2E). Reste: v6.0.0 Pro (SSO/SAML, permissions granulaires, Web Clipper, API publique, realtime production)*
|