Aller au contenu principal

Architecture Workflows – État technique et propositions

Dernière mise à jour : 2026-02-28

Ce document décrit l’état actuel de la brique Workflows (post v2), les écarts avec la documentation existante, et des propositions d’amélioration.


1. Modèle de données actuel (post-migration 0173)

1.1 Tables principales

TableRôle
workflowsWorkflows unifiés (templates is_template=true sans owner_id, workflows utilisateur avec owner_id). Champs : name, description, is_published, forked_from_id, display_order.
workflow_phasesPhases d’un workflow. phase_type : CREATION, CONFIRMATION, DATE, CUSTOM. display_order pour l’ordre.
workflow_tasksTâches d’une phase. title, description, relative_days, relative_unit (HOURS, DAYS, WEEKS, MONTHS), is_manual, display_order. Pas de colonne action ni task_type : le type et l’action viennent des workflow_task_actions.
workflow_task_actionsActions attachées à une tâche (0-N). action_type : SEND_EMAIL, SEND_SMS, CLIENT_PORTAL_INVITE, SEND_NOTIFICATION, CREATE_REMINDER, WEBHOOK, ASSIGN_FORM, CHANGE_SESSION_STATUS, SEND_SESSION_INFO_INVITE. config (JSONB) : email_template_id, sms_template_id, action (ex. SESSION_NOTIFICATION:appointment-reminder-1w), etc. Voir SESSION_INFO_RENSEIGNEMENTS.md pour SEND_SESSION_INFO_INVITE.
workflow_triggersDéclencheurs d’un workflow. trigger_event (SESSION_CREATED, SESSION_STATUS_CHANGED, SESSION_INFO_SUBMITTED, CONTACT_CREATED, QUOTE_STATUS_CHANGED, INVOICE_STATUS_CHANGED, PAYMENT_RECEIVED, FORM_SUBMITTED, SCHEDULED), conditions (JSONB : `{ "operator": "AND"
workflow_trigger_executionsHistorique d’exécution des déclencheurs. entity_type (SESSION, CONTACT, QUOTE, INVOICE, FORM_SUBMISSION), entity_id, status (PENDING, EXECUTED, FAILED, SKIPPED). Contrainte unique (trigger_id, entity_type, entity_id).
session_workflow_instancesUne instance de workflow par session. session_id (unique), workflow_id, workflow_snapshot, status (ACTIVE, PAUSED, COMPLETED, CANCELLED).
session_workflow_task_runsExécution d’une tâche pour une instance. instance_id, task_id (référence workflow_tasks), phase_id, status (PENDING, SCHEDULED, COMPLETED, SKIPPED, FAILED), scheduled_at, executed_at, metadata (JSONB).
session_workflow_action_runsExécution d’une action pour un task run. task_run_id, action_id, action_type, status, result, error_message.

1.2 Tables legacy supprimées

Les anciennes tables user_workflows, user_workflow_phases, user_workflow_tasks, default_workflows, default_workflow_phases, default_workflow_tasks et session_workflow_tasks ont été supprimées par la migration 0173.

Le code runtime backend et les types Kysely ne les référencent plus. Si elles existent encore en base sur un environnement donné, elles doivent être traitées comme reliquats de schéma à supprimer, pas comme dépendances applicatives actives.

1.3 Conditions des triggers

  • Structure stockée et attendue par le code : \{ "operator": "AND" | "OR", "conditions": [ \{ "field": "...", "operator": "equals" | "contains" | ... , "value": ... \} ] \}.
  • La doc WORKFLOW_TRIGGERS.md utilise la même structure (conditions avec un tableau conditions). Pas d’imbrication de groupes (groupes de groupes).

2. Flux d’exécution

2.1 Déclenchement (triggers)

  • Sessions : SessionIntegrationService appelle WorkflowTriggersService.evaluateTriggersForEvent(triggerEvent, "SESSION", session.id, entityData, ownerId) après création ou mise à jour de session.
  • Contacts, devis, factures : ContactsService (CONTACT_CREATED), QuotesInvoicesQuotesCrudService (QUOTE_STATUS_CHANGED), QuotesInvoicesInvoicesCrudService (INVOICE_STATUS_CHANGED, PAYMENT_RECEIVED) ; évaluation et enregistrement, exécution workflow SKIPPED.
  • Renseignements soumis : SessionClientInfoService appelle evaluateTriggersForEvent("SESSION_INFO_SUBMITTED", "SESSION", sessionId, entityData, ownerId) après putClientInfo ou putClientInfoForClient (client ou back-office). Exécution : workflow appliqué à la session si conditions remplies.
  • Non implémenté : FORM_SUBMITTED, SCHEDULED (pas d'appel depuis les services concernés).

2.2 Création des tâches (task runs)

  • Après qu’un trigger a été exécuté, WorkflowTasksCreationService.createWorkflowTasksForSession(sessionId) est appelé.
  • Création/mise à jour de session_workflow_instances, puis création des session_workflow_task_runs à partir des workflow_tasks du workflow (phases CREATION toujours ; CONFIRMATION et DATE uniquement si session validée, sauf option onlyCreationPhase).
  • createNotificationTasksForSession est actuellement un no-op (« Notification tasks are now represented as workflow_task_actions in workflow v2 »). Aucun code ne crée de task runs dédiés aux rappels 1 semaine / 24 h / 1 h à partir de session_reminder_settings.

2.3 Exécution des tâches

  • Scheduler : WorkflowTasksScheduler (cron toutes les 5 min) récupère les task runs PENDING/SCHEDULED avec scheduled_at <= now, enfile des jobs addWorkflowTaskJob dans la queue.
  • Processor : le job est traité par le worker ; WorkflowTasksExecutionService exécute selon task_type (dérivé de la première workflow_task_action) :
    • TASK : marquage complété (manuel).
    • AUTOMATIC_EMAIL : si task.action?.startsWith("SESSION_NOTIFICATION:")executeNotificationEmailTask (utilise session_reminder_settings, template_key, destinataires) ; sinon → envoi email classique (template, config).
    • AUTOMATIC_SMS : envoi SMS (template utilisateur ou fallback config/action/description).

Pour que les rappels de session (1w, 24h, 1h) s’exécutent, il faudrait des session_workflow_task_runs dont la tâche liée a une action avec config.action = "SESSION_NOTIFICATION:appointment-reminder-1w" (etc.). Aujourd’hui, aucun workflow seedé (0173, 0175) ne crée de telles tâches, et createNotificationTasksForSession ne crée plus de runs. Donc les rappels basés sur session_reminder_settings ne sont pas créés pour les nouvelles sessions.


3. API et frontend (résumé)

  • Workflows : CRUD via WorkflowsController ; admin/defaults via WorkflowsAdminController (templates, création de defaults utilisateur).
  • Triggers : CRUD via WorkflowTriggersController sous /workflows/:workflowId/triggers.
  • Session : PUT /sessions/:id/apply-workflow pour attacher un workflow à une session ; réattachement et recréation des task runs.
  • Frontend : WorkflowFormPage (éditeur 2 colonnes : Flow à gauche, édition phase/tâches à droite), DefaultWorkflowsTab (Settings > Data > Workflows par défaut), pas de dry-run ni de drag & drop de réordonnancement dans l’éditeur.

4. Écarts documentation / code

DocÉcart
WORKFLOW_TRIGGERS.md« ContactsService, QuotesService, InvoicesService (à implémenter) » : correct, seul Sessions est branché. « SCHEDULED nécessite un scheduler dédié » : toujours vrai. Structure conditions : cohérente (operator + conditions).
WORKFLOW_VISUAL_EDITOR.mdGlobalement aligné (2 colonnes, pas de drag & drop, validation champs obligatoires, sous-tâches 1 niveau).
WORKFLOWS_REVIEW_PLAN.mdListe des fichiers : workflow-triggers.service.ts existe ; pas de session_workflow_tasks ni default_workflow_tasks (supprimés en 0173).
SESSION_NOTIFICATIONS_ARCHITECTURE.mdDocument historique archivé : décrit l’ancien modèle pré-v2. Ne plus l’utiliser comme source d’implémentation.
OpenAPI (RelativeUnit)workflows.yaml définit RelativeUnit avec HOURS, DAYS, MONTHS, YEARS. En base, la contrainte est HOURS, DAYS, WEEKS, MONTHS (pas YEARS, mais WEEKS). À aligner.

5. Propositions d’amélioration

5.1 Documentation

  1. Garder WORKFLOWS_ARCHITECTURE.md comme source active

    • Décrire ici le modèle v2 (workflows, phases, tasks, task_actions, session_workflow_instances, session_workflow_task_runs).
    • Indiquer que les rappels (1w, 24h, 1h) reposent sur une action avec config.action = "SESSION_NOTIFICATION:..." et sur user_metadata.session_reminder_settings.
    • Documenter le trou fonctionnel actuel : createNotificationTasksForSession est un no-op ; aucun workflow template ne contient les tâches SESSION_NOTIFICATION ; donc pas de création de rappels pour les nouvelles sessions tant qu’un mécanisme dédié n’est pas (re)implémenté.
  2. Aligner WORKFLOW_TRIGGERS.md

    • Préciser que seuls les événements session sont évalués (SESSION_CREATED, SESSION_STATUS_CHANGED).
    • Garder la section « Limitations » et « Améliorations futures » (contacts, quotes, invoices, SCHEDULED, conditions imbriquées).
  3. Mettre à jour WORKFLOWS_REVIEW_PLAN.md

    • Remplacer les références aux anciennes tables par le modèle 0173 (workflows, workflow_phases, workflow_tasks, workflow_task_actions, session_workflow_instances, session_workflow_task_runs).
    • Corriger la liste des fichiers cibles (pas de session_workflow_tasks).
  4. OpenAPI / schéma DB

    • Aligner RelativeUnit avec la base : soit ajouter WEEKS et retirer YEARS dans l’API, soit ajouter YEARS et WEEKS en base et exposer les deux.

5.2 Fonctionnel

  1. Rappels de session (notifications)

    • Option A : Réintroduire la création de task runs pour les rappels : à la création/mise à jour de session (et au changement de session_reminder_settings), créer des session_workflow_task_runs sans task_id (ou avec un task_id « virtuel ») et un metadata ou un champ dédié indiquant SESSION_NOTIFICATION:appointment-reminder-1w (etc.), avec scheduled_at calculé à partir de session.start_date et hours_before. Adapter le scheduler/execution pour accepter ces runs sans task_id en lisant metadata / action.
    • Option B : Créer un workflow template « Session Notifications » (ou par utilisateur) avec des tâches DATE et des actions SEND_NOTIFICATION dont config.action = "SESSION_NOTIFICATION:...", et un mécanisme qui attache ce workflow à chaque session (ou fusionne ses tâches avec le workflow métier) et appelle createWorkflowTasksForSession pour générer les runs.
    • Option C : Conserver un scheduler dédié aux rappels (comme avant v2) qui lit session_reminder_settings et envoie les emails sans passer par session_workflow_task_runs.
      Choisir une option et documenter le flux dans ce document.
  2. Triggers pour contacts / devis / factures

    • Brancher l’évaluation des triggers depuis les services concernés (ContactsService, QuotesService, InvoicesService, etc.) pour CONTACT_CREATED, QUOTE_STATUS_CHANGED, INVOICE_STATUS_CHANGED, PAYMENT_RECEIVED, avec les mêmes précautions (ownership, non-blocage).
  3. Déclencheurs SCHEDULED

    • Implémenter un scheduler (cron ou job) qui parcourt les triggers trigger_event = 'SCHEDULED', évalue schedule_config (cron ou relatif), et appelle l’exécution du workflow pour les entités concernées.

5.3 Observabilité et robustesse

  1. Vue exécutions par workflow

    • Exposer une vue ou un endpoint simple listant les exécutions récentes (trigger_executions + task_runs) par workflow, pour le debug et le suivi.
  2. Logs et métriques

    • Standardiser les logs avec workflowId, triggerId, taskId, sessionId où c’est pertinent ; ajouter des métriques (compteurs succès/échec, délais) pour les triggers et les task runs.
  3. Validation et garde-fous

    • Compléter les validations (phases/tâches optionnelles, champs obligatoires) côté API et frontend ; garder l’alignement DTO / schéma DB / types frontend.

6. Fichiers clés (référence)

RôleFichiers
Workflows CRUD / templatesworkflows.controller.ts, workflows-admin.controller.ts, workflow-crud.service.ts, workflow-phases.service.ts, workflow-template.service.ts, workflow-publish-validation.service.ts
Triggersworkflow-triggers.controller.ts, workflow-triggers.service.ts, condition-evaluator.helper.ts
Task actionsworkflow-task-actions.service.ts
Création / exécution task runsworkflow-tasks-creation.service.ts, workflow-tasks-execution.service.ts, workflow-tasks-query.service.ts, workflow-tasks-helpers.service.ts, workflow-tasks.service.ts, workflow-tasks.scheduler.ts
Intégration sessionsession-integration.service.ts (évaluation triggers + création workflow tasks)
Queueprocessors/workflow-tasks-processor.module.ts (ou équivalent)

7. Références

  • Migrations : 0173_workflow_v2_rework, 0174_workflow_v2_reset_data, 0175_workflow_v2_seed_templates, 0176_workflow_v2_update_session_type_defaults
  • Docs existants : WORKFLOW_TRIGGERS.md, WORKFLOW_VISUAL_EDITOR.md, WORKFLOWS_REVIEW_PLAN.md, archive/session-notifications-architecture.md
  • PRIORITES.md : section « 8.b Séquence validée » (workflows, lot 0, sprints)