Skip to content

BDD-119 — Rechargement de source API

1. User Story

En tant qu'administrateur, je veux pouvoir recharger une source créée depuis une API (formulaire ou fiche) afin de continuer à exploiter des données à jour sans avoir à recréer la source.

Ce ticket ajoute la capacité de recharger les données d'une source API avec une stratégie REPLACE (remplacement complet de la table), et permet de réattacher une source à une connexion différente si la connexion d'origine n'est plus disponible.

2. Critères d'acceptance

#CritèreStatut
1Un bouton « Recharger » est disponible sur la fiche d'une source API (type API_FORM ou API_CARD), activé uniquement si la connexion est ACTIVE
2Le rechargement exécute un REPLACE (suppression complète des lignes existantes + insertion des nouvelles) depuis la connexion et la ressource d'origine (formulaire ou fiche)
3Sur la fiche d'une source API dont la connexion est supprimée (soft-delete, deleted_at IS NOT NULL) ou en statut ERROR, un état explicite « Connexion indisponible » est affiché
4Quand la connexion est indisponible, le bouton « Recharger » est désactivé et la raison est affichée au survol (tooltip)
5Une action « Rattacher à une autre connexion » est disponible sur la fiche ; elle affiche un dialog de sélection avec une liste des connexions ACTIVE du type adéquat (ex. FORMULAIRES pour une source API_FORM)
6Dans le dialog de rattachement, après avoir choisi une nouvelle connexion, un sélecteur de ressource (formulaire ou fiche) est affiché, filtrable et triable comme en création
7Après validation du rattachement, la source est réassociée à la nouvelle connexion + nouvelle ressource ; le rechargement redevient possible
8En cas de succès du rechargement : notification avec le nombre de lignes importées (ex. « 1 234 lignes chargées »)
9En cas d'erreur durant le rechargement ou le rattachement : message d'erreur explicite, contenu de la table et association inchangés (atomicité garantie)
10Les sources fichier (DOCUMENT) conservent leur comportement de rechargement actuel (re-sélection de fichier + stratégies REPLACE / INSERT) — aucune régression

3. Périmètre fonctionnel

Backend — Rechargement et Rattachement

