3 API Referenz
SurfaceScratcher edited this page 2026-05-12 22:39:36 +02:00

API-Referenz

Base URL (Produktion): https://api.mrrm.de
Base URL (Dev): http://localhost:3000

Alle geschützten Endpoints erfordern einen gültigen Bearer Token im Authorization-Header:

Authorization: Bearer <access_token>

Health

GET /healthz (öffentlich)

Prüft ob API und Datenbank erreichbar sind.

Response:

{
  "status": "ok",
  "db": true,
  "timestamp": "2026-04-28T12:00:00.000Z"
}

status ist "degraded" wenn die DB nicht erreichbar ist.


Auth

GET /auth/me (geschützt)

Gibt den eingeloggten Benutzer zurück (aus dem JWT-Token dekodiert).

Response:

{
  "sub": "keycloak-user-uuid",
  "email": "user@example.com",
  "name": "Max Mustermann",
  "preferredUsername": "max.mustermann"
}

Listen

GET /lists (geschützt)

Alle Listen des eingeloggten Benutzers.

GET /lists/:id (geschützt)

Einzelne Liste mit allen Items.

POST /lists (geschützt)

Neue Liste erstellen.

{
  "type": "shopping",
  "title": "Wocheneinkauf",
  "storeId": "uuid-optional"
}

type ist "shopping" | "todo" | "notes"

PATCH /lists/:id (geschützt)

Liste aktualisieren (Titel, Store).

DELETE /lists/:id (geschützt)

Liste löschen (alle Items werden mitgelöscht).

POST /lists/:id/items (geschützt)

Item zu einer Liste hinzufügen.

Für shopping-Items im data-Feld:

{
  "data": {
    "type": "shopping",
    "title": "Milch",
    "checked": false,
    "missing": false,
    "quantity": 1,
    "description": "optional"
  }
}

missing: true markiert einen Artikel, der im Geschäft nicht verfügbar war (orange hervorgehoben in der UI, übertragbar in andere Listen — siehe unten).

PATCH /lists/:id/items/:itemId (geschützt)

Item aktualisieren.

DELETE /lists/:id/items/:itemId (geschützt)

Item löschen.

POST /lists/:id/items/transfer-missing (geschützt)

Alle Items mit missing: true aus der Quellliste in eine andere Liste kopieren. Genau eines von targetListId oder newListTitle muss angegeben werden:

{ "targetListId": "uuid-einer-bestehenden-Shoppingliste" }

oder

{ "newListTitle": "Resteinkauf" }

Verhalten:

  • Quell-Items bleiben unverändert
  • Kopien im Ziel haben missing: false und checked: false
  • Ziel muss eine shopping-Liste sein (bzw. wird als solche neu angelegt)

Response: die Ziel-Liste inklusive aller Items (ListWithItems).

POST /lists/parse-image (geschützt)

Einkaufsliste aus Bild erkennen (Multipart-Form, image-Feld).
Ruft intern den OCR-Service auf.


Stores (Geschäfte)

GET /stores (geschützt)

Alle gespeicherten Geschäfte des Benutzers.

POST /stores (geschützt)

{ "name": "REWE Mitte", "details": {} }

PATCH /stores/:id (geschützt)

Store aktualisieren.

DELETE /stores/:id (geschützt)

Store löschen. Verknüpfte Listen bekommen storeId = null.


Mail

GET /mail/accounts (geschützt)

Alle konfigurierten Mail-Konten.

POST /mail/accounts (geschützt)

Neues IMAP-Konto hinzufügen.

{
  "label": "Mein Gmail",
  "host": "imap.gmail.com",
  "port": 993,
  "tls": true,
  "username": "user@gmail.com",
  "password": "app-passwort"
}

POST /mail/accounts/:id/test (geschützt)

IMAP-Verbindung testen.

GET /mail/accounts/:id/folders (geschützt)

Ordner-Liste des Kontos.

GET /mail/accounts/:id/folders/:folder/messages (geschützt)

Nachrichten eines Ordners (paginiert).
Query-Parameter: limit, offset, since (ISO-Datum)

DELETE /mail/accounts/:id (geschützt)

Konto löschen.

PATCH /mail/accounts/:id (geschützt)

Konto-Einstellungen ändern. Aktuell: label, trackingScanEnabled.

{ "trackingScanEnabled": false }

Tracking

Siehe Paket-Tracking für die Modul-Übersicht.

GET /trackings (geschützt)

Alle Sendungen des Benutzers (paginiert).

POST /trackings (geschützt)

Sendung manuell anlegen.

{
  "trackingNumber": "1Z9999W99999999999",
  "carrier": "ups",
  "note": "Geschenk an Mama"
}
  • 409 Conflict wenn (owner, trackingNumber) bereits existiert.

GET /trackings/:id (geschützt)

Detail einer Sendung inklusive letztem bekanntem Status und zugehörigen Order-Infos.

DELETE /trackings/:id (geschützt)

Sendung löschen.


Fehlerformat

{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request"
}
Code Bedeutung
400 Validierungsfehler (Zod)
401 Kein oder ungültiger Token
403 Kein Zugriff auf fremde Ressource
404 Ressource nicht gefunden
500 Interner Fehler