Standort & Personen

Der Standort, sein Personal, seine Zonen und seine Geräte — die feste Karte, an der jede Temperaturmessung hängt.

Das sind die Dinge, die sich nicht bewegen: das Restaurant selbst, die Menschen, die darin arbeiten, die Zonen, in die es aufgeteilt ist, und die Geräte, die Lebensmittel auf Temperatur halten. Nichts davon ist eine Kontrolle.

Es entscheidet trotzdem, was die Kontrollen bedeuten. Eine Temperatur ist eine Zahl ohne Urteil, solange Sie nicht die Schwellen von dem Gerät lesen, an dem sie gemessen wurde, und eine Messung gehört nur deshalb zu einem Teil des Gebäudes, weil das Gerät sagt, in welchem Bereich es steht. Liegen Sie bei dieser Seite falsch, ist jede Kennzahl danach still und leise falsch.

CollectionBerechtigungWas ein Datensatz ist
restaurantsrestaurants:readDer Standort selbst: Name, Adresse, Schließtage, Einstellungen.
usersusers:readEin Mitarbeiterkonto, das Kontrollen erfasst.
areasareas:readEine Zone, in die der Standort aufgeteilt ist — Küche, Kühlraum, Bar.
equipmentequipment:readEin Kühlschrank, ein Gefriergerät, eine Kühlketten-Einheit, mit ihren Schwellen.
sensorssensors:readEin Funkfühler, über seine MAC-Adresse.
cooking-equipmentcooking-equipment:readEin Ofen oder ein anderes Gargerät, mit seinen Schwellen.

Alle sechs teilen sich den Snapshot-Umschlag: id, deleted, capturedAt, receivedAt, sequence und der Rest stehen neben dem data, das unten beschrieben ist.

restaurants

Der Standort, auf den Ihr Schlüssel begrenzt ist, als Datensatz. Einer pro Restaurant, diese Collection ist also meist eine einzige Seite.

FeldTypBedeutung
namestring, PflichtDer Name des Standorts, so wie er in der App angezeigt wird.
addressstring, PflichtDie Postanschrift, als eine Zeichenkette.
closingDaysstring[], PflichtDie Tage, an denen der Standort geschlossen ist. Schlichte Zeichenketten, vom Schema nicht eingeschränkt.
exceptionalClosuresobject[]Einmalige Schließungen, jede ein Objekt mit from und to.
detailedAddressobject | nullDie Adresse in ihre Teile zerlegt, wenn die App sie so hält.
deliveryAddressstring | nullWohin Waren geliefert werden, wenn es von address abweicht.
deliveryDetailedAddressobject | nullDasselbe, in Teilen.
preferredLanguagestring | nullDie Sprache, in der das Restaurant arbeitet.
multiAreaboolean | nullOb der Standort in mehr als einen Bereich aufgeteilt ist.
settingsobject | nullApp-Einstellungen. Die Struktur gehört der App, und sie bewegt sich.
{
  "id": "e5a1d3c9-7b40-4a28-9df6-18c0b2e46a75",
  "collection": "restaurants",
  "deleted": false,
  "capturedAt": "1789300481002",
  "receivedAt": "1789300489517",
  "sequence": "7",
  "data": {
    "name": "Le Comptoir de Nanterre",
    "address": "12 rue des Anciennes Mairies, 92000 Nanterre",
    "closingDays": ["sunday"],
    "preferredLanguage": "fr",
    "multiArea": true
  }
}

Das Beispiel zeigt nur die betriebliche Hälfte. Daneben trägt der Datensatz die kaufmännische: subscription, subscriptions, companyName, billingAddress, billingEmail, tvaNumber, trialEndDate, customerId, discount. Es gibt sie, sie stehen im OpenAPI-Dokument, und diese Seite führt Sie nicht durch sie hindurch.

Lesen Sie die betrieblichen Felder und lassen Sie die kaufmännischen in Ruhe. Sie beschreiben den Vertrag des Restaurants mit uns, nicht seine Küche. Sie sind keine Abrechnungs-API, sie ändern sich aus Gründen, die nichts mit Lebensmittelsicherheit zu tun haben, und eine Integration, die einem Kunden seinen Abonnementstatus zurückspiegelt, ist ein Support-Ticket, das nur auf seinen Termin wartet.

