vendorData
Chaque réponse peut inclure des objets vendorData (au niveau réponse, patient ou appointment). La borne ne les lit jamais : elle mémorise chacun sous l'id de l'entité qui le porte, et le renvoie inchangé sur les appels suivants visant cette entité.
Principe du round-trip
Vous posez un objet opaque sur une entité de votre réponse — ici un sur le patient, un sur le RDV :
{
"patients": [
{
"patient": {
"id": "pat-77",
"firstName": "Marie", "lastName": "Durand",
"vendorData": { "patientKey": 77, "shard": "eu-1" }
},
"appointments": [
{
"id": "apt-1001", "examLabel": "IRM lombaire",
"vendorData": { "appointmentKey": 1001 }
}
]
}
]
}La borne le restitue tel quel dans context.vendorData des appels suivants qui visent la même entité :
PATCH /patients/pat-77
{
"context": {
"locationId": "loc-42",
"vendorData": { "patientKey": 77, "shard": "eu-1" } // ← celui de pat-77, tel quel
},
"patient": { "mobilePhone": "+33612345678" }
}La clé : vos propres ids
Il n'y a pas de « clé de session » à définir : la clé de mémorisation est l'id contrat de l'entité, c'est-à-dire le patient.id ou l'appointment.id que vous avez renvoyé. La borne tient une table id d'entité → vendorData : quand une réponse porte un vendorData sur pat-77, elle enregistre (ou remplace) l'entrée pat-77 ; quand elle appelle une route qui concerne pat-77, elle joint cette entrée — et uniquement celle-là.
Le contenu de l'objet est entièrement libre et défini par vous (ids de base internes, clé de partition, jeton…) : la borne ne l'interprète jamais, elle ne fait que le ranger sous votre id et le ressortir.
Quel vendorData sur quel appel
POST /patients/identify— jamais devendorData: c'est le premier appel, la borne n'a encore rien à restituer ;PATCH /patients/{patientId}— levendorDatadu patient visé ;- toutes les routes
/appointments/{appointmentId}/…(documents, upload, prescripteur, readiness, check-in) — levendorDatadu RDV visé ; - un
vendorDataau niveau réponse (ex. réponse de check-in) est mémorisé sous l'id de l'entité que l'appel concernait — même logique.
Pourquoi deux accueils ne se mélangent pas
Un nouvel accueil recommence toujours par une identification : les réponses portent les entités du nouveau patient, avec leurs propres ids — donc leurs propres entrées dans la table. Les appels du parcours ne visent que ces ids-là : le vendorData d'un autre patient ne peut structurellement pas être joint, puisque la clé est l'id de l'entité visée, pas une session.
Et si le même patient repasse ? Même id → même entrée, et chaque réponse qui porte un vendorData remplace la valeur mémorisée (dernier écrit gagne) : la valeur jointe est donc toujours la plus récente que vous ayez servie pour cette entité.
Règles et limites
- Opaque : la borne ne lit ni ne modifie jamais le contenu ;
- Taille : moins de 4 Ko sérialisé par objet ;
- Pas de secret : l'objet transite par le navigateur de la borne — n'y mettez rien de sensible (pas de mot de passe, pas de clé d'API) ;
- Optimisation, pas un canal d'état : la mémoire vit avec la session de l'application borne (elle est vide après un redémarrage). Vos routes DOIVENT fonctionner sans
context.vendorData— servez-vous-en pour éviter une résolution d'identifiants, jamais comme unique porteur d'un état indispensable ; - Mécanisme d'extension officiel : tout besoin propriétaire passe par
vendorData, jamais par une modification de la spec.
Dans l'implémentation de référence, le pattern est visible dans src/server/contract/mappers.ts (les ids SQLite internes voyagent en vendorData).
