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 :
- INSERT en PostgreSQL : stocke le job avec l'apiKey chiffree (AES-256-GCM) et les fichiers chiffres. C'est la source de verite.
- ADD dans BullMQ : ajoute le job dans Redis avec
apiKey: undefinedetfiles: 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 jobIdWorker
Le worker BullMQ dequeue les jobs et :
- Dechiffre l'
apiKeyet les fichiers depuis PostgreSQL - Obtient un
bearerTokenOAuth2 (token manager) - Execute le pipeline complet (10 etapes)
- Met a jour le status en DB (
completedoufailed) - Dispatche un webhook
job.completedoujob.failed - Purge les fichiers chiffres de la DB
Retry
| Parametre | Valeur |
|---|---|
| Tentatives max | 3 |
| Backoff | Exponentiel (1s, 2s, 4s) |
| Erreurs retryable | 429, timeout, 5xx |
| Erreurs non-retryable | 400, 403, 404, 422 |
Les erreurs non-retryable (OpcoviaError.retryable === false) sont converties en UnrecoverableError BullMQ pour eviter des retries inutiles.
Priorites
| Priorite | Valeur BullMQ | Usage |
|---|---|---|
high | 1 | Requetes POST normales |
normal | 5 | Default |
low | 10 | Bulk sync, polling |
Les POST clients passent toujours devant les sync et polls.
Types de jobs
| Type | Endpoint | Format |
|---|---|---|
post-dossier | POST /dossiers | JSON |
post-facture | POST /factures | Multipart |
post-convention | POST /conventions | Multipart |
post-certificat | POST /certificats | Multipart |
post-document | POST /documents | Multipart |
sync-discovery | interne | - |
sync-batch | interne | - |
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.