closingDays ist eine Liste schlichter Zeichenketten. Das Schema gibt ihnen keine Form, lesen Sie sie also und zeigen Sie sie; verzweigen Sie nicht darauf und nehmen Sie keine bestimmte Schreibweise und keine bestimmte Groß- und Kleinschreibung an.

users

Die Mitarbeiterkonten, die Kontrollen erfassen. Auf sie zeigt das userId eines Temperaturdatensatzes.

FeldTypBedeutung
firstNamestring, PflichtVorname, so wie eingetragen.
lastNamestring, PflichtNachname, so wie eingetragen.
emailstring, PflichtDie E-Mail-Adresse des Kontos.
phoneNumberstring | nullEine Rufnummer, sofern eine angegeben wurde.
modulesstring[]Welche Teile der App diese Person nutzt. Freie Zeichenketten.
preferredNotificationTimestring | nullWann diese Person erinnert werden möchte.
isChildrenboolean | nullEin internes Kennzeichen. Das Schema gibt ihm keine Bedeutung; bauen Sie nicht darauf.
isDeletedboolean | nullDas eigene Kennzeichen der App für ausgemusterte Einträge — und hier darf es null sein, anders als sonst.
{
  "id": "2774953d-8d9b-4a68-8ec4-1209edd90777",
  "collection": "users",
  "deleted": false,
  "capturedAt": "1789315002664",
  "receivedAt": "1789315010218",
  "sequence": "31",
  "data": {
    "firstName": "Amina",
    "lastName": "Berthier",
    "email": "amina.berthier@example.test",
    "phoneNumber": null,
    "modules": ["temperatures", "cleaning"],
    "isDeleted": false
  }
}

Das sind personenbezogene Daten. email, phoneNumber und die beiden Namensfelder benennen eine echte Person, und sie stehen aus einem einzigen Grund in dieser API: Ein Datensatz zur Lebensmittelsicherheit muss sagen, wer die Kontrolle durchgeführt hat. Das ist ihre einzige Aufgabe hier.

Speichern Sie also das id und lösen Sie einen Anzeigenamen auf, wenn Sie einen brauchen. Kopieren Sie Kontaktdaten nicht in Ihre eigenen Tabellen, Ihre Protokolle, Ihre Analytics-Ereignisse oder ein Werkzeug eines Dritten, nur weil sie zufällig in der Antwort standen. Das Restaurant ist für sein Personal der Verantwortliche im Sinne des Datenschutzes, und jede Kopie, die Sie anlegen, ist eine, für die es nun geradestehen muss.

isDeleted darf in dieser Collection null sein, wo es sonst Pflicht ist; behandeln Sie ein fehlendes Kennzeichen also als „nicht ausgemustert“, statt es versehentlich als falsch-artig durchfallen zu lassen. Der Unterschied zum deleted des Umschlags ist auf der Katalogseite erklärt.

areas

Eine Zone des Restaurants. Zwei Felder, und weit wichtiger, als zwei Felder vermuten lassen.

FeldTypBedeutung
namestring, PflichtDie Zone, so wie das Restaurant sie nennt — Küche, Kühlraum, Bar.
isDeletedboolean, PflichtDas Kennzeichen der App für ausgemusterte Einträge. Siehe die Katalogseite.
{
  "id": "9c2b17ae-4d80-4f55-b3e1-0a6c8f4d2b19",
  "collection": "areas",
  "deleted": false,
  "capturedAt": "1789301120440",
  "receivedAt": "1789301126871",
  "sequence": "12",
  "data": {
    "name": "Chambre froide",
    "isDeleted": false
  }
}

Über areaId wird alles nach Zone gruppiert. Geräte, Gargeräte, Fritteusen und Reinigungsaufgaben tragen alle eines, und es ist die einzige Verbindung zwischen einer Messung und einem Teil des Gebäudes. Auf den Datensätzen selbst gibt es kein areaId: Sie kommen über das Gerät dorthin.

areaId darf überall, wo es auftaucht, null sein. Ein Kühlschrank ohne Bereich ist normal — es heißt, dass ihn niemand zugeordnet hat, meist an einem Standort mit einem einzigen Raum, wo multiArea falsch ist. Fassen Sie solche unter „nicht zugeordnet“ zusammen, statt sie wegzulassen.

