From 997f94912e65832d4328496e2076e42e3dfce9fa Mon Sep 17 00:00:00 2001 From: Matthias G Date: Sat, 1 Aug 2026 18:20:53 +0200 Subject: [PATCH] Document what the API can do The markdown had no writing section at all, so posts, blocks, drafts and deletes were only visible in the admin. Adds them with every field, plus date and number rules and the media delete in both places. --- docs/api.md | 83 ++++++++++++++++++++++++++++++++++++++ src/app/admin/api/page.tsx | 34 ++++++++++++++-- 2 files changed, 113 insertions(+), 4 deletions(-) diff --git a/docs/api.md b/docs/api.md index 5345dcc..a3f9e90 100644 --- a/docs/api.md +++ b/docs/api.md @@ -105,6 +105,80 @@ curl -s -X POST -H "Authorization: Bearer $TOKEN" \ Antwort: `{ "marked": 1 }`, also die Zahl der tatsächlich neu vermerkten Einträge. Unbekannte Kennungen und Einträge fremder Projekte werden still verworfen, die Antwort bleibt 200. +## Schreiben + +Ein Zugang mit Schreibrecht legt immer Entwürfe an. Veröffentlicht wird von Hand in der Verwaltung. + +### GET /api/v1/post-types + +Die verwaltbaren Beitragsarten mit Schlüssel, Bezeichnung und Farbe. Vor dem Schreiben abfragen statt raten. + +### POST /api/v1/posts + +Legt einen Beitrag als Entwurf an. + +| Feld | Pflicht | Bedeutung | +|---|---|---| +| `project` | ja | Slug des Projekts | +| `title` | ja | höchstens 200 Zeichen | +| `type` | ja | Schlüssel einer Beitragsart | +| `teaser` | nein | höchstens 500 Zeichen | +| `audience` | nein | `internal`, `customer` oder `public`, Standard `internal` | +| `author_name` | nein | sonst der Name des Zugangs | +| `slug` | nein | sonst aus dem Titel gebildet | +| `cover_media_id` | nein | Kennung eines hochgeladenen Bildes | +| `publish_at` | nein | gewünschtes Datum, siehe unten | +| `blocks` | nein | Inhalt, höchstens 100 Blöcke | +| `idempotency_key` | nein | derselbe Schlüssel liefert denselben Beitrag zurück | + +```bash +curl -s -X POST -H "Authorization: Bearer $TOKEN" \ + -H "content-type: application/json" \ + -d '{ + "project": "trakk", + "title": "SLA-Uhr zählt Feiertage nicht mehr mit", + "teaser": "Reaktionszeiten liefen über Wochenenden weiter.", + "type": "fix", + "audience": "customer", + "cover_media_id": "", + "publish_at": "2026-06-04T09:00:00Z", + "idempotency_key": "sla-2026-07-31" + }' \ + http://localhost:4700/api/v1/posts +``` + +Antwort 201 mit dem angelegten Entwurf. `number` ist `null`, die Nummer kommt beim Veröffentlichen. + +### PATCH /api/v1/posts/:id + +Ändert Titel, Anreißer, Art, Zielgruppe, Slug, Aufmacherbild oder Datum. Nur solange nichts veröffentlicht ist, sonst 409. Zum Ändern wird die Kennung gebraucht, nicht der Slug. + +```bash +curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \ + -H "content-type: application/json" \ + -d '{"teaser":"Neuer Anreißer.","publish_at":"2026-06-04T09:00:00Z"}' \ + http://localhost:4700/api/v1/posts/ +``` + +### PUT /api/v1/posts/:id/blocks + +Setzt die Blöcke vollständig, in der übergebenen Reihenfolge. Höchstens 100. + +```bash +curl -s -X PUT -H "Authorization: Bearer $TOKEN" \ + -H "content-type: application/json" \ + -d '{"blocks":[{"type":"text","data":{"text":"Erster Absatz."}}]}' \ + http://localhost:4700/api/v1/posts//blocks +``` + +### GET /api/v1/posts/:id + +Liest den Entwurf mit allen Blöcken zurück, zum Prüfen vor der Freigabe. Mit Schreibrecht findet dieser Aufruf den Entwurf auch über den Slug. + +### DELETE /api/v1/posts/:id + +Löscht einen Entwurf. Veröffentlichtes lässt sich nicht löschen. + ## Bilder ### POST /api/v1/media @@ -136,6 +210,15 @@ curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \ Liefert eine Variante aus. Die Pfade stehen am Medium unter `variants`, je Eintrag mit `width`, `format` und `path`. +## Werkzeuge + +| Adresse | Inhalt | +|---|---| +| `GET /api/v1/openapi.json` | maschinenlesbare Beschreibung für Postman, Bruno, Insomnia oder einen KI-Assistenten | +| `GET /api/v1/style-guide` | dieser Redaktionsleitfaden als Markdown | + +Beide verlangen ein Token. In der Verwaltung unter API lädt ein angemeldeter Admin beide Dateien ohne Token herunter. + ## Redaktionsleitfaden Wer über die API schreibt, schreibt für Menschen. Diese Regeln gelten für jeden Eintrag. diff --git a/src/app/admin/api/page.tsx b/src/app/admin/api/page.tsx index 197723f..2efc50f 100644 --- a/src/app/admin/api/page.tsx +++ b/src/app/admin/api/page.tsx @@ -185,7 +185,7 @@ export default async function AdminApiPage() { method="GET" path="/api/v1/posts/:slug" auth="read" - summary="Ein einzelner Eintrag. Nicht sichtbar heißt 404, nicht 403, damit die Antwort seine Existenz nicht verrät." + summary="Ein einzelner Eintrag über Slug oder Kennung. Mit Schreibrecht findet der Aufruf auch eigene Entwürfe. Nicht sichtbar heißt 404, nicht 403, damit die Antwort seine Existenz nicht verrät." example={'curl -s -H "Authorization: Bearer $TOKEN" \\\n http://localhost:4700/api/v1/posts/regel-engine'} /> @@ -221,8 +221,8 @@ export default async function AdminApiPage() { method="POST" path="/api/v1/posts" auth="write" - summary="Legt einen Beitrag an, immer als Entwurf. Mit idempotency_key erzeugt ein wiederholter Aufruf keinen zweiten Beitrag." - example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -H "content-type: application/json" \\\n -d \'{\n "project": "trakk",\n "title": "SLA-Uhr zählt Feiertage nicht mehr mit",\n "teaser": "Reaktionszeiten liefen über Wochenenden weiter.",\n "type": "fix",\n "audience": "customer",\n "idempotency_key": "sla-2026-07-31"\n }\' \\\n http://localhost:4700/api/v1/posts'} + summary="Legt einen Beitrag an, immer als Entwurf. Aufmacherbild und Datum gehen gleich mit. Mit idempotency_key erzeugt ein wiederholter Aufruf keinen zweiten Beitrag." + example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -H "content-type: application/json" \\\n -d \'{\n "project": "trakk",\n "title": "SLA-Uhr zählt Feiertage nicht mehr mit",\n "teaser": "Reaktionszeiten liefen über Wochenenden weiter.",\n "type": "fix",\n "audience": "customer",\n "cover_media_id": "",\n "publish_at": "2026-06-04T09:00:00Z",\n "idempotency_key": "sla-2026-07-31"\n }\' \\\n http://localhost:4700/api/v1/posts'} /> '} /> @@ -264,6 +264,32 @@ export default async function AdminApiPage() { summary="Lädt ein Bild hoch und erzeugt WebP-Varianten. Nur Bildformate, höchstens 15 MB." example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -F "file=@screenshot.png" \\\n -F "project=trakk" \\\n -F "alt=Spaltenmenü mit den neuen Einträgen" \\\n http://localhost:4700/api/v1/media'} /> + + '} + /> + + +
+ Datum und Nummer +
+

+ publish_at nimmt eine ISO-Zeitangabe entgegen, + beim Anlegen und beim Ändern. Der Zugang veröffentlicht damit nichts, er hinterlegt nur das Datum. + Gibt ein Mensch den Beitrag frei, übernimmt Logbuch genau dieses Datum statt der aktuellen Uhrzeit. + So lassen sich ältere Meldungen richtig einsortieren. +

+

+ Die laufende Nummer wird erst beim Veröffentlichen vergeben. Ein Entwurf hat + {' '} + number: null. Damit bleiben die Nummern im + Archiv lückenlos, auch wenn Entwürfe wieder verworfen werden. +

+