CodamAIDocs
Themafertig

Auf einen alten Stand zurücksetzen

Ein Rollback erzeugt eine neue Revision mit dem alten Inhalt. Was zurückkommt (eigene Felder, Einzelreferenzen) und was nicht (Listen, gelöschte Objekte).

Ausprägungen
einfache FelderEinzelreferenzenListen (nicht)gelöschtes Objekt (nicht)fremde Revision → abgelehntSingleton

Worum es geht

Ein Rollback setzt ein Objekt auf den Stand einer älteren Revision zurück. Du nennst dazu die id des Objekts und die Nummer der Revision, die du aus der Historie kennst (revisionMeta.ref).

Die Historie wird dabei nicht umgeschrieben. CDMS schreibt den alten Stand als neue Revision auf das Objekt, so wie bei einer normalen Änderung. Alle Revisionen dazwischen bleiben, und auch den Rollback selbst kannst du wieder zurücknehmen.

Vorher und nachher

flowchart LR
    subgraph V["vorher"]
      A["17 · ADD<br/>price 90.8"] --> B["42 · MOD<br/>price 120.5"] --> C["51 · MOD<br/>price 99.0"]
    end
    subgraph N["nachher"]
      A2["17 · ADD<br/>price 90.8"] --> B2["42 · MOD<br/>price 120.5"] --> C2["51 · MOD<br/>price 99.0"] --> D2["58 · MOD<br/>price 90.8<br/>Rollback auf 17"]
    end
    V -- "POST /{id}/rollback/17" --> N
Rollback eines Auftrags auf Revision 17
Anfrage
POST /api/rest/order/7e1…/rollback/17
{ "response": ["orderNr", "price", "_updatedOn"] }
Antwort
{ "data": { "id": "7e1…", "orderNr": "A-1000", "price": 90.8,
            "_updatedOn": "2026-09-20 14:05:11" },
  "meta": { "error": false, … } }

Die Antwort ist dieselbe wie beim Lesen: das Objekt im neuen Stand mit den Feldern aus response. response ist Pflicht. Siehe Feldauswahl mit response.

Der Ablauf

POST /order/{id}/rollback/{revision}
  1. 1
    Client→CDMS
    schickt POST /order/7e1…/rollback/17 mit response
  2. 2
    CDMS
    Ist das Objekt für die Person sichtbar? Es wird mit denselben Filtern gesucht wie beim Ändern.
    Nein, oder gelöscht → 404 not-found|<Dto>|<id>. Siehe Warum Unsichtbares 404 liefert.
  3. 3
    CDMS
    Hat die Person die Rollback-Rolle des Modells?
    Nein → 403.
  4. 4
    Hook
    Die Before-Hooks für ROLLBACK laufen, mit dem Objekt im aktuellen Stand.
  5. 5
    CDMS→Datenbank
    Gehört Revision 17 zu diesem Objekt?
    Revision 0 oder kleiner → 400 invalid-history-revision|<nr>. Keine Revision dieses Objekts → 404 history-revision-not-found|<nr>.
  6. 6
    CDMS→Datenbank
    kopiert den Stand von Revision 17 auf das Objekt: einfache Felder und Einzelreferenzen
    Eine Einzelreferenz, deren Ziel inzwischen gelöscht ist → 404 history-relation-not-found|<feld>|<id>.
  7. 7
    CDMS
    Darfst du die Ziele lesen, die der Rollback umhängt?
    Geprüft werden nur Einzelreferenzen, die sich ändern: das alte und das neue Ziel, wie beim Verknüpfen und Lösen. Ziel für dich unsichtbar → 404 missing-object|<id>|<Modell>. Leserolle des Zielmodells fehlt → 403. Beides verwirft den ganzen Rollback.
  8. 8
    CDMS→Dateispeicher
    bei Datei-Modellen: holt den Inhalt zurück, der zu Revision 17 gehört
  9. 9
    Hook
    Die After-Hooks für ROLLBACK laufen, mit dem Objekt im zurückgesetzten Stand.
  10. 10
    CDMS→Client
    liest das Objekt mit response zurück und antwortet
    Ergebnis: Die Anfrage endet erfolgreich, Envers schreibt die neue Revision 58. Jeder Fehler unterwegs verwirft die ganze Änderung in der Datenbank.

Das Zurücklesen am Ende ist ein normales Lesen. Dafür brauchst du auch die Leserolle des Modells und die Rollen der Referenzen, die du in response nennst.

Was zurückkommt

Teil des ObjektsBeim Rollback
einfache Felder (Text, Zahl, Datum, Enum …)kommen zurück, auch null aus der alten Revision
Einzelreferenz (zeigt auf ein Objekt)kommt zurück: das Objekt zeigt wieder auf dasselbe Ziel wie damals. Das Ziel selbst wird nicht verändert. Hängt der Rollback dabei um, musst du altes und neues Ziel lesen dürfen.
Listen (1:n, n:m)bleiben, wie sie jetzt sind
idbleibt
_createdOnbleibt
_updatedOnbleibt unverändert, der Rollback setzt keinen neuen Zeitpunkt
_version bei Datei-Modellenwird hochgezählt wie bei jeder Änderung
Dateiinhaltkommt zurück, siehe Rollback bei Dateien
Felder, die es in der alten Revision noch nicht gabwerden leer