equipment

Kühlschränke, Gefriergeräte und andere Einheiten der Kühlkette. Der Datensatz, der entscheidet, ob eine Temperatur zulässig war.

FeldTypBedeutung
indexinteger, PflichtDie Position, die das Restaurant ihm in seiner eigenen Liste gegeben hat. Anzeigereihenfolge, keine Kennung.
typestring, PflichtUm welche Art Einheit es sich handelt. Eine nicht eingeschränkte Zeichenkette — lesen Sie sie, verzweigen Sie nicht darauf.
namestring, PflichtDie Einheit, so wie die Küche sie nennt.
minnumber | nullDie niedrigste zulässige Temperatur.
maxnumber | nullDie höchste zulässige Temperatur.
areaIdstring | nullDer Bereich, in dem sie steht.
equipmentSensorIdstring | nullDer Sensor, der daran angebracht ist, sofern es einen gibt.
statestring | nullDer aktuelle Zustand der Einheit, als nicht eingeschränkte Zeichenkette.
outOfRangeCountnumber | nullEine Anzahl von Messungen außerhalb des Bereichs, die die App führt.
isDeletedboolean, PflichtDas Kennzeichen der App für ausgemusterte Einträge.
{
  "id": "84ce5c13-3237-40d4-901a-cbba59a6406f",
  "collection": "equipment",
  "deleted": false,
  "capturedAt": "1789302455901",
  "receivedAt": "1789302461330",
  "sequence": "58",
  "data": {
    "index": 2,
    "type": "freezer",
    "name": "Congélateur bas",
    "min": -22,
    "max": -18,
    "areaId": "9c2b17ae-4d80-4f55-b3e1-0a6c8f4d2b19",
    "equipmentSensorId": "b31f7d64-0e29-42ca-9a57-51d3c8e07f28",
    "state": "ok",
    "outOfRangeCount": 0,
    "isDeleted": false
  }
}

min und max sind das einzige Urteil, das Sie bekommen. Ein Temperaturdatensatz trägt einen Wert, eine Zeit und das Gerät, an dem gemessen wurde — nichts, was sagt, ob es in Ordnung war. -14,4 °C sind in einem Kühlschrank eine Krise und in einem Gefriergerät ein normaler Dienstag, und dieser Datensatz ist es, der beides unterscheidet. Jede Compliance-Kennzahl, die Sie bauen, verbindet sich hier.

Sie dürfen auch null sein. Fehlt min oder max, haben Sie keine Schwelle, und die ehrliche Antwort für diese Messung lautet „unbekannt“, nicht „im Bereich“. Sagen Sie das in Ihrer Oberfläche, statt auf Grün zurückzufallen.

Die Schwellen sind die heutigen, nicht die, die damals galten. Der Snapshot gibt Ihnen das min und max von heute; eine Messung vom März wurde an dem gemessen, was im März eingestellt war, und das Restaurant kann sie jederzeit ändern. Wenn Sie alte Messungen gegen die heutigen Zahlen neu bewerten — mehr lässt diese API nicht zu —, kennzeichnen Sie das Ergebnis als Ihre Neuberechnung, nicht als das, was die Küche gesehen hat.

type und state sind nicht eingeschränkte Zeichenketten. Beide sind im Schema einzelne Freitextfelder ohne Liste dahinter. Zeigen Sie sie an, gruppieren Sie darauf, wenn es sein muss, und lassen Sie einen unbekannten Wert nie durch eine Verzweigung ins Schweigen fallen.

outOfRangeCount ist die Zahl der App, nicht Ihre. Das Schema sagt nicht, welchen Zeitraum sie abdeckt, und Sie können sie aus den Snapshots hier nicht nachbauen. Behandeln Sie sie als Hinweis aus der App, und wenn Sie eine Zahl brauchen, die Sie vertreten können, berechnen Sie Ihre eigene aus den Messungen und den Schwellen und kennzeichnen Sie sie als Ihre.

equipmentSensorId zeigt vom Gerät auf seinen Sensor. Der Sensordatensatz zeigt in die andere Richtung zurück. Beide Seiten dürfen null sein, und keine ist garantiert gefüllt, nur weil die andere es ist.

sensors

