Skip to content

BDD-137 — Fix le rechargement d'une source type API référençant les fiches

1. User Story

En tant qu'administrateur, je veux recharger une source à partir d'une Fiche d'une connexion API (en plus des Formulaires), afin d'accéder aux données à jour.

Ce ticket est un correctif du rechargement des sources API [BDD-119] : aujourd'hui nous pouvons recharger une source dont l'origine API est typée comme un formulaire, mais pas comme une fiche, où le message d'erreur « Source ou fichier introuvable. » s'affiche.

2. Critères d'acceptance

#CritèreStatut
1Depuis /sources, depuis le rechargement d'une source API, je dois pouvoir aussi bien recharger les données d'un formulaire que les données d'une fiche

3. Périmètre fonctionnel

Backend — outil-bdd (Sources)

FichierRôle
back/prisma/schema.prismaNouveau. Enum ApiResourceType (form | card) + colonne sources.api_resource_type (nullable)
sql/tool_25_add_api_resource_type_to_sources.sqlNouveau. Migration SQL correspondante (CREATE TYPE + ADD COLUMN IF NOT EXISTS)
back/src/api/sources/sources.service.tsbuildApiFormSourceContext persiste désormais api_resource_type à la création ; reloadApiFormSource branche loadCardSubmissions ou loadFormResponses selon ce champ au lieu d'appeler systématiquement loadFormResponses
back/src/api/sources/sources.service.spec.tsTests création (assertion api_resource_type persisté) + nouveau test de rechargement d'une source fiche

Backend — formulaires (Export)

FichierRôle
back/src/export/export.service.tsbuildCardSubmissionsTable calculait un filtre where scopé à la fiche mais ne le transmettait jamais à submissionService.getSubmissions (qui reconstruit son propre where à partir de query.filters) — les soumissions de toutes les fiches de l'entreprise remontaient au lieu de celles de la fiche demandée. Ajout de card: { uuid } dans filters (même mécanisme que le chemin formulaire et que le front), suppression du where mort et des console.log de debug laissés en place

4. Détail des correctifs

A. Persistance du type de ressource API (formulaire vs fiche)

  • Avant : source_type valait toujours API_FORM, qu'il s'agisse d'un formulaire ou d'une fiche — l'UUID de la ressource atterrissait dans la même colonne form_uuid. Aucune trace du type d'origine n'était conservée après la création. Au rechargement, reloadApiFormSource appelait donc systématiquement connectionBrowse.loadFormResponses, qui renvoie 404 (ApiConnectionFormNotFoundException) quand l'UUID est en réalité celui d'une fiche.
  • Après : un champ dédié api_resource_type ('form' | 'card') est persisté à la création (buildApiFormSourceContext) et relu au rechargement pour choisir le bon appel (loadCardSubmissions vs loadFormResponses).
  • Alternative envisagée et écartée : ajouter une valeur API_CARD à l'enum SourceType, conformément à l'intention initiale de [BDD-119]. Écartée au profit d'un champ séparé car source_type répond à « d'où viennent les données » (document / API / workflow) alors que api_resource_type répond à « quelle ressource API précisément » — deux axes distincts. Un nouveau source_type aurait aussi obligé à élargir tous les tests sourceType === 'API_FORM' déjà présents côté front (SourceReloadDialog.vue, SourceListItem.vue, WorkflowHeriadeSourcePanel.vue), qui restent valides tels quels avec un champ séparé.
  • Sources historiques : les sources fiche créées avant ce correctif ont api_resource_type = NULL, traité comme 'form' par le code (comportement identique à avant, aucune régression). Elles resteront en échec au rechargement tant qu'elles ne sont pas recréées — aucun backfill n'a été fait, la perte de ces quelques sources est acceptée.

