Skip to content

Profils OPCO ​

Qu'est-ce qu'un profil ? ​

Un profil est une description declarative de la maniere dont l'API d'un OPCO differe du schema normalise Opcovia. Chaque OPCO a ses particularites : fautes de frappe dans les enums, formats de date differents, champs obligatoires supplementaires, wrappers autour des reponses, etc.

Au lieu d'ecrire un adapter TypeScript par OPCO, on declare un profil avec le DSL. Le profil est un ensemble de routes, chacune associant un endpoint Opcovia a un endpoint upstream avec ses transforms.

Pourquoi des profils ? ​

Chaque OPCO expose une API differente. Exemples de divergences reelles :

ProblemeExemple OPCO EP
Typos dans les enumsRUTPURE au lieu de RUPTURE
Format de date non standardISO datetime au lieu de YYYY-MM-DD
Noms en majuscules exigesapprenti.nom doit etre uppercase
Crash sur nullL'API plante si un champ est null
Reponse non pagineeArray brut au lieu d'un objet pagine
Durees en stringHeures/minutes attendues comme string, pas number

Le profil absorbe ces differences. Le code metier ne les voit jamais.

Architecture ​

                        Profil OPCO
                     ┌──────────────────┐
                     │  defineProfile()  │
                     │  ├── route GET    │
                     │  ├── route POST   │
                     │  └── ...          │
                     └──────────────────┘
                              │
                              ▼
                       ProfileAdapter
                      (implements OpcoAdapter)

Flux request ​

Corps JSON client
       │
       ▼
  requestOps[]          t.transform('nom', cleanName)
  (appliques            t.stripNulls()
   sequentiellement)
       │
       ▼
  Corps JSON OPCO  →  envoi a l'API upstream

Flux response ​

Reponse JSON OPCO
       │
       ▼
  responseOps[]         t.mapDeep('etat', corrections)
  (appliques            t.editData(normaliserPagination)
   sequentiellement)
       │
       ▼
  Reponse normalisee  →  renvoyee au client

Pipeline de transformation DSL ​

Concepts cles ​

defineRoute ​

Definit une route simple : un endpoint Opcovia mappe a un endpoint upstream.

typescript
defineRoute('/dossiers', 'POST', {
  dest: '/v1/dossiers',
  cacheTtl: 600,
  rateLimit: { maxPerMinute: 60 },
  requestTransform: (t) => { /* ops sur la requete */ },
  responseTransform: (t) => { /* ops sur la reponse */ },
})

defineCompositeRoute ​

Definit une route composite : plusieurs appels upstream enchaines, avec passage de donnees entre etapes via t.next() / t.previous().

defineProfile ​

Assemble les routes en un profil complet.

typescript
defineProfile('opco-ep', {
  sync: { batchSize: 50 },
  poll: { intervalMs: 300_000 },
  routes: [routeGet, routePost, ...],
})

FieldTransform (t.xxx()) ​

Transforms chainables et immutables sur une valeur. Stockables dans des variables pour reutilisation.

typescript
const cleanName = t.trim().uppercase()
// reutilisable sur N champs
t.transform('apprenti.nom', cleanName)
t.transform('apprenti.prenom', cleanName)

Structure des fichiers ​

profiles/
  field-transform.ts     — FieldTransform chainable + factory t
  dsl.ts                 — defineRoute, defineProfile, TransformBuilder
  engine.ts              — applyOps() execute les operations
  adapter.ts             — ProfileAdapter implements OpcoAdapter
  types.ts               — Op, RouteDefinition, ProfileDefinition
  opco-ep/               — 1 fichier par route
  opco-mock/             — profil mock pour les tests
  __tests__/             — tests unitaires et integration

Voir aussi ​