Die Funkfühler. Zwei Felder, beide optional.

FeldTypBedeutung
macAddressstring | nullDie Hardware-Adresse des Fühlers — so unterscheiden Sie ein physisches Gerät vom anderen.
sensorEquipmentIdstring | nullDas Gerät, das dieser Sensor überwacht.
{
  "id": "b31f7d64-0e29-42ca-9a57-51d3c8e07f28",
  "collection": "sensors",
  "deleted": false,
  "capturedAt": "1789302501764",
  "receivedAt": "1789302509002",
  "sequence": "61",
  "data": {
    "macAddress": "F4:12:9D:3A:77:0B",
    "sensorEquipmentId": "84ce5c13-3237-40d4-901a-cbba59a6406f"
  }
}

Achten Sie auf die beiden Feldnamen, die Spiegelbilder sind und sich leicht vertauschen lassen: Ein Gerät trägt equipmentSensorId, ein Sensor trägt sensorEquipmentId. Lesen Sie das falsche, bekommen Sie undefined ohne Fehler.

Hier gibt es keinen Namen, keinen Batteriestand und keinen Zeitpunkt der letzten Meldung. Was ein Sensor gemeldet hat, steht in temperature-readings, und die sind über equipmentId geschlüsselt statt über den Sensor — ein Fühler, der verstummt ist, sieht also genau so aus wie einer, der nichts zu melden hatte.

cooking-equipment

Öfen, Warmhalteschränke und der Rest der heißen Seite. Derselbe Gedanke wie bei equipment, ohne die Technik der Kühlkette.

FeldTypBedeutung
indexinteger, PflichtAnzeigereihenfolge in der eigenen Liste des Restaurants.
typestring, PflichtUm welche Art Einheit es sich handelt. Nicht eingeschränkte Zeichenkette.
namestring, PflichtDie Einheit, so wie die Küche sie nennt.
minnumber | nullDie niedrigste zulässige Temperatur.
maxnumber | nullDie höchste zulässige Temperatur.
areaIdstring | nullDer Bereich, in dem sie steht.
isDeletedboolean, PflichtDas Kennzeichen der App für ausgemusterte Einträge.
{
  "id": "3d90f4c8-62b7-4e13-8a05-ff71d6b9c204",
  "collection": "cooking-equipment",
  "deleted": false,
  "capturedAt": "1789303880115",
  "receivedAt": "1789303887640",
  "sequence": "64",
  "data": {
    "index": 1,
    "type": "oven",
    "name": "Four à sole",
    "min": 63,
    "max": 260,
    "areaId": "9c2b17ae-4d80-4f55-b3e1-0a6c8f4d2b19",
    "isDeleted": false
  }
}

Kein state, kein outOfRangeCount, kein Sensor: Gargeräte werden von einer Person abgelesen, zwischen den Kontrollen beobachtet sie also nichts. Ihre Messungen sind cooking-temperature-records, die mit cookingEquipmentId hierher zeigen — ein anderer Feldname als der der Kühlkette, und die übliche Stelle, an der ein Client stillschweigend nichts liest.

Die Karte lesen

Alles auf dieser Seite ist klein, ändert sich langsam und wird gebraucht, bevor irgendeine andere Collection Sinn ergibt.

  • Laden Sie es zuerst und halten Sie es. Durchlaufen Sie areas, equipment, cooking-equipment und sensors, bevor Sie irgendeine Datensatz-Collection durchlaufen, und lösen Sie Namen und Schwellen aus Ihrer eigenen Kopie auf, statt pro Datensatz.
  • Frischen Sie es trotzdem auf. Geräte werden umbenannt, Schwellen werden korrigiert, ein Kühlschrank zieht in einen anderen Bereich. Eine Kopie, die einmal genommen und nie wieder durchlaufen wird, läuft auseinander, ohne je zu scheitern.
  • Halten Sie Kennungen, keine Kopien — besonders bei Personen. Speichern Sie userId und lösen Sie einen Namen beim Anzeigen auf. Siehe die Anmerkung zu personenbezogenen Daten oben.
  • Beide Löschkennzeichen, überall. Das deleted des Umschlags und das isDeleted in data sind verschiedene Dinge, und die Katalogseite erklärt, welches welches ist.

Zuletzt aktualisiert am 2026-09-20.