Skip to content

Queue & Workers

Les requetes POST sont asynchrones : le client recoit un 202 { jobId } immediat et le traitement s'effectue en arriere-plan via BullMQ.

Architecture

Cycle de vie d'un job

Producer (enqueueJob)

Le producer fait deux choses en sequence :

  1. INSERT en PostgreSQL : stocke le job avec l'apiKey chiffree (AES-256-GCM) et les fichiers chiffres. C'est la source de verite.
  2. ADD dans BullMQ : ajoute le job dans Redis avec apiKey: undefined et files: undefined — les secrets ne transitent jamais par Redis.

Si l'ajout BullMQ echoue, le producer rollback le row PostgreSQL.

Idempotence

Si le client envoie un header Idempotency-Key, le jobId est derive de sha256(tenantHash + idempotencyKey). Le INSERT ON CONFLICT DO NOTHING detecte les doublons :

1er appel  → INSERT OK    → status: 'created'
2e appel   → INSERT NOOP  → status: 'duplicate', meme jobId

Worker

Le worker BullMQ dequeue les jobs et :

  1. Dechiffre l'apiKey et les fichiers depuis PostgreSQL
  2. Obtient un bearerToken OAuth2 (token manager)
  3. Execute le pipeline complet (10 etapes)
  4. Met a jour le status en DB (completed ou failed)
  5. Dispatche un webhook job.completed ou job.failed
  6. Purge les fichiers chiffres de la DB

Retry

ParametreValeur
Tentatives max3
BackoffExponentiel (1s, 2s, 4s)
Erreurs retryable429, timeout, 5xx
Erreurs non-retryable400, 403, 404, 422

Les erreurs non-retryable (OpcoviaError.retryable === false) sont converties en UnrecoverableError BullMQ pour eviter des retries inutiles.

Priorites

PrioriteValeur BullMQUsage
high1Requetes POST normales
normal5Default
low10Bulk sync, polling

Les POST clients passent toujours devant les sync et polls.

Types de jobs

TypeEndpointFormat
post-dossierPOST /dossiersJSON
post-facturePOST /facturesMultipart
post-conventionPOST /conventionsMultipart
post-certificatPOST /certificatsMultipart
post-documentPOST /documentsMultipart
sync-discoveryinterne-
sync-batchinterne-

Routes composites (multi-step)

Certaines routes OPCO necessitent plusieurs appels sequentiels (ex : creer un dossier complet = cerfa + convention + facture + certificat). Le composite-executor gere ces routes :

Le composite executor est reprise-safe : en cas de retry, il relit les stepResults en DB et saute les steps deja completes.

Flux de retry (erreur retryable)

Quand l'OPCO retourne une erreur retryable, BullMQ relance le job avec backoff exponentiel :

Flux composite avec retry partiel

Les routes composites enchainent plusieurs appels. En cas d'erreur sur une etape, seule cette etape est retentee :

Consultation du statut

Le client consulte le statut via GET /:opcoId/jobs/:jobId qui retourne le status, la progression (pour les composites), et le resultat une fois termine.