B. Filtrage manquant sur l'export des soumissions d'une fiche (formulaires)

  • Découvert pendant la vérification manuelle du correctif A : une fois le rechargement d'une fiche débloqué, les données remontées mélangeaient les soumissions de plusieurs fiches.
  • Cause : buildCardSubmissionsTable vérifiait que la fiche existait puis appelait submissionService.getSubmissions(user, { where, filters: { ...filterQuery } })where était calculé mais jamais utilisé (getSubmissions reconstruit son propre where uniquement à partir de query.filters), et filters ne contenait aucune référence à la fiche demandée.
  • Correctif : filters: { ...filterQuery, card: { uuid } }, à l'identique du chemin formulaire (filters: { ...filterQuery, form: { uuid, type: 'general' } }) et du front, qui utilise déjà cette forme (SubmissionCardPage.vue : { card: { uuid: cardId } }).
  • Effet de bord positif : ce mélange de données inter-fiches provoquait aussi un plantage non maîtrisé au rechargement côté outil-bdd (normalizeNumericValue de decimal.js levant une erreur brute sur une valeur texte injectée dans une colonne inférée number), puisqu'une colonne majoritairement numérique récupérait occasionnellement une valeur texte issue d'une fiche différente.

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

  • Le rechargement d'une source API_FORM lit api_resource_type (traité comme 'form' si absent) pour choisir l'appel externe adéquat.
  • attachConnection (rattachement à une autre connexion) n'a pas été modifié : source_type reste API_FORM dans tous les cas, le filtre de recherche de la source n'avait donc pas besoin d'évoluer ; api_resource_type n'est pas touché par ce flux.
  • L'export/rechargement d'une fiche est désormais strictement scopé à la fiche demandée côté formulaires.

6. Points de vérification

  • Créer une source depuis une Fiche → api_resource_type vaut card en base.
  • Recharger cette source → succès (plus de « Source ou fichier introuvable. »), et les données rechargées appartiennent uniquement à la fiche d'origine (plus de mélange inter-fiches).
  • Recharger une source Formulaire existante → comportement inchangé (loadFormResponses).
  • Une source fiche créée avant ce correctif (api_resource_type NULL) → comportement inchangé (tentative via loadFormResponses, échoue toujours ; à recréer si besoin).

7. Tests associés

Backend outil-bdd (unitaires)

  • back/src/api/sources/sources.service.spec.ts :
    • persistance de api_resource_type: 'form' / 'card' à la création (formulaire et fiche) ;
    • nouveau test de rechargement : une source api_resource_type: 'card' appelle loadCardSubmissions et n'appelle jamais loadFormResponses.
    • 74 tests, tous verts.

Backend outil-bdd (e2e)

  • back/test/e2e/sources-controller.e2e-spec.tsnon modifié. La suite existante sur /reload et /attach-connection ne couvre que les cas guard / validation / 404 (aucun scénario n'y crée ni ne recharge une vraie source API_FORM, ce qui nécessiterait de mocker l'appel externe Formulaires — hors périmètre de la suite actuelle). Le correctif ne change aucun de ces comportements.

Backend formulaires

  • Pas de test ajouté : ExportService / SubmissionService n'ont aucune couverture de test existante dans ce dépôt (seul app.controller.spec.ts généré par défaut), donc pas de convention à suivre. Correctif vérifié manuellement.

8. Notes d'implémentation

  • Hors scope (volontairement) :
    • garde validateTypedColumns manquante dans reloadApiFormSource (présente dans createSource mais jamais portée au rechargement API) — un type de colonne inféré à tort peut toujours faire planter normalizeNumericValue avec une erreur brute non catchée. Générique aux deux types de ressource, pas spécifique fiche/formulaire, identifié mais non corrigé dans ce ticket ;
    • libellés front (SourceListItem.vue, SourceReloadDialog.vue) distinguant visuellement « Formulaire » et « Fiche » — sourceType reste API_FORM pour les deux, ces libellés ne sont donc pas cassés, seulement pas différenciés davantage qu'avant ;
    • rattachement (attachConnection) d'une source fiche vers une nouvelle ressource fiche explicite — le DTO n'accepte que formUuid, limitation déjà existante avant ce ticket.

9. Variables d'environnement

Aucune nouvelle variable.