2026-05-10 · 12 min · Architecture

Connecter Cegid Loop à Supabase en streaming.

Comment on a connecté un logiciel comptable propriétaire à une base PostgreSQL moderne sans tomber dans les pièges classiques.

Quand on a démarré NHS Finances en début 2025, l'enjeu était clair : donner à la direction d'un groupe hôtelier une vision consolidée temps réel de 5 sociétés dont les données comptables vivaient dans Cegid Loop. Sur le papier, c'est un problème classique d'ETL. En pratique, ça nous a pris plusieurs itérations pour trouver la bonne architecture.

Le problème de départ

Cegid Loop expose bien une API REST, mais avec quelques particularités :

La première version naïve était une fonction serverless classique sur Vercel. Elle a tenu 3 jours avant de péter sur la limite de mémoire de 1 Go.

Quand on traite 8000 lignes en mémoire avant de pousser en base, on tape vite dans le mur sur du serverless.

Bascule vers Supabase Edge Functions

On a migré sur les Edge Functions Supabase (basées sur Deno) pour deux raisons :

  1. Proximité avec la base : les Edge Functions tournent dans la même région que Postgres, latence négligeable
  2. Support natif du streaming : Deno gère nativement les ReadableStream et les Server-Sent Events

Architecture finale

L'architecture qu'on a fini par retenir tient en 3 couches :

1. Authentification mutualisée

Plutôt qu'un OAuth par utilisateur, on a une table cegid_urls qui stocke les credentials chiffrés pour chaque société. L'Edge Function s'authentifie côté serveur, le frontend ne voit jamais les tokens.

2. Streaming SSE

L'Edge Function "smooth-api" lit la réponse Cegid en streaming, parse ligne par ligne, et émet des événements SSE vers le frontend. Trois bénéfices :

3. RLS dynamique côté Postgres

Les permissions sont gérées au niveau Postgres via Row Level Security. Une table permissions_role définit ce que chaque rôle peut voir (RAF voit tout, économe ne voit que son périmètre). Aucune logique de droits côté frontend : impossible de "bypasser".

Les pièges qu'on a évités

Piège 1 : faire confiance au timeout Cegid

Cegid peut mettre 30 secondes à répondre sur les gros payloads. La doc dit 10 secondes max — c'est faux. On retry avec un timeout de 60s et un backoff exponentiel.

Piège 2 : parser le JSON en une seule passe

JSON.parse charge tout en mémoire. On utilise un parser streaming (oboe.js équivalent en Deno) qui émet des événements à chaque objet rencontré dans le tableau.

Piège 3 : oublier la dédup

Si l'utilisateur relance une sync en cours, on peut se retrouver avec des doublons. Solution : un lock applicatif via une table sync_locks avec timeout automatique.

Le résultat

Aujourd'hui, une sync complète sur les 5 sociétés prend 4,2 secondes en moyenne, traite environ 8740 lignes, et n'a jamais hit la memory limit depuis qu'on est en production. Le frontend affiche une barre de progression en temps réel, et les utilisateurs ont l'impression que c'est instantané.


Si vous travaillez sur un projet similaire et que vous voulez en discuter, écrivez-nous. On adore parler d'ETL avec d'autres devs.