# Plan de migration — persistance workflows (JSON → SQLAlchemy) - `Date`: 2026-06-09 - `Auteur`: Claude (proposition, validation Dom requise) - `Statut`: PLANIFIÉ — **post-POC, aucun refactor engagé** - `Réf dette`: DETTE-015 (docs/DETTE_TECHNIQUE.md) - `Priorité`: P2 (fragilité réelle, contournée proprement pour le POC par symlink) ## Constat Trois stockages de workflows coexistent, sans source de vérité unique : | Store | Emplacement | Utilisé par | État | |-------|-------------|-------------|------| | Fichiers JSON | `visual_workflow_builder/backend/data/workflows/*.json` | route API VWB `/api/workflows/` (`api/workflows.py:53`, **relatif au cwd**) | **source réelle** (42 fichiers) | | DB SQLAlchemy | `…/backend/instance/workflows.db`, table `workflows` + Alembic | composants SQLAlchemy (`db.models`) | propre mais **pas lue par la route** (23 lignes) | | JSON legacy | `data/training/workflows/` | dashboard `web_dashboard` (`app.py:187-189`) | vide partout | ### Problèmes 1. **Pas de source unique** → divergences (les 42 JSON ≠ 23 lignes DB). 2. **Résolution par cwd** → le bug P0-1 du 2026-06-09 (dev cwd=backend OK ; DGX cwd=racine = 0 workflows). 3. Pas d'écriture atomique ni de validation de schéma côté JSON. 4. Confusion : 3 emplacements, dont un legacy mort. ## Cible **Unifier sur la DB SQLAlchemy déjà présente** (infra à moitié en place : table + Alembic). La route API lit/écrit la DB ; le store fichier JSON et le legacy sont retirés. Bénéfices : source unique, transactions, intégrité, requêtes, fin de la dépendance au cwd. > Note : un store fichier n'est pas disqualifiant en soi ; c'est la **coexistence non synchronisée** + la dépendance au cwd qui posent problème. On choisit SQLAlchemy car l'infra existe déjà (vs fiabiliser le JSON, qui laisserait le double store). ## Plan (TDD, post-POC, validation Dom entre étapes) 1. **Audit d'usage** : recenser tous les appels à `WorkflowDatabase` (lecture **et** écriture) — API, moteur d'exécution, agent, frontend VWB. Cartographier le contrat (méthodes `list/load/save/delete`). 2. **Repository SQLAlchemy** : implémenter un `WorkflowRepository` exposant le **même contrat** que `WorkflowDatabase`, adossé à la table `workflows` (réutiliser `db.models`). Tests unitaires CRUD. 3. **Script de migration** : importer les 42 JSON → table `workflows` (idempotent, backup DB avant). Vérifier parité (42 JSON ↔ N lignes, diff de contenu). 4. **Bascule de la route** derrière un flag (`RPA_WORKFLOWS_BACKEND=sqlalchemy|json`, défaut `json`) → tests d'équivalence API (mêmes réponses qu'avant). 5. **Bascule par défaut** sur SQLAlchemy une fois la parité prouvée ; retrait du symlink (DETTE-015). 6. **Nettoyage** : retirer le store legacy `data/training/workflows` (dashboard) ou le rebrancher sur le repository ; supprimer `WorkflowDatabase` quand plus aucun appelant. ## Préconditions / risques - **Ne pas engager avant la fin du POC** (refactor de persistance = risque pour la démo). - Touche frontend VWB + agent + moteur d'exécution → bascule progressive sous flag obligatoire. - Le symlink (DETTE-015) reste le contournement stable jusqu'à la migration. ## Effort estimé ~1,5–2,5 j en TDD (audit + repository + migration + tests d'équivalence + bascule).