# Dokumente

> Der eigene Dokumentenspeicher des Restaurants (Bescheinigungen, Verfahren, Berichte): jeder Datensatz eine abgelegte Datei mit ihrem eigenen Medientyp.

Source: https://developers.backresto.com/de/docs/drive-files

Jedes Restaurant hält neben den Kontrollen auch Papier: Bescheinigungen von
Lieferanten, Reinigungsverfahren, den letzten Kontrollbericht, einen
unterschriebenen Plan. Die App gibt ihm einen Ort, es abzulegen, und diese
Collection ist dieser Aktenschrank: ein Datensatz pro Dokument, jeder auf die
Datei selbst zeigend.

| Collection | Scope | Was ein Datensatz ist |
| --- | --- | --- |
| `drive-files` | `drive-files:read` | Ein Dokument, das im Dokumentenspeicher des Restaurants abgelegt ist. |

Sie teilt sich den [Snapshot-Umschlag](https://developers.backresto.com/de/docs/collections): `id`, `deleted`,
`capturedAt`, `receivedAt`, `sequence` und der Rest stehen um das `data`
darunter herum.

## `drive-files`

| Feld | Typ | Bedeutung |
| --- | --- | --- |
| `s3Key` | string, **Pflicht** | Wo das Dokument im Speicher liegt. Ein Schlüssel, keine URL. Bis zu 1024 Zeichen. |
| `name` | string, **Pflicht** | Der Dateiname, so wie das Restaurant ihn sieht. |
| `sizeBytes` | number, **Pflicht** | Größe des Dokuments in Bytes. |
| `contentType` | string \| null | Der Medientyp, den die App erfasst hat. Kann fehlen. |
| `asset` | object | Die Datei. Lesen Sie den nächsten Abschnitt. |

```json
{
  "id": "a94c7e51-3f60-4b2d-8e17-05c9d3a6f482",
  "collection": "drive-files",
  "deleted": false,
  "capturedAt": "1789743015220",
  "receivedAt": "1789743098644",
  "sequence": "97",
  "data": {
    "s3Key": "drive/fournisseurs/attestation-metro-2026.pdf",
    "name": "Attestation Metro 2026.pdf",
    "sizeBytes": 184320,
    "contentType": "application/pdf",
    "asset": {
      "objectKey": "restaurants/36eaa3fa/drive/a17c93be4f02",
      "status": "uploaded",
      "contentType": "application/pdf",
      "byteLength": 184320,
      "sha256": "9f2a…"
    }
  }
}
```

In `data` gibt es kein `timestamp`. Wann das Dokument abgelegt wurde, steht wie
bei jeder anderen Collection in `capturedAt` auf dem Umschlag.

## Die Datei ist der Punkt

Anderswo ist der Datensatz die Information und die Datei der Beleg. Hier ist es
umgekehrt: Fünf Felder beschreiben ein Dokument, dessen Inhalt der ganze Grund
ist, aus dem jemand diese Collection liest. Sie werden also fast immer dem
Datensatz bis zu den Bytes folgen.

```http
GET /v1/restaurants/{restaurantId}/collections/drive-files/records/{recordId}/assets
```

Signierte URLs, **fünfzehn Minuten** gültig, jede mit ihrer eigenen
Autorisierung. [Die Collections-Seite](https://developers.backresto.com/de/docs/collections) hat die Regeln, und
zwei davon zählen hier mehr als sonst irgendwo:

- **`sha256` erspart Ihnen einen Download.** Es ist die Prüfsumme der Bytes.
  Eine Bescheinigung, die sich seit Ihrem letzten Durchlauf nicht geändert hat,
  muss nicht erneut geholt werden, und Dokumente sind das Größte, was diese API
  Ihnen reicht.
- **Jetzt abrufen, die Bytes speichern, nie den Link.** Fünfzehn Minuten reichen
  zum Herunterladen und sind kurz genug, dass eine URL in Ihrer Datenbank bis
  zum Morgen ein toter Link ist.

**`asset` beschreibt die Datei; herausgeben tut sie nur der Endpunkt.** Es trägt
`objectKey`, `status`, `contentType`, `byteLength` und `sha256`: genug, um zu
entscheiden, ob Sie die Bytes wollen, und keine URL, denn eine URL, die nie
abläuft, wäre ein dauerhafter unauthentifizierter Link zu den Unterlagen eines
Restaurants.

`status` ist das Feld, auf das Sie verzweigen. Es ist `uploaded`, sobald die
Bytes angekommen und geprüft sind, und `pending`, solange ein Gerät sie noch
sendet. Ein Asset mit `pending` fehlt beim Assets-Endpunkt; das ist richtig so
und kein Defekt: Fragen Sie später erneut, statt es als fehlendes Dokument zu
behandeln. `asset` ist außerdem das eine Feld hier, das ganz fehlen
kann: ein Datensatz, der noch ohne Datei abgelegt wurde.

## Das sind keine Bilder

Ein Reinigungsbeleg ist ein Foto. Ein Dokument ist, was immer das Restaurant
abgelegt hat: eine PDF-Bescheinigung, ein Temperaturexport als Excel oder CSV,
ein Verfahren in Word, ein Scan, den jemand mit dem Telefon gemacht hat. All das
taucht hier auf.

**Lesen Sie `contentType`, statt einen anzunehmen.** Im Datensatz darf es `null`
sein (die App hat ihn nicht immer). Nehmen Sie also, wenn es `null` ist,
stattdessen den `contentType` vom Asset; der ist der Medientyp des Objekts, das
tatsächlich gespeichert ist, und ihm ist zu trauen, wenn die beiden sich
widersprechen. Ein Client, der alles als Bild darstellt oder alles als `.pdf`
speichert, geht bei der ersten Tabelle kaputt.

**Leiten Sie den Typ auch nicht aus `name` oder `s3Key` ab.** Eine Endung ist
eine Konvention, keine Garantie, und beide Felder sind Freitext von einer
Person, die auf einem Tablet eine Datei benennt.

## Sie auf Ihrer Seite ablegen

**`s3Key` ist ein Schlüssel, keine Adresse.** Er benennt das Objekt im
Speicher: Er hat kein Schema, keinen Host und keinen führenden Schrägstrich,
und Sie können ihn nicht abrufen. Jedes Byte, das Sie bekommen, kommt vom
Assets-Endpunkt.

**Nutzen Sie die `id` des Umschlags als Schlüssel, nicht `name`.** Nichts hindert
zwei Dokumente daran, `Attestation 2026.pdf` zu heißen, im selben Restaurant,
ein Jahr auseinander abgelegt.

**Es lohnt sich, `sizeBytes` vor dem Download zu lesen.** Es ist der billigste
Weg zu entscheiden, ob Sie einen 40 MB großen Scan über eine Mobilverbindung
ziehen. Maßgeblich ist das `byteLength` des gespeicherten Objekts selbst, auf
dem Asset.

**Ein Tombstone nimmt die Datei mit.** `deleted: true` heißt, dass das Dokument
in der App entfernt wurde, und seine Assets werden nicht mehr aufgelistet. Wenn
Sie diese Bescheinigung gebraucht haben, haben Sie die Bytes gebraucht. Wie sich
Tombstones verhalten, steht auf
[der Seite zum Umschlag](https://developers.backresto.com/de/docs/collections).
