CodamAIDocs
Themafertig

Historie lesen

Wie POST /{id}/history Revisionen seitenweise liefert, welche Rechte nötig sind und warum auch gelöschte Objekte eine Historie haben.

Ausprägungen
normales ModellSingletongelöschtes Objektohne History-Rolle → 403unsichtbares Objekt → 404unbekannte id → leere Liste (Modell ohne Filter)blättern mit page und limit

Worum es geht

Die Historie ist die Liste aller Revisionen eines Objekts, die neueste zuerst. Du liest sie mit einem eigenen Endpunkt, den es nur bei auditierten Modellen gibt und nur, wenn er in der Endpunkt-Liste des Modells eingetragen ist.

Anfrage und Antwort

Historie eines Auftrags, zwei Einträge je Seite
Anfrage
POST /api/rest/order/7e1…/history
{
  "response": ["orderNr", "price"],
  "parameter": { "page": 0, "limit": 2 }
}
Antwort
{ "data": [
    { "revision": { "id": "7e1…", "orderNr": "A-1000", "price": 99.0 },
      "revisionMeta": { "ref": 51, "ts": 1790000300000, "username": "Ben Beispiel", … },
      "revisionType": "MOD" },
    { "revision": { "id": "7e1…", "orderNr": "A-1000", "price": 120.5 },
      "revisionMeta": { "ref": 42, "ts": 1790000200000, "username": "Anna Muster", … },
      "revisionType": "MOD" }
  ],
  "meta": { "error": false, "totalCount": 0, "currentPage": 0, … } }

Jeder Eintrag in data ist eine Revision mit drei Teilen: revision (der Stand des Objekts), revisionMeta (wer, wann, von wo) und revisionType (ADD, MOD, DEL). Die Felder von revisionMeta erklärt Was eine Revision festhält.

Was die Anfrage steuert

Teil der AnfrageWirkung in der Historie
responsePflicht. Welche einfachen Felder jede Revision zeigt. + und * liefern alle einfachen Felder, die du lesen darfst. Ein Feld mit eigener Leserolle fehlt ohne diese Rolle auch in jeder Revision, siehe Geschützte Werte.
Referenzen und Listen in responsewerden nicht ausgebaut. Die Historie zeigt nur die Felder des Objekts selbst.
parameter.page, parameter.limitBlättern. Ohne limit kommen alle Revisionen auf einmal.
Filter und Sortierung in parameterwerden nicht ausgewertet. Die Reihenfolge ist immer: neueste Revision zuerst.

Die Systemfelder _createdOn und _updatedOn bringen + und * in der Historie nicht mit. Den Zeitpunkt einer Revision liest du aus revisionMeta.ts. Siehe Audit ist nicht dasselbe wie Systemfelder.

Die Prüfungen

Der Weg von POST /{id}/history
  1. CDMS
    Endpunkt
    Ist das Modell auditiert und steht der History-Endpunkt in seiner Endpunkt-Liste?
    ↳ nein Den Endpunkt gibt es nicht
  2. CDMS
    Leserolle
    Hat die Person die Leserolle des Modells?
    ↳ nein 403
  3. CDMS
    Historienrolle
    Hat die Person die Historienrolle des Modells?
    ↳ nein 403
  4. CDMS
    Sichtbarkeit
    Hätte die Person das Objekt lesen dürfen – Owner-Filter und Attributfilter?
    ↳ nein 404
  5. Die Revisionen zur id werden geliefert, neueste zuerst

Beide Rollen stehen im Modell. Welche Namen sie tragen, steht unter Modellrollen. Im Strict Mode heißt der Fehler missing-permission|<rolle>, ohne Strict Mode missing-read-role oder missing-history-role. Siehe Strict Mode.

Die Rollen sagen, ob jemand Historien dieses Modells lesen darf – nicht, welche. Das entscheiden dieselben Zeilenfilter wie beim Lesen und Suchen: der Owner-Filter und die Attributfilter. Wer ein Objekt nicht lesen kann, bekommt auch seine Historie nicht.

Bei einem gelöschten Objekt gibt es keine Zeile mehr, an der sich das prüfen ließe. CDMS nimmt dafür die letzte Revision vor der Löschung: Sie trägt Eigentümer und Attributwerte noch, und die Filter werden auf sie angewendet. Die DEL-Revision taugt dafür nicht, ihre Felder sind leer.

