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. +

+