Livraisons
Les contrôles à réception et les photographies prises à la réception : deux collections, chaque champ, et ce qu'ils signifient sur le terrain.
Une livraison est un contrôle à réception : un membre du personnel qui réceptionne une commande, relève des températures, et décide de l'accepter ou non. C'est l'enregistrement que demande un inspecteur de la sécurité alimentaire. Les photos prises à la réception forment une seconde collection à côté.
| Collection | Scope | Ce qu'est un enregistrement |
|---|---|---|
deliveries | deliveries:read | Un contrôle à réception, avec un relevé de température par produit. |
delivery-pictures | delivery-pictures:read | Une photographie prise pendant une livraison, qui pointe vers celle-ci. |
Toutes deux sont des collections ordinaires : la même
enveloppe de snapshot autour de data, les mêmes endpoints, le même curseur, la
même règle des 90 jours. Elles portent l'historique des livraisons que
l'application détenait encore à leur ouverture, pas seulement ce qui a été
enregistré depuis.
deliveries
| Champ | Type | Signification |
|---|---|---|
timestamp | string, obligatoire | Quand le contrôle a eu lieu, en millisecondes depuis l'epoch sous forme de chaîne de caractères. |
isCompliant | boolean, obligatoire | Le verdict du membre du personnel sur la livraison dans son ensemble. |
supplierDeliveriesId | string | null | Le fournisseur dont viennent les marchandises : l'id d'un enregistrement suppliers. |
temperatureRecords | array | null | Une entrée par produit mesuré. Voir ci-dessous. |
nonComplianceReasons | string[] | null | Pourquoi la livraison a été refusée ou acceptée avec réserve. Texte libre choisi par le membre du personnel ; vide quand la livraison est conforme. |
correctiveActions | string[] | null | Ce qui a été fait en réponse. Vide quand rien n'était nécessaire. |
commentary | string | null | Note en texte libre. Souvent null. |
userId | string | null | Le membre du personnel qui l'a réceptionnée, quand l'application en a enregistré un. |
temperatureRecords[]
| Champ | Type | Signification |
|---|---|---|
product | string | Ce qui a été mesuré, tel que le membre du personnel l'a nommé. Jamais vide. |
lotNumber | string | null | Le lot ou le numéro de lot, quand il a été saisi. |
value | number | null | Le relevé. null quand le produit a été consigné sans mesure. |
unit | "C" | Toujours des degrés Celsius. Voir ci-dessous. |
Les températures sont toujours en degrés Celsius. Un restaurant dont
l'application relève en Fahrenheit envoie toujours des relevés en Fahrenheit,
et ils sont convertis à leur arrivée, avant d'être stockés. unit vaut "C"
sur chaque entrée, si bien qu'un consommateur n'a jamais à convertir ni à
deviner.
{
"id": "8f2c1b04-0d5a-4b7e-9f31-6ad2c0e77a51",
"collection": "deliveries",
"deleted": false,
"capturedAt": "1787932805120",
"receivedAt": "1787932911004",
"sequence": "88",
"data": {
"timestamp": "1787932800000",
"isCompliant": false,
"supplierDeliveriesId": "supplier-7",
"temperatureRecords": [
{ "product": "Poulet fermier", "lotNumber": "L2291", "value": 6.4, "unit": "C" },
{ "product": "Farine T55", "lotNumber": null, "value": null, "unit": "C" }
],
"nonComplianceReasons": ["Température trop élevée"],
"correctiveActions": ["Produit refusé", "Fournisseur prévenu"],
"commentary": "Camion en retard, rupture de chaîne du froid probable",
"userId": "2774953d-8d9b-4a68-8ec4-1209edd90777"
}
}
delivery-pictures
Une étiquette, une palette abîmée, une sonde posée contre un afficheur : ces
photos sont la preuve derrière isCompliant. Chacune est un enregistrement qui
pointe vers sa livraison, et elle porte un fichier : les octets viennent donc
de l'endpoint des fichiers.
| Champ | Type | Signification |
|---|---|---|
timestamp | string, obligatoire | Quand la photo a été prise, en millisecondes depuis l'epoch sous forme de chaîne de caractères. |
deliveryId | string | null | L'enregistrement deliveries auquel elle appartient. |
part | number | null | Position de cet enregistrement au sein d'une photo que l'application a stockée en plusieurs parties. Transportez-le plutôt que de l'interpréter. |
groupId | string | null | Relie ces parties entre elles. Des enregistrements qui partagent un groupId sont la même photo. |
asset | object, obligatoire | Nomme le fichier : objectKey et status toujours, plus contentType, byteLength et sha256 une fois qu'il est téléversé. |
{
"id": "c61e0a7d-35b2-4f89-a1d4-7e90b2c45f18",
"collection": "delivery-pictures",
"deleted": false,
"capturedAt": "1787932861240",
"receivedAt": "1787932990517",
"sequence": "143",
"data": {
"timestamp": "1787932860000",
"deliveryId": "8f2c1b04-0d5a-4b7e-9f31-6ad2c0e77a51",
"part": 4,
"groupId": "b4d81f0a-c2e7-4a55-9d10-6f3e8a2b7c91",
"asset": {
"objectKey": "delivery-pictures/b4d81f0a/4.jpg",
"status": "uploaded",
"contentType": "image/jpeg",
"byteLength": 902450,
"sha256": "9f2a…"
}
}
}
Les octets sont un second appel, sur l'identifiant propre à l'enregistrement :
GET /v1/restaurants/{restaurantId}/collections/delivery-pictures/records/{recordId}/assets
Il répond par des URL signées valables quinze minutes, exactement comme le décrit la page des collections. Demandez sur n'importe quelle partie d'une photo et vous obtenez le même fichier : l'API résout le groupe pour vous, inutile donc de chercher quelle partie le contient.
Pour afficher les photographies d'une livraison, parcourez delivery-pictures
et gardez les enregistrements dont le deliveryId est l'id de cette
livraison, un par groupId.
Le lire correctement
isCompliant est l'enregistrement, pas un calcul. C'est ce qu'a décidé la
personne qui a réceptionné la livraison, et cela peut diverger de ce que vous
concluriez des seules températures : une mesure prise avec une sonde de surface,
un produit qui a son propre seuil, une appréciation. Présentez-le comme leur
verdict. Si vous voulez le vôtre, calculez-le à côté du leur et indiquez qu'il
est de vous.
Les champs en texte libre sont du texte libre. nonComplianceReasons,
correctiveActions et product sont saisis par le personnel pendant le
service, dans la langue du restaurant, avec l'orthographe d'un mardi chargé.
N'en tirez pas une énumération, n'en faites pas la clé d'une jointure, et ne
supposez pas que c'est du français.
value peut être null. Un produit consigné sans relevé est normal. C'est
souvent une denrée sèche. Traitez null comme "non mesuré", jamais comme 0.
Les horodatages sont des chaînes de caractères. timestamp est une chaîne
de caractères en millisecondes depuis l'epoch, en notation décimale, parce que
toute la plateforme BackResto stocke les horodatages ainsi.
Number(timestamp) est sûr aujourd'hui et pour les quelques centaines de
milliers d'années à venir, mais ne laissez pas un analyseur JSON le convertir
silencieusement pour le réécrire ensuite avec une précision perdue.
Une photo peut arriver après sa livraison. Un téléphone téléverse les photographies quand il le peut, parfois quelques minutes après le contrôle lui-même. Une livraison sans photo pour l'instant peut simplement en avoir une encore en route ; parcourez à nouveau plus tard avant de conclure qu'elle n'en a aucune.