FichierRôle
back/src/api/sources/sources.service.tsAjout de reloadSource(uuid: string) : récupère la connexion + ressource, valide la connexion (ACTIVE), refetch les données, REPLACE (delete + insert atomique)
back/src/api/sources/sources.service.tsAjout de attachSourceToConnection(sourceUuid, connectionUuid, apiResourceUuid, apiResourceTitle) : réassociation + validation
back/src/api/sources/sources.controller.tsPATCH /sources/:uuid/reload — endpoint de rechargement ; retourne le nombre de lignes chargées et un message de succès
back/src/api/sources/sources.controller.tsPATCH /sources/:uuid/attach-connection — endpoint de rattachement ; valide les paramètres et retourne la source mise à jour
back/src/api/sources/source.presenter.tsAjout de connectionStatus (null | 'ACTIVE' | 'DELETED' | 'ERROR') dans le DTO source retourné au front
back/src/exceptions/source.exceptions.tsNouvelles exceptions : ConnectionUnavailableException, InvalidApiResourceException, ReloadFailedException
back/src/api/sources/sources.service.spec.tsTests : succès rechargement, erreur connexion indisponible, atomicité (rollback en cas d'erreur), réassociation valide + succès rechargement après
back/test/e2e/sources-controller.e2e-spec.tsE2E : rechargement API, rechargement quand connexion supprimée (403), rattachement (PATCH), rechargement post-rattachement

Frontend — Rechargement et Rattachement

FichierRôle
front/src/pages/admin/sources/AdminSourcePage.vueNouveau. Page affichant la fiche détaillée d'une source avec : nom, type, connexion, statut de connexion (badge « Connexion indisponible »), bouton « Recharger » (actif/inactif selon connexion), action « Rattacher » (lien / bouton dans un menu)
front/src/components/sources/SourceReloadDialog.vueNouveau. Dialog de confirmation avant rechargement, affichant la ressource (formulaire / fiche) à recharger. Soumission déclenche PATCH /sources/:uuid/reload
front/src/components/sources/SourceAttachConnectionDialog.vueNouveau. Dialog de sélection de connexion + ressource (formulaire ou fiche), parité avec la création. Soumission déclenche PATCH /sources/:uuid/attach-connection
front/src/stores/source-store.jsAjout de reloadSource(uuid) et attachSourceToConnection(sourceUuid, payload) ; gestion d'erreur + notification de succès
front/src/__tests__/pages/admin/sources/AdminSourcePage.spec.jsTests : affichage fiche source, état connexion indisponible + bouton recharger désactivé, dialog rattachement, succès et erreurs

4. Détail des fonctionnalités

A. Rechargement de source API

  • Endpoint : PATCH /sources/:uuid/reload

    • Authentification requise (admin ou propriétaire entreprise).
    • Validation : source doit être de type API_FORM ou API_CARD.
    • Validation : connexion associée doit être ACTIVE (statut non ERROR, deleted_at IS NULL).
    • Logique :
      1. Récupère la source et sa connexion.
      2. Fetch les données depuis la connexion d'origine (formulaire ou fiche).
      3. Supprime tous les SourceData de cette source (atomique).
      4. Insère les nouvelles lignes (normalisation des en-têtes et des dates appliquée, cf. [BDD-127]).
      5. En cas d'erreur à l'étape 3 ou 4, rollback complet (la table reste inchangée).
    • Réponse (200 OK) :
      json
      {
        "message": "Source rechargée avec succès",
        "rowCount": 1234
      }
    • Erreurs :
      • 404 : source inexistante.
      • 403 : connexion indisponible (supprimée ou en ERROR).
      • 500 : erreur lors du fetch ou de l'insertion (message sanitisé).
  • Frontend : bouton « Recharger » sur la fiche source

    • Actif uniquement si connectionStatus === 'ACTIVE'.
    • Clique → dialog de confirmation (SourceReloadDialog.vue).
    • Dialog : affiche la ressource à recharger (titre formulaire ou fiche).
    • Soumission → PATCH /sources/:uuid/reload → toast de succès avec nombre de lignes.

B. Rattachement de source à une autre connexion

  • Endpoint : PATCH /sources/:uuid/attach-connection

    • Authentification requise (admin ou propriétaire entreprise).
    • Validation : source doit être de type API_FORM ou API_CARD.
    • Payload :
      json
      {
        "connectionUuid": "<uuid>",
        "apiResourceUuid": "<uuid_formulaire ou uuid_fiche>",
        "apiResourceTitle": "Mon formulaire",
        "apiResourceType": "form" | "card"
      }
    • Logique :
      1. Valide la nouvelle connexion (doit être du type adéquat et ACTIVE).
      2. Valide la ressource (formulaire ou fiche) dans la nouvelle connexion.
      3. Met à jour les colonnes connectionUuid, formUuid / cardUuid, formTitle / cardTitle de la source.
      4. N'insère pas de nouvelles données (le rechargement est une étape suivante volontaire).
    • Réponse (200 OK) : la source mise à jour.
    • Erreurs :
      • 404 : source inexistante, connexion inexistante, ressource inexistante.
      • 400 : type de connexion incompatible, ressource non trouvée dans la connexion.
      • 403 : connexion non ACTIVE.
  • Frontend : dialog de rattachement (SourceAttachConnectionDialog.vue)

    • Accessible via un bouton « ⋮ Rattacher » dans le menu source, ou un lien « Rattacher » si connexion indisponible.
    • Dialog en deux étapes :
      1. Sélecteur de connexion (liste ACTIVE du type adéquat, filtrable).
      2. Sélecteur de ressource (formulaire ou fiche, triée).
    • Validation : les deux champs sont obligatoires.
    • Soumission → PATCH /sources/:uuid/attach-connection → toast de succès.

C. État de la connexion sur la fiche source

  • Nouveau champ connectionStatus dans le DTO source :
    • null : connexion normale / aucune info.
    • 'ACTIVE' : connexion opérationnelle.
    • 'DELETED' : connexion soft-deletée.
    • 'ERROR' : connexion en statut ERROR.
  • Affichage :
    • Connexion ACTIVE : affichage normal, bouton « Recharger » activé.
    • Connexion DELETED ou ERROR : badge rouge « ⚠️ Connexion indisponible », bouton « Recharger » désactivé (tooltip : raison).
  • Lien sur le nom de connexion (redirect vers /connections/:uuid pour édition/debug).

5. Règles métier implémentées

  • Atomicité du rechargement : si le fetch réussit mais l'insertion échoue, la source reste inchangée (no partial updates).
  • Validation stricte de connexion : une connexion supprimée ou en ERROR n'est jamais rechargeable ; elle est rattachable seulement vers une connexion ACTIVE.
  • Ressource immédiate : le rattachement ne recharge pas les données — l'utilisateur fait un rechargement volontaire après.
  • Pas de migration de données : le rechargement suit toujours la logique de normalisation d'en-têtes et de dates du ticket [BDD-127].
  • Logging : tout rechargement et rattachement est tracé avec userId, sourceUuid, connectionUuid, rowCount (succès) ou error code (échec).

6. Points de vérification

Rechargement de source API

  • Sur /sources/:uuid (fiche source) :
    • Connexion ACTIVE : bouton « Recharger » affiché et actif.
    • Connexion DELETED/ERROR : badge « Connexion indisponible » + bouton désactivé + tooltip explicite.
    • Clique sur « Recharger » → dialog affichant la ressource (ex. « Formulaire: Inscriptions 2026 »).
    • Validation → PATCH /sources/:uuid/reload appelé.
    • Succès (200) → toast « 1 234 lignes chargées ».
    • Erreur (403/500) → toast « Erreur : [message] ».

Rattachement de source

  • Sur la même fiche source :
    • Lien « ⋮ » menu → action « Rattacher à une autre connexion ».
    • Dialog : sélecteur de connexion (ACTIVE, type adéquat), puis sélecteur de ressource.
    • Super-admin : la liste des connexions est visible pour toutes les entreprises.
    • Validation → PATCH /sources/:uuid/attach-connection appelé.
    • Succès (200) → toast « Source rattachée ».
    • Retour à la fiche → bouton « Recharger » de nouveau actif (si nouvelle connexion ACTIVE).

Atomicité

  • Rechargement d'une source avec 100 lignes → erreur au milieu de l'insertion.
    • Base : la source garde ses 100 lignes originales.
    • Pas de doublons, pas de perte.

Pas de régression

  • Les sources fichier (DOCUMENT) continuent de fonctionner comme avant (sélection fichier + REPLACE / INSERT).

7. Tests associés

Backend (unitaires)

  • back/src/api/sources/sources.service.spec.ts :
    • reloadSource succès : fetch + REPLACE atomique, rowCount retourné.
    • reloadSource erreur connexion indisponible (deleted ou ERROR) : 403.
    • reloadSource erreur ressource : 400.
    • attachSourceToConnection succès : source réassociée, statut connexion mis à jour.
    • attachSourceToConnection erreur type incompatible : 400.
    • attachSourceToConnection erreur connexion non ACTIVE : 403.

Backend (e2e)

  • back/test/e2e/sources-controller.e2e-spec.ts :
    • Rechargement source API (formulaire) succès.
    • Rechargement source API (fiche) succès.
    • Rechargement avec connexion supprimée : 403.
    • Rechargement avec connexion ERROR : 403.
    • Rattachement à une nouvelle connexion succès.
    • Rattachement après succès, rechargement avec nouvelle connexion.

Frontend (unitaires)

  • front/src/__tests__/pages/admin/sources/AdminSourcePage.spec.js :
    • Affichage fiche source (connexion ACTIVE).
    • État connexion indisponible (badge + bouton désactivé).
    • Dialog rechargement : affiche ressource.
    • Dialog rattachement : sélecteur connexion + ressource.
    • Soumission rechargement (mock) → toast succès.
    • Soumission rattachement (mock) → toast succès.
    • Erreur rechargement : message d'erreur affiché.

Frontend (e2e Playwright)

  • front/e2e/pages/admin/admin-sources.spec.js :
    • Récupération fiche source (GET /sources/:uuid).
    • Clique « Recharger » → dialog confirmé → PATCH /sources/:uuid/reload appelé.
    • Succès rechargement : toast + nouvelle rowCount affichée.
    • Connexion supprimée : badge + bouton désactivé, dialog non appelé.
    • Clique « Rattacher » → dialog → sélection connexion + ressource → PATCH /sources/:uuid/attach-connection appelé.
    • Succès rattachement : toast + bouton « Recharger » réactivé.

8. Notes d'implémentation

  • Détection de connexion indisponible : vérifier deleted_at IS NOT NULL OU status = 'ERROR' au fetch de la source. Cacher proactivement le bouton rechargement côté front si connectionStatus !== 'ACTIVE'.
  • Normalisation cohérente : le rechargement applique la même normalisation d'en-têtes et de dates que [BDD-127]. Pas de nouvelle logique ici, réutilisation des utilitaires existants.
  • Logging obligatoire : chaque rechargement / rattachement doit logger userId, sourceUuid, connectionUuid, apiResourceType, résultat (rowCount ou error).
  • Hors scope (volontairement) :
    • édition manuelle d'une source après rechargement (structure des colonnes reste figée).
    • rechargement automatique / programmé (pas de cron ou trigger, seulement manuel).
    • historique des rechargements (pas de table source_reload_history).

9. Variables d'environnement

Aucune nouvelle variable. Les variables existantes (CONSOLE_ADMIN_API_URL, CONSOLE_ADMIN_API_KEY, etc.) restent suffisantes.