Mehr zu den Systemfeldern unter Systemfelder, die der Server setzt.

Die Ausprägungen

Was ein Rollback mit welchem Teil macht

Wann: Das Objekt hat seit Revision 17 andere Werte bekommen.

Jedes einfache Feld bekommt den Wert aus Revision 17. Auch Felder, die du nie geändert hast, werden geschrieben, dort ändert sich nur nichts.

Ergebnis: Neue MOD-Revision mit genau dem Stand von 17.

Wann: order.company zeigte in Revision 17 auf Firma A, heute auf Firma B.

Nach dem Rollback zeigt der Auftrag wieder auf Firma A. Die Firma selbst behält ihren heutigen Stand. Gibt es Firma A nicht mehr, scheitert der ganze Rollback mit 404 history-relation-not-found|company|<id>, und nichts wird geändert. Das Umhängen ist ein Verknüpfen: Darfst du Firma A oder Firma B nicht sehen, kommt 404 missing-object, fehlt dir die Leserolle für Firmen, kommt 403. Eine Änderungsrolle für Firmen brauchst du nicht.

Ergebnis: Zurückholen kannst du nur Ziele, die du heute lesen darfst. Siehe Die vier Fälle.

Wann: Der Auftrag hatte in Revision 17 zwei Positionen, heute drei.

Die Liste bleibt bei drei Positionen. Ein Rollback legt keine Kinder an, löscht keine und hängt keine um. Jede Position hat ihre eigene Historie, sofern ihr Modell auditiert ist. Du kannst sie einzeln zurücksetzen. Eine gelöschte Position kommt so aber nicht zurück.

Wann: Das Objekt wurde gelöscht, die Historie endet mit DEL.

404 not-found|<Dto>|<id>, weil es das Objekt nicht mehr gibt. Brauchst du es wieder, lege es neu an, mit einer neuen id.

Ergebnis: Siehe Was nach dem Löschen bleibt.

Wann: Die Nummer gehört zu einem anderen Objekt oder gibt es gar nicht.

404 history-revision-not-found|<nr>. CDMS prüft vorher, ob die Nummer in der Historie genau dieses Objekts steht. Eine Nummer 0 oder kleiner ergibt 400 invalid-history-revision|<nr>.

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

Der Server sucht das eine Objekt selbst und setzt es zurück wie jedes andere Objekt. Gibt es noch kein Objekt oder ist es gelöscht, kommt 404 data-not-found.

Ergebnis: Siehe Singletons: genau ein Objekt.

Entscheidungstabelle

Was passiert bei POST /{id}/rollback/{revision}?
Objekt sichtbar?Rollback-Rolle?Revision gehört zum Objekt?Referenzziele gibt es noch?Umgehängte Ziele lesbar?Ergebnis
nein––––404 not-found, auch bei gelöschtem Objekt
janein–––403
jajanein––404 history-revision-not-found (bei Nummer ≤ 0: 400)
jajajanein–404 history-relation-not-found, nichts geändert
jajajajanein404 missing-object (unsichtbar) bzw. 403 (Leserolle fehlt), nichts geändert
jajajajaja200, neuer Stand als neue MOD-Revision

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractSystemLayer.historyRollback (assertVisibleForWrite, Rollback-Rolle, ROLLBACK-Hooks, assertRestoredReferencesReadable, rollbackFileContent, flush, readObject), AbstractSystemSingletonLayer.historyRollback
  • CDMS/cdms-persistence-database – AuditHistoryReader.historyRollback, findRevision, copyRevisionState (Metamodell, ohne id/Version/Sammlungen, Referenzen per id neu aufgelöst), _updatedOn bleibt; docs/adr/ADR-019
  • CDMS/cdms-rest-api – AbstractRestApi.rollback, AbstractRestSingletonApi.rollback (Branch feature/singleton-rollback)
  • CDMS/cdms-generator – ApiProcessor.getRollbackMethod, ApiSingletonProcessor.getRollbackMethod (POST /rollback/{revision})
  • CDMS/cdms-integrationtest – AbstractFileRollbackTest (rollbackAddsARevisionInsteadOfRewritingOne, rollbackWithoutTheRoleIsRefused), AbstractSingletonRollbackTest, AbstractFieldRoleTest (aRollbackCannotRelinkAFilteredRecord, aRollbackAsksForTheReadRoleOfTheTarget, aRollbackLeavesAnUnchangedReferenceAlone); Probe: fremde Revision 404, Revision 0 → 400
Suchen