Hat ein Modell weder Owner- noch Attributfilter, gibt es nichts zu prüfen – dort entscheiden die beiden Rollen allein.

Die Ausprägungen

Historie in vier Fällen

Wann: POST /{basis}/{id}/history für ein bestehendes Objekt

Alle Revisionen des Objekts, die neueste zuerst. Die erste ist ein ADD, danach folgen MOD-Revisionen, auch die eines Rollbacks.

Wann: POST /{basis}/history, ohne id im Pfad

  1. 1
    Client→CDMS
    schickt POST /api/rest/tenant/preferences/history mit response
  2. 2
    CDMS
    sucht das eine Objekt, das zur Person oder zum Mandanten gehört
  3. 3
    CDMS→Client
    kein Objekt da → 404 data-not-found
  4. 4
    CDMS→Client
    Objekt da → prüft die Rollen und liefert seine Historie wie beim normalen Modell

Wann: POST /{basis}/{id}/history mit der id eines gelöschten Objekts

Die Historie bleibt lesbar – für die, die das Objekt lesen durften. Ob das zutrifft, entscheidet CDMS an der letzten Revision vor der Löschung, weil die Zeile selbst weg ist. Die neueste Revision ist ein DEL. Sie nennt Person und Zeitpunkt der Löschung, ihre Felder sind leer bis auf die id. Den letzten Inhalt findest du in der Revision davor. Bei einem Singleton geht das nicht: Ohne Objekt findet CDMS keine id und antwortet mit 404.

Ergebnis: Siehe Was nach dem Löschen bleibt.

Wann: Die Person hat die Leserolle, aber nicht die Historienrolle.

403. Es wird nichts geliefert, auch nicht teilweise. Dasselbe gilt ohne Leserolle.

Entscheidungstabelle

Was liefert POST /{id}/history?
Endpunkt vorhanden?Leserolle?Historienrolle?Sichtbar?Revisionen zur id?Antwort
nein––––Den Endpunkt gibt es nicht. Modell auditieren und Endpunkt eintragen.
janein–––403
jajanein––403
jajajanein–404 missing-object
jajajakein Filternein200, data ist eine leere Liste. Bei einem Modell ohne Filter ergibt eine unbekannte id kein 404.
jajajajaja200 mit den Revisionen, neueste zuerst

Bei einem Modell mit Filter ist eine unbekannte id nicht von einer verborgenen zu unterscheiden: Beide ergeben 404. Sonst wäre der Unterschied der Antworten eine Auskunft darüber, welche fremden ids es gibt.

Blättern

Mit page und limit holst du die Historie in Seiten, genau wie bei einer Suche. page beginnt bei 0. Lässt du limit weg, kommen alle Revisionen auf einmal.

Anders als bei einer Suche füllt die Historie meta nicht: totalCount, currentPage und currentLimit stehen immer auf 0. Die Gesamtzahl erfährst du also nicht vorab. Blättere weiter, bis eine Seite weniger Einträge hat als limit.

Die ganze Historie in Seiten zu je 20 holen
  1. 1
    Client→CDMS
    page: 0, limit: 20 → 20 Einträge
  2. 2
    Client→CDMS
    page: 1, limit: 20 → 20 Einträge
  3. 3
    Client→CDMS
    page: 2, limit: 20 → 7 Einträge
    Ergebnis: Weniger als 20, also ist das die letzte Seite. Insgesamt 47 Revisionen.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-rest-api – AbstractRestApi.getHistory (nur fields, parameter), AbstractRestSingletonApi.getHistory (getExistingData, data-not-found), Expander.expandResponse
  • CDMS/cdms-system-layer – AbstractLayer.queryHistory (Leserolle, Historienrolle, assertHistoryVisible)
  • CDMS/cdms-persistence-database – AuditHistoryReader.queryHistory (forRevisionsOfEntity mit gelöschten, neueste zuerst, page/limit nur bei limit > 0, recursiveRemoveObjects)
  • CDMS/cdms-commons – AuditQueryResponse, AuditRevision, AuditRevisionMeta, QueryMetaResponse
  • CDMS/cdms-generator – ApiProcessor.getHistoryMethod, ApiSingletonProcessor.getHistoryMethod
  • CDMS/cdms-integrationtest – AbstractAuditTrailTest (history mit order-history + order-read), AbstractSingletonRollbackTest.history
Suchen