Revisionssichere Datenhaltung mit ArcadeDB

Die NOSQL-Datenbank bietet eine einfache, intuitive Lösung für revisionsichere Buchungen. Im Ruby-Interface werden hierzu der »create«- und der »update«-Befehl modifiziert. Veränderungen an Datensätzen erweitern automatisch die Versionshistorie.

Revisionssicherheit ist für kaufmännische Applikationen unabhängig von der regulatorischen Notwendigkeit unabdingbar.

Revisionssichere Buchungen sind Buchungen, die den gesetzlichen Anforderungen an Ordnungsmäßigkeit, Vollständigkeit, Richtigkeit, Zeitgerechtigkeit und Ordnung entsprechen. Sie müssen so geführt werden, dass sie jederzeit nachvollziehbar und nachprüfbar sind. (bard.google.com)

In der Praxis wird zusätzlich zur eigentlichen Buchung ein Protokoll-Datensatz erzeugt, der die Historie des Vorgangs dokumentiert und sicherstellt, dass für Berichte nur validierte Daten herangezogen werden.

NOSQL-Datenbanken bieten hierfür elegante Lösungen an. Der ArcadeDB-Ruby-Adapter hält für diese Anforderung eine spezialisierte Datenbanklasse bereit.

  • Revisionssichere Datenbank-Typen tragen eingebettete Revisions-Stacks, auf denen Updates nicht veränderbar abgelegt sind.
  • Updates von Datensätzen in diesen Typen erzeugen zwingend einen neuen Revisions-Eintrag.
  • Die üblichen Datenbankabfragen werden von dem Plugin nicht verändert. Die Verarbeitungsgeschwindigkeit verringert sich hierdurch nicht.
  • Der Zugriff auf die Historie per Datenbankabfrage ist nicht vorgesehen. Die Historie ist aber aus den Revisionseinträgen rekonstruierbar.

Implementation

Revisionssichere Daten sind werden als Vertex gespeichert. Sie leiten sich vom spezialisierten Vertex Arcade::Revision ab.

module Arcade 
  class RevisionssichererVertex < Arcade::Revision 
    attribute  ...
  end

Der Protokoll-Stack wird als set of embedded revision-records realisiert. Es handelt sich um fest mit dem Buchungsdatensatz verbundene Dokumente (Klasse: Arcade::RevisionRecord). Sie können nicht vom Buchungsdatensatz gelöst werden. Datensätze können angefügt werden, aber nicht einzeln aus dem Verbund herausgelöst werden. Von der Klasse Arcade::Revision abgeleitete Datenbank-Klassen erben spezialisierte Insert- und Update- Methoden.

Anlegen eines revisionssicheren Datensatzes

Der insert Befehl legt automatisch den ersten Datensatz in den Revisions-Stack

  Member.insert( name: "Hubert", 
              vorname: "Hugo", 
           geburtstag: Date.new( 1976,3,15 ) ) { 'Datensatz angelegt' }

Im Hintergrund wird ein Revisionsdatensatz erzeugt. Der »Member«-Datensatz wird erzeugt. Anschließend wird ein »protocol-Datensatz angelegt und mit dem Member-Datensatz verbunden.

 p = RevisionRecord.create date: Date.today, 
                         action: "Datensatz angelegt" 

 m =  Member.insert        name: 'Hubert',
                        vorname: ...

 m.update_list        :protocol, p, modus: :first

 m.protocol =>  Datum    | User |  Action 
            =>  1.1.2024 | root |  Datensatz angelegt

Der Update-Prozess verläuft analog. Der Basisbefehl wird »umgebogen«. Zunächst werden die Bestandsdaten ermittelt, der Datensatz wird aktualisiert und anschließend der Protokoll-Datensatz angefügt.

 m.update( geburtstag: Date.new( 1978,3,15 ) ) { "Mitglied hat fehlerhafte Eingabe per mail mitgeteilt" }
 
   => p = RevisionRecord.create action: "Mit...",
                                 field: { geburtstag: m.geburtstag } 
   => m.update_list :protocol, p, modus: :append
   => m.update geburtstag: Date.new( 1978,3,15 )

 m.protocol =>  Datum    | User |  Action                                               | old
            =>  1.1.2024 | root |  Datensatz angelegt                                   |
            =>  1.2.2024 | root |  Mitglied hat fehlerhafte Eingabe per mail mitgeteilt | geburtstag: "1976-3-15"

Customisation

Arcade::Revision kann beim Start der Applikation benutzerspezifisch konfiguriert werden. Hierzu sind Klassenmethoden implementiert:

module Arcade 
  class RVertex < Arcade::Revision 
    attribute  ...
  end

end 

Arcade::RVertex.set_user 'hb'
Arcade::RVertex.set_initial_message 'Datensatz angelegt'

Danach können Datensätze mit den Standard insert Befehl angelegt werden. Für Updates ist die Standard-Message in Arcade::RevisionRecord selbst definiert und muss für eine benutzer­spezi­fische Anpassung als Block übergeben werden.