Weicht der Ticket-Status von der Statusbox ab, markiert das Knoten-Fenster
die Abweichung und bietet beide Richtungen ausdrücklich an.
- „nach Taiga schreiben": Spalte des Projekts suchen (Taiga schreibt nach Id,
die Namen sind je Projekt frei) und mit der zuletzt GELESENEN `version`
patchen — hat jemand dazwischen geändert, lehnt Taiga ab und der Text steht
im Fenster, statt dass etwas überschrieben wird.
- „aus Taiga übernehmen": `setStatusBox()` schreibt die Box in die Textzeile,
undo-fähig wie jede andere Änderung.
- Schreibbar sind nur die fünf abgebildeten Zustände; `[?]`, `[!]`, `[-]` und
der neutrale Knoten lassen das Ticket unangetastet — mit Begründung im
Fenster.
- Proxy: zwei Spaltenlisten (`/taiga/{userstory,task}-statuses?slug=`) und
zwei Schreib-Endpunkte (`PATCH …/{ref}/status?slug=`); die Zielspalte wählt
der Editor, das Backend parst die Notation nicht (D14).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1351 lines
43 KiB
YAML
1351 lines
43 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Editor Backend API
|
|
description: |
|
|
CRUD-Grundgeruest fuer Dokumente.
|
|
|
|
Vorbereitete Erweiterungen (noch nicht aktiv):
|
|
- Autorisierung: securitySchemes.bearerAuth ist definiert, wird aber noch
|
|
auf keine Operation angewendet.
|
|
- Live-Editing: Das Feld `version` dient spaeter der Konflikterkennung
|
|
(Optimistic Locking) und als Basis fuer Delta-Updates via WebSocket.
|
|
- Clientseitige Verschluesselung: `content` ist ein opaker String. Der
|
|
Server interpretiert den Inhalt nicht, sodass spaeter Ciphertext
|
|
transportiert werden kann, ohne die API zu aendern.
|
|
version: 0.1.0
|
|
|
|
servers:
|
|
- url: /api/v1
|
|
|
|
tags:
|
|
- name: Documents
|
|
description: Verwaltung von Dokumenten
|
|
- name: Taiga
|
|
description: >
|
|
Schmaler, benannter Proxy zur konfigurierten Taiga-Instanz (D91).
|
|
Kein Durchreich-Proxy: Die Taiga-Basis-URL ist Server-Konfiguration
|
|
(`werkbaum.taiga.api-url`), nie Request-Parameter - die SSRF-Falle
|
|
naiver Proxies. Das Token bleibt im Browser; der Server speichert
|
|
nichts. Ohne konfigurierte Instanz antworten alle Taiga-Endpunkte
|
|
mit 503; ob sie konfiguriert ist, meldet `GET /info` (`taiga`).
|
|
|
|
paths:
|
|
/documents:
|
|
get:
|
|
tags: [Documents]
|
|
operationId: listDocuments
|
|
summary: Alle Dokumente auflisten
|
|
description: >
|
|
Verlangt das Master-Passwort (HTTP Basic, Benutzer `werkbaum`).
|
|
Ohne diesen Schutz waere jede Dokument-UUID auflistbar - und das
|
|
Zugriffsmodell "unerratbare UUID" damit hinfaellig. Nach mehreren
|
|
Fehlversuchen wird der Endpunkt fuer eine Weile gesperrt (429).
|
|
security:
|
|
- masterPassword: []
|
|
responses:
|
|
"200":
|
|
description: Liste aller Dokumente
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Document"
|
|
"401":
|
|
description: Master-Passwort fehlt oder ist falsch
|
|
"429":
|
|
description: Zu viele Fehlversuche; `Retry-After` nennt die Restdauer
|
|
post:
|
|
tags: [Documents]
|
|
operationId: createDocument
|
|
summary: Neues Dokument anlegen
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DocumentCreateRequest"
|
|
responses:
|
|
"201":
|
|
description: Dokument wurde angelegt
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Document"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
|
|
/documents/{documentId}:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
get:
|
|
tags: [Documents]
|
|
operationId: getDocument
|
|
summary: Einzelnes Dokument abrufen
|
|
responses:
|
|
"200":
|
|
description: Das angeforderte Dokument
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Document"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
put:
|
|
tags: [Documents]
|
|
operationId: updateDocument
|
|
summary: Dokument vollstaendig aktualisieren
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DocumentUpdateRequest"
|
|
responses:
|
|
"200":
|
|
description: Aktualisiertes Dokument
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Document"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
description: Versionskonflikt (fuer spaeteres Optimistic Locking reserviert)
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
delete:
|
|
tags: [Documents]
|
|
operationId: deleteDocument
|
|
summary: Dokument loeschen
|
|
responses:
|
|
"204":
|
|
description: Dokument wurde geloescht
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
|
|
/documents/{documentId}/history:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
get:
|
|
tags: [Documents]
|
|
operationId: getDocumentHistory
|
|
summary: Historie eines Dokuments abrufen
|
|
description: >
|
|
Liefert die nutzersichtbaren Staende (Meilensteine) in chronologischer
|
|
Reihenfolge, dazu immer den juengsten Stand. Kurzlebige Sync-Versionen
|
|
des Live-Editings bleiben aussen vor. Die Historie ueberlebt das
|
|
Loeschen des Dokuments.
|
|
responses:
|
|
"200":
|
|
description: Meilensteine des Dokuments (aelteste zuerst)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/DocumentHistoryEntry"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
|
|
/documents/{documentId}/restore:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
post:
|
|
tags: [Documents]
|
|
operationId: restoreDocument
|
|
summary: Geloeschtes Dokument aus der Historie wiederherstellen
|
|
description: >
|
|
Stellt ein geloeschtes Dokument unter derselben UUID wieder her.
|
|
Ohne Request-Body wird der letzte Stand vor dem Loeschen
|
|
wiederhergestellt; optional kann eine bestimmte Version angegeben
|
|
werden (auch als Rollback fuer ein noch existierendes Dokument).
|
|
requestBody:
|
|
required: false
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/RestoreRequest"
|
|
responses:
|
|
"200":
|
|
description: Wiederhergestelltes Dokument
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Document"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
description: >
|
|
Dokument existiert noch und es wurde keine Zielversion angegeben.
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
|
|
/documents/{documentId}/content:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
patch:
|
|
tags: [Documents]
|
|
operationId: patchDocumentContent
|
|
summary: Zeilen-Diff auf den Inhalt anwenden (Live-Editing)
|
|
description: >
|
|
Reicht eine Aenderung als Zeilen-Diff gegen eine Basisversion ein.
|
|
|
|
|
|
Ist die Basis veraltet, ueberschneiden sich die Operationen aber nicht
|
|
mit den zwischenzeitlichen, verschiebt der Server sie selbst und
|
|
akzeptiert (200); die fremden Operationen stehen dann in
|
|
`opsSinceBase`, damit der Client seine Schattenkopie nachzieht. Nur
|
|
bei echter Ueberschneidung antwortet er mit 409.
|
|
|
|
|
|
`clientId` und `seq` machen den Aufruf wiederholbar: Eine Wiederholung
|
|
liefert das Ergebnis von damals, statt die Aenderung ein zweites Mal
|
|
anzuwenden.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ContentPatchRequest"
|
|
responses:
|
|
"200":
|
|
description: Aenderung angenommen (ggf. serverseitig verschoben)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ContentPatchResult"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
description: >
|
|
Echte Ueberschneidung mit einer zwischenzeitlichen Aenderung. Der
|
|
Client entscheidet - fremde Fassung uebernehmen oder eigene
|
|
durchsetzen -, ohne neu zu laden.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ContentConflict"
|
|
"422":
|
|
description: >
|
|
Diff nicht anwendbar: Pruefsummenfehler, Index ausserhalb, oder die
|
|
Basisversion ist nicht mehr verfuegbar. Der Client laedt einmalig neu.
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
|
|
/documents/{documentId}/title:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
patch:
|
|
tags: [Documents]
|
|
operationId: patchDocumentTitle
|
|
summary: Dokument umbenennen (Live-Editing)
|
|
description: >
|
|
Aendert nur den Titel - er ist ein Metadatum, kein Zeileninhalt, und
|
|
bekommt deshalb seinen eigenen Weg mit Versionspruefung (D76). Die
|
|
Umbenennung erzeugt eine neue Version vom Typ RENAMED, die der
|
|
Aenderungsfeed mit dem neuen Titel im Klartext zustellt - alle sehen
|
|
denselben Namen.
|
|
|
|
|
|
Verwaltungs-Aktion: Sie wird kuenftig an das geplante Owner-Passwort
|
|
gebunden (die Bindung kommt als Berechtigungspruefung dazu, die
|
|
Signatur bleibt).
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TitlePatchRequest"
|
|
responses:
|
|
"200":
|
|
description: Umbenanntes Dokument
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Document"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
description: >
|
|
Versionskonflikt - `expectedVersion` ist nicht mehr die aktuelle
|
|
Version. Der Client holt das Dokument frisch und versucht es mit
|
|
dessen Version erneut.
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
|
|
/documents/{documentId}/changes:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
get:
|
|
tags: [Documents]
|
|
operationId: getDocumentChanges
|
|
summary: Aenderungsfeed (Long Polling)
|
|
description: >
|
|
Liefert alles, was seit `since` geschehen ist. Gibt es nichts, haelt
|
|
der Server die Anfrage bis zu `wait` Sekunden offen und antwortet
|
|
sofort, sobald eine Aenderung eintrifft; sonst 204.
|
|
|
|
|
|
Der Feed arbeitet auf der **Historie**, nicht am Dokument: Ein
|
|
geloeschtes Dokument muss sein DELETED-Ereignis noch zustellen koennen.
|
|
404 gibt es deshalb nur bei gaenzlich unbekannter UUID.
|
|
|
|
|
|
Ist `since` bereits verdichtet, kann kein exaktes Diff mehr geliefert
|
|
werden - dann enthaelt die Antwort statt `ops` den **Volltext**, und
|
|
`fromVersion` fehlt. Der Client ersetzt seinen Stand.
|
|
parameters:
|
|
- name: since
|
|
in: query
|
|
required: true
|
|
description: Zuletzt gesehene Version; 0 fuer "noch nichts".
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
- name: wait
|
|
in: query
|
|
required: false
|
|
description: >
|
|
Wartezeit in Sekunden. Serverseitig geklemmt - ein Client darf
|
|
keine beliebig lange Verbindung binden.
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
default: 25
|
|
responses:
|
|
"200":
|
|
description: Aenderungen seit `since`
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ChangeFeed"
|
|
"204":
|
|
description: Nichts Neues innerhalb der Wartezeit
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
|
|
/taiga/auth:
|
|
post:
|
|
tags: [Taiga]
|
|
operationId: taigaLogin
|
|
summary: Bei Taiga anmelden (Proxy)
|
|
description: >
|
|
Reicht Benutzername und Passwort einmalig an die konfigurierte
|
|
Taiga-Instanz durch (`POST <api-url>/auth`, mit dem serverseitig
|
|
konfigurierten Login-Typ, Voreinstellung `ldap` - D91-Nachtrag 1).
|
|
Der Endpunkt sieht das Passwort nur im Durchflug: Der Server
|
|
speichert nichts und loggt den Request-Body nie; das Token gehoert
|
|
dem Browser. Bei der angekuendigten OIDC-Umstellung der Instanz wird
|
|
dieser Endpunkt durch den Redirect-Flow ersetzt - die uebrigen
|
|
Taiga-Endpunkte bleiben unveraendert (sie nehmen nur das Token).
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaAuthRequest"
|
|
responses:
|
|
"200":
|
|
description: Anmeldung gelungen
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaSession"
|
|
"400":
|
|
description: >
|
|
Zugangsdaten abgelehnt - Taiga meldet falsche Anmeldedaten als
|
|
400, der Status wird durchgereicht.
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/projects:
|
|
get:
|
|
tags: [Taiga]
|
|
operationId: taigaProjects
|
|
summary: Projekte des angemeldeten Nutzers auflisten (Proxy)
|
|
description: >
|
|
`GET <api-url>/projects?member=<userId>` - die Auswahlliste des
|
|
Projekt-Dialogs der Ticket-Anlage. Der `slug` ist zugleich der Wert
|
|
des Schlagworts `&taiga.<slug>` (SPEC par. 1).
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- name: member
|
|
in: query
|
|
required: true
|
|
description: Taiga-Benutzer-Id aus der Sitzung; filtert auf die eigenen Projekte.
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
responses:
|
|
"200":
|
|
description: Projekte des Nutzers
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TaigaProject"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/userstories:
|
|
post:
|
|
tags: [Taiga]
|
|
operationId: taigaCreateStory
|
|
summary: User Story anlegen (Proxy)
|
|
description: >
|
|
`POST <api-url>/userstories`. Die Antwort traegt die projektweite
|
|
`ref` - Werkbaum schreibt daraus `#US-<ref>` als Token an die
|
|
Knotenzeile (SPEC par. 11, D91-Nachtrag 2).
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaStoryCreateRequest"
|
|
responses:
|
|
"201":
|
|
description: Story wurde angelegt
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicket"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/tasks:
|
|
post:
|
|
tags: [Taiga]
|
|
operationId: taigaCreateTask
|
|
summary: Task unter einer User Story anlegen (Proxy)
|
|
description: >
|
|
`POST <api-url>/tasks`. Tasks haengen immer an einer Story
|
|
(`userStory` ist die Id, nicht die Ref) - storyless Tasks sind im
|
|
Kanban unsichtbar und werden bewusst nicht angeboten (D91). Die
|
|
Antwort traegt die `ref`; Werkbaum schreibt daraus `#T-<ref>`.
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTaskCreateRequest"
|
|
responses:
|
|
"201":
|
|
description: Task wurde angelegt
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicket"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/userstories/{ref}:
|
|
get:
|
|
tags: [Taiga]
|
|
operationId: taigaStoryByRef
|
|
summary: User Story ueber ihre Ref lesen (Proxy)
|
|
description: >
|
|
Loest `#US-<ref>` auf (D91-Nachtrag 6): Betreff, Status und
|
|
Zustaendiger einer Story. Refs sind nur **je Projekt** eindeutig -
|
|
deshalb der `slug`, den der Editor aus dem Schlagwort
|
|
`&taiga.<slug>` des Teilbaums nimmt (SPEC par. 1). Der Proxy fragt
|
|
dafuer zuerst `GET <api-url>/projects/by_slug`, dann
|
|
`GET <api-url>/userstories/by_ref?project=<id>&ref=<ref>`.
|
|
Nur gelesen: Werkbaum schreibt hier nichts nach Taiga und nichts in
|
|
den Notationstext.
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaRef"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
responses:
|
|
"200":
|
|
description: Die Story
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicketDetail"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: >
|
|
Projekt oder Ref gibt es nicht - Taigas Status wird
|
|
durchgereicht (der Editor zeigt den Fehlertext im Knoten-Fenster).
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/tasks/{ref}:
|
|
get:
|
|
tags: [Taiga]
|
|
operationId: taigaTaskByRef
|
|
summary: Task ueber ihre Ref lesen (Proxy)
|
|
description: >
|
|
Wie `GET /taiga/userstories/{ref}`, nur ueber
|
|
`GET <api-url>/tasks/by_ref` - loest `#T-<ref>` auf. Zwei Endpunkte
|
|
statt eines mit Typ-Parameter, weil das Praefix der Ref den Typ
|
|
traegt und Taiga getrennte `by_ref`-Endpunkte hat (SPEC par. 11).
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaRef"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
responses:
|
|
"200":
|
|
description: Die Task
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicketDetail"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: Projekt oder Ref gibt es nicht
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/userstories/{ref}/status:
|
|
patch:
|
|
tags: [Taiga]
|
|
operationId: taigaSetStoryStatus
|
|
summary: Status einer User Story setzen (Proxy)
|
|
description: >
|
|
Schreibt den Status zurueck (D91-Nachtrag 7/8) - die eine Haelfte des
|
|
Abgleichs, die der Benutzer im Knoten-Fenster ausdruecklich anstoesst;
|
|
von selbst geschieht nichts. `status` ist die **Id** einer Spalte aus
|
|
`GET /taiga/userstory-statuses` (die Namen sind je Projekt frei),
|
|
`version` die zuletzt gelesene: Hat jemand dazwischen geaendert, lehnt
|
|
Taigas optimistische Sperre ab und der Konflikt wird durchgereicht,
|
|
statt ihn zu ueberschreiben.
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaRef"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaStatusPatch"
|
|
responses:
|
|
"200":
|
|
description: Der neue Stand des Tickets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicketDetail"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: Projekt oder Ref gibt es nicht
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/tasks/{ref}/status:
|
|
patch:
|
|
tags: [Taiga]
|
|
operationId: taigaSetTaskStatus
|
|
summary: Status einer Task setzen (Proxy)
|
|
description: >
|
|
Wie `PATCH /taiga/userstories/{ref}/status`, nur fuer Tasks; die
|
|
Spalten kommen aus `GET /taiga/task-statuses`.
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaRef"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaStatusPatch"
|
|
responses:
|
|
"200":
|
|
description: Der neue Stand des Tickets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/TaigaTicketDetail"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: Projekt oder Ref gibt es nicht
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/userstory-statuses:
|
|
get:
|
|
tags: [Taiga]
|
|
operationId: taigaStoryStatuses
|
|
summary: Workflow-Spalten der Storys eines Projekts (Proxy)
|
|
description: >
|
|
`GET <api-url>/userstory-statuses?project=<id>`. Gebraucht zum
|
|
Schreiben: Taiga nimmt die Status-**Id**, und welche Spalte zu welcher
|
|
Statusbox gehoert, entscheidet der Editor (SPEC par. 4/9) - das
|
|
Backend parst die Notation nicht (D14).
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
responses:
|
|
"200":
|
|
description: Die Spalten des Projekts
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TaigaStatus"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: Projekt gibt es nicht
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/taiga/task-statuses:
|
|
get:
|
|
tags: [Taiga]
|
|
operationId: taigaTaskStatuses
|
|
summary: Workflow-Spalten der Tasks eines Projekts (Proxy)
|
|
description: Wie `GET /taiga/userstory-statuses`, nur fuer Tasks.
|
|
parameters:
|
|
- $ref: "#/components/parameters/TaigaToken"
|
|
- $ref: "#/components/parameters/TaigaSlug"
|
|
responses:
|
|
"200":
|
|
description: Die Spalten des Projekts
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TaigaStatus"
|
|
"401":
|
|
description: Token fehlt oder ist abgelaufen
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"404":
|
|
description: Projekt gibt es nicht
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
"502":
|
|
$ref: "#/components/responses/TaigaUnavailable"
|
|
"503":
|
|
$ref: "#/components/responses/TaigaNotConfigured"
|
|
|
|
/info:
|
|
get:
|
|
tags: [Documents]
|
|
operationId: getInfo
|
|
summary: Name und Version des Dienstes
|
|
description: >
|
|
Offen und ohne Nebenwirkung - gedacht als Lebendprobe fuer Deploy und
|
|
Ueberwachung. Ohne diesen Endpunkt bliebe dafuer nur eine Anfrage nach
|
|
einem Dokument, das es nicht gibt, und man muesste auf eine 404 hoffen:
|
|
Ein erwarteter Fehler ist eine schlechte Zusicherung, weil ihn auch ein
|
|
falsch konfigurierter Proxy liefert.
|
|
responses:
|
|
"200":
|
|
description: Der Dienst laeuft
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ServiceInfo"
|
|
|
|
components:
|
|
parameters:
|
|
TaigaToken:
|
|
name: X-Taiga-Token
|
|
in: header
|
|
required: true
|
|
description: >
|
|
Das Taiga-Token aus `POST /taiga/auth`, nackt (ohne `Bearer `-Praefix).
|
|
Der Proxy setzt daraus den `Authorization: Bearer <token>`-Header der
|
|
Weiterleitung. Bewusst ein eigener Header-Name: Einen Header-Parameter
|
|
namens `Authorization` muessen OpenAPI-Werkzeuge laut Spezifikation
|
|
ignorieren, und der Name kollidierte mit dem Master-Passwort (Basic).
|
|
schema:
|
|
type: string
|
|
maxLength: 512
|
|
|
|
TaigaRef:
|
|
name: ref
|
|
in: path
|
|
required: true
|
|
description: >
|
|
Die nackte Taiga-Nummer, ohne das Werkbaum-Praefix: aus `#US-123`
|
|
bzw. `#T-1234` wird `123` bzw. `1234`. Den Typ traegt der Pfad.
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
|
|
TaigaSlug:
|
|
name: slug
|
|
in: query
|
|
required: true
|
|
description: >
|
|
Projekt-Slug aus dem Schlagwort `&taiga.<slug>` (SPEC par. 1). Refs
|
|
laufen je Projekt fortlaufend - ohne das Projekt ist eine Ref nicht
|
|
eindeutig.
|
|
schema:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
|
|
responses:
|
|
TaigaNotConfigured:
|
|
description: >
|
|
Keine Taiga-Instanz konfiguriert (`werkbaum.taiga.api-url`) - der
|
|
Editor fragt vorher `GET /info` (`taiga`) und zeigt die Aktionen
|
|
dann gar nicht erst.
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
TaigaUnavailable:
|
|
description: Taiga-Instanz nicht erreichbar oder antwortet fehlerhaft
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
NotFound:
|
|
description: Ressource nicht gefunden
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
BadRequest:
|
|
description: Ungueltige Anfrage
|
|
content:
|
|
application/problem+json:
|
|
schema:
|
|
$ref: "#/components/schemas/ProblemDetail"
|
|
|
|
schemas:
|
|
Document:
|
|
type: object
|
|
required: [id, title, content, version, createdAt, updatedAt]
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
title:
|
|
type: string
|
|
maxLength: 255
|
|
content:
|
|
type: string
|
|
description: >
|
|
Opaker Inhalt. Bei clientseitiger Verschluesselung enthaelt dieses
|
|
Feld spaeter den Ciphertext.
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
description: Wird bei jeder Aenderung inkrementiert (Basis fuer Live-Editing/Konflikterkennung).
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
|
|
DocumentCreateRequest:
|
|
type: object
|
|
required: [title, content]
|
|
properties:
|
|
title:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
content:
|
|
type: string
|
|
|
|
DocumentUpdateRequest:
|
|
type: object
|
|
required: [title, content]
|
|
properties:
|
|
title:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
content:
|
|
type: string
|
|
expectedVersion:
|
|
type: integer
|
|
format: int64
|
|
description: Optional; wird spaeter fuer Optimistic Locking ausgewertet.
|
|
|
|
DocumentHistoryEntry:
|
|
description: >
|
|
Ein Stand der nutzersichtbaren Historie. Sync-Versionen des
|
|
Live-Editings erscheinen hier nicht - sie tragen das Protokoll, nicht
|
|
die Erzaehlung.
|
|
type: object
|
|
required: [documentId, version, title, content, changeType, timestamp]
|
|
properties:
|
|
documentId:
|
|
type: string
|
|
format: uuid
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
title:
|
|
type: string
|
|
content:
|
|
type: string
|
|
changeType:
|
|
type: string
|
|
description: >
|
|
RESTORED heisst: ein geloeschtes Dokument ist wieder da.
|
|
ROLLED_BACK ist der Rueckfall eines lebenden Dokuments auf eine
|
|
aeltere Version.
|
|
enum: [CREATED, UPDATED, RENAMED, DELETED, RESTORED, ROLLED_BACK]
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
clientId:
|
|
type: string
|
|
description: Fehlt bei Aenderungen ohne Absender (etwa ueber PUT).
|
|
displayName:
|
|
type: string
|
|
description: >
|
|
Selbstgewaehlt und ohne Anmeldung eine Behauptung - in der
|
|
Oberflaeche nicht wie ein Nachweis darstellen. Traegt das
|
|
"geaendert von" der Historie (D86).
|
|
|
|
TitlePatchRequest:
|
|
type: object
|
|
required: [title, expectedVersion]
|
|
properties:
|
|
title:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
expectedVersion:
|
|
type: integer
|
|
format: int64
|
|
description: >
|
|
Die Version, auf der die Umbenennung aufsetzt - weicht sie von der
|
|
aktuellen ab, antwortet der Server mit 409.
|
|
|
|
RestoreRequest:
|
|
type: object
|
|
properties:
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
description: >
|
|
Optionale Zielversion. Ohne Angabe wird der letzte inhaltliche
|
|
Stand vor dem Loeschen wiederhergestellt.
|
|
|
|
LineOperation:
|
|
description: >
|
|
Eine Zeilen-Operation relativ zur Basisversion (0-basierter Index).
|
|
Operationen sind aufsteigend sortiert und ueberschneiden sich nicht.
|
|
type: object
|
|
required: [op, index]
|
|
properties:
|
|
op:
|
|
type: string
|
|
enum: [replace, insert, delete]
|
|
index:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
count:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
description: Zahl der betroffenen Basiszeilen; bei `insert` ohne Bedeutung.
|
|
lines:
|
|
type: array
|
|
description: Einzusetzende Zeilen; bei `delete` ohne Bedeutung.
|
|
items:
|
|
type: string
|
|
|
|
ContentPatchRequest:
|
|
type: object
|
|
required: [baseVersion, checksum, clientId, seq, ops]
|
|
properties:
|
|
baseVersion:
|
|
type: integer
|
|
format: int64
|
|
description: Version, gegen die das Diff gebildet wurde.
|
|
checksum:
|
|
type: string
|
|
description: >
|
|
Pflicht. `sha256:<hex>` des vollstaendigen Basistexts mit
|
|
LF-Zeilenenden. Die Versionsnummer bestaetigt nur, dass die Basis
|
|
dieselbe Version ist, nicht dass beide Seiten sie gleich lesen.
|
|
clientId:
|
|
type: string
|
|
maxLength: 64
|
|
description: Zufaellige, pseudonyme Kennung des Clients.
|
|
seq:
|
|
type: integer
|
|
format: int64
|
|
description: Laufende Nummer dieses Clients; macht den Aufruf wiederholbar.
|
|
displayName:
|
|
type: string
|
|
maxLength: 64
|
|
description: >
|
|
Selbstgewaehlter Anzeigename. Ohne Anmeldung ist er eine
|
|
Behauptung und darf in der Oberflaeche nicht wie ein Nachweis
|
|
aussehen.
|
|
milestone:
|
|
type: boolean
|
|
default: false
|
|
description: >
|
|
`true` schreibt einen nutzersichtbaren Stand (Knopfdruck).
|
|
Der getaktete Strom laesst das Feld weg.
|
|
ops:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/LineOperation"
|
|
|
|
ContentPatchResult:
|
|
type: object
|
|
required: [version, opsSinceBase]
|
|
properties:
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
description: Neue Version des Dokuments.
|
|
opsSinceBase:
|
|
type: array
|
|
description: >
|
|
Leer, wenn die Basis noch aktuell war. Sonst die fremden
|
|
Operationen, um die der Server verschoben hat.
|
|
items:
|
|
$ref: "#/components/schemas/LineOperation"
|
|
|
|
ContentConflict:
|
|
type: object
|
|
required: [currentVersion, opsSinceBase]
|
|
properties:
|
|
currentVersion:
|
|
type: integer
|
|
format: int64
|
|
opsSinceBase:
|
|
type: array
|
|
description: Diff von der eingereichten Basis bis zur aktuellen Version.
|
|
items:
|
|
$ref: "#/components/schemas/LineOperation"
|
|
|
|
ChangeEvent:
|
|
description: Was an einer Version geschehen ist und wer sie eingereicht hat.
|
|
type: object
|
|
required: [version, changeType]
|
|
properties:
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
changeType:
|
|
type: string
|
|
enum: [CREATED, UPDATED, RENAMED, DELETED, RESTORED, ROLLED_BACK]
|
|
clientId:
|
|
type: string
|
|
description: Fehlt bei Aenderungen ohne Absender (etwa ueber PUT).
|
|
displayName:
|
|
type: string
|
|
description: >
|
|
Selbstgewaehlt und ohne Anmeldung eine Behauptung - in der
|
|
Oberflaeche nicht wie ein Nachweis darstellen.
|
|
title:
|
|
type: string
|
|
description: >
|
|
Nur bei RENAMED - der neue Titel im Klartext, damit der Client
|
|
ihn ohne weiteren Abruf uebernehmen kann (D76).
|
|
|
|
ChangeFeed:
|
|
type: object
|
|
required: [currentVersion, events]
|
|
properties:
|
|
fromVersion:
|
|
type: integer
|
|
format: int64
|
|
description: >
|
|
Basis des mitgelieferten Diffs. Fehlt, wenn stattdessen `content`
|
|
geliefert wird.
|
|
currentVersion:
|
|
type: integer
|
|
format: int64
|
|
ops:
|
|
type: array
|
|
description: Kumuliertes Diff von `fromVersion` bis `currentVersion`.
|
|
items:
|
|
$ref: "#/components/schemas/LineOperation"
|
|
content:
|
|
type: string
|
|
description: >
|
|
Volltext statt Diff - wenn `since` bereits verdichtet ist oder der
|
|
Client noch gar nichts hat (`since=0`).
|
|
events:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/ChangeEvent"
|
|
|
|
ServiceInfo:
|
|
type: object
|
|
required: [name, version]
|
|
properties:
|
|
name:
|
|
type: string
|
|
version:
|
|
type: string
|
|
builtAt:
|
|
type: string
|
|
format: date-time
|
|
description: Fehlt, wenn ohne Build-Informationen gestartet (z. B. aus der IDE).
|
|
taiga:
|
|
type: boolean
|
|
description: >
|
|
true, wenn eine Taiga-Instanz konfiguriert ist
|
|
(`werkbaum.taiga.api-url`) - der Editor zeigt die Ticket-Aktionen
|
|
im Knoten-Fenster nur dann (D91).
|
|
taigaWeb:
|
|
type: string
|
|
description: >
|
|
Basis-URL des Taiga-Frontends (`werkbaum.taiga.web-url`), ohne
|
|
abschliessenden Schraegstrich - der Editor baut daraus die Links
|
|
zum Oeffnen einer Ticket-Referenz
|
|
(`<web>/project/<slug>/us/<ref>` bzw. `.../task/<ref>`).
|
|
Fehlt, wenn nicht konfiguriert; das Oeffnen entfaellt dann.
|
|
|
|
TaigaAuthRequest:
|
|
type: object
|
|
required: [username, password]
|
|
properties:
|
|
username:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
password:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 255
|
|
description: Wird nur durchgereicht - nie gespeichert, nie geloggt.
|
|
|
|
TaigaSession:
|
|
type: object
|
|
required: [authToken, userId, username]
|
|
properties:
|
|
authToken:
|
|
type: string
|
|
description: >
|
|
Bearer-Token der Taiga-Sitzung. Es gehoert dem Browser; der
|
|
Server merkt sich nichts davon.
|
|
userId:
|
|
type: integer
|
|
format: int64
|
|
description: Taiga-Benutzer-Id - der `member`-Filter der Projektliste.
|
|
username:
|
|
type: string
|
|
fullName:
|
|
type: string
|
|
|
|
TaigaProject:
|
|
type: object
|
|
required: [id, name, slug]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
name:
|
|
type: string
|
|
slug:
|
|
type: string
|
|
description: >
|
|
Zugleich der Wert des Schlagworts `&taiga.<slug>` im
|
|
Notationstext (SPEC par. 1, D91-Nachtrag 3).
|
|
|
|
TaigaStoryCreateRequest:
|
|
type: object
|
|
required: [project, subject]
|
|
properties:
|
|
project:
|
|
type: integer
|
|
format: int64
|
|
description: Taiga-Projekt-Id (aus der Projektliste).
|
|
subject:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 500
|
|
|
|
TaigaTaskCreateRequest:
|
|
type: object
|
|
required: [project, subject, userStory]
|
|
properties:
|
|
project:
|
|
type: integer
|
|
format: int64
|
|
subject:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 500
|
|
userStory:
|
|
type: integer
|
|
format: int64
|
|
description: Id (nicht Ref) der User Story, unter der die Task haengt.
|
|
|
|
TaigaTicket:
|
|
type: object
|
|
required: [id, ref, subject]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
ref:
|
|
type: integer
|
|
format: int64
|
|
description: >
|
|
Projektweite Nummer, fortlaufend ueber alle Typen. Werkbaum
|
|
schreibt daraus `#US-<ref>` bzw. `#T-<ref>` an die Knotenzeile -
|
|
die Praefixe traegt Werkbaum selbst, Taiga zeigt nur `#<ref>`
|
|
(D91-Nachtrag 2).
|
|
subject:
|
|
type: string
|
|
|
|
TaigaTicketDetail:
|
|
type: object
|
|
description: >
|
|
Der gelesene Stand eines Tickets (D91-Nachtrag 6) - schmal wie alles
|
|
hier: genau die Felder, die das Knoten-Fenster zeigt.
|
|
required: [id, ref, subject]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
ref:
|
|
type: integer
|
|
format: int64
|
|
subject:
|
|
type: string
|
|
status:
|
|
type: string
|
|
description: >
|
|
Name des Taiga-Workflow-Status (`status_extra_info.name`), z. B.
|
|
"In progress". Die Abbildung auf die Statusbox der Notation macht
|
|
der Editor (SPEC par. 4/9) - das Backend parst die Notation nicht
|
|
(D14). Fehlt, wenn Taiga den Namen nicht mitliefert.
|
|
statusClosed:
|
|
type: boolean
|
|
description: Taigas eigene Aussage, ob der Status als erledigt gilt.
|
|
assignee:
|
|
type: string
|
|
description: >
|
|
Anzeigename des Zustaendigen
|
|
(`assigned_to_extra_info.full_name_display`); fehlt, wenn niemand
|
|
zugewiesen ist.
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
description: >
|
|
Taigas optimistische Sperre. Sie geht beim Schreiben unveraendert
|
|
zurueck (`PATCH .../status`); passt sie nicht mehr, lehnt Taiga ab
|
|
und der Konflikt wird durchgereicht.
|
|
|
|
TaigaStatus:
|
|
type: object
|
|
description: Eine Spalte des Projekt-Workflows (D91-Nachtrag 8).
|
|
required: [id, name]
|
|
properties:
|
|
id:
|
|
type: integer
|
|
format: int64
|
|
name:
|
|
type: string
|
|
description: >
|
|
Frei benannt, je Projekt verschieden - die Zuordnung zur Statusbox
|
|
der Notation macht der Editor.
|
|
closed:
|
|
type: boolean
|
|
|
|
TaigaStatusPatch:
|
|
type: object
|
|
required: [status, version]
|
|
properties:
|
|
status:
|
|
type: integer
|
|
format: int64
|
|
description: Id der Zielspalte (aus den Status-Listen), nicht ihr Name.
|
|
version:
|
|
type: integer
|
|
format: int64
|
|
description: Die zuletzt gelesene Version des Tickets.
|
|
|
|
ProblemDetail:
|
|
type: object
|
|
description: Fehlerformat nach RFC 9457 (Problem Details)
|
|
properties:
|
|
type:
|
|
type: string
|
|
title:
|
|
type: string
|
|
status:
|
|
type: integer
|
|
detail:
|
|
type: string
|
|
instance:
|
|
type: string
|
|
|
|
securitySchemes:
|
|
masterPassword:
|
|
type: http
|
|
scheme: basic
|
|
description: >
|
|
Master-Passwort fuer die Dokumentenliste. Der Hash liegt serverseitig
|
|
in einer Umgebungsvariable (`werkbaum.master-password.hash`); ist er
|
|
nicht gesetzt, bleibt die Liste gesperrt.
|
|
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: >
|
|
Noch nicht aktiv. Wird bei Einfuehrung der Autorisierung auf die
|
|
Operationen angewendet (security: - bearerAuth: []).
|