Worum es geht
CRMS speichert Vorlagen, Journale und die Einträge endgültiger Dokumente in einer Datenbank. Die Dateien der Dokumente selbst liegen im S3-Bucket, nicht in der Datenbank.
CRMS hat dafür keinen eigenen Datenbankweg. Es nutzt die gemeinsame Datenbankschicht von CodamAI, dieselbe wie CDMS. Sie wählt je Anfrage den Entity Manager der System-Datenbank oder der Mandanten-Datenbank des Aufrufers. Ein Entity Manager ist das Objekt, über das JPA Zeilen liest und schreibt.
Welche Datenbank
| eingebettet | eigener Dienst | |
|---|---|---|
| Datenbank | die Datenbank der CDMS-Anwendung | eine eigene Datenbank |
| Variablen | die der Anwendung, nichts zusätzlich | CODAMAI_PERSISTENCE_*, Pflicht |
| Transaktion | dieselbe wie die der Anwendung, dieselben Pools | eigene |
| Tabellen | neben den Tabellen der Anwendung | nur die CRMS-Tabellen |
System und Mandant
Wie bei CDMS gibt es zwei Arten, eine Installation zu betreiben (siehe SINGLE und MULTI):
SINGLE: Eine Datenbank hält alles.MULTI: Eine System-Datenbank und je Mandant eine eigene Datenbank.
Jedes CRMS-Modul legt dieselben Tabellen in der System-Datenbank und in jeder Mandanten-Datenbank an. In welche eine Zeile kommt, entscheidet, wem sie gehört:
| Was | Wohin |
|---|---|
Systemvorlagen (Scope SYSTEM) | System-Datenbank |
| Vorlagen eines Mandanten und eines Benutzers | Datenbank des Mandanten des Aufrufers |
| endgültige Dokumente | Datenbank des Mandanten des Aufrufers, ohne Mandant die System-Datenbank |
Bei SINGLE ist das dieselbe Datenbank.
Die Variablen des eigenen Diensts
| Variable | Bedeutung | Vorgabe |
|---|---|---|
CODAMAI_PERSISTENCE_TENANT_MODE | SINGLE oder MULTI | Pflicht |
CODAMAI_PERSISTENCE_DATABASE_DRIVER | JDBC-Treiberklasse, etwa com.mysql.cj.jdbc.Driver | Pflicht |
CODAMAI_PERSISTENCE_DATABASE_URL | JDBC-URL mit dem Platzhalter {tenant}. Er wird zu single, system oder dem Schlüssel eines Mandanten | Pflicht |
CODAMAI_PERSISTENCE_DATABASE_USER, _PASSWORD | das Datenbankkonto | Pflicht |
CODAMAI_PERSISTENCE_DATABASE_POOL_SIZE | Größe eines Verbindungspools | 20 |
CODAMAI_PERSISTENCE_DATABASE_AUTO_UPDATE | Hibernate passt das Schema beim Start an | true |
CODAMAI_PERSISTENCE_DATABASE_AUTO_CREATE_TENANT_DATABASE | eine fehlende Mandanten-Datenbank beim ersten Zugriff anlegen | false |
CODAMAI_PERSISTENCE_DATABASE_SHOW_SQL | SQL ins Log schreiben | false |
Eingebettet setzt du keine davon zusätzlich. CRMS nutzt, was die Anwendung schon hat.
Das Schema
- Aus den Entities. Hibernate baut die Tabellen aus den Entity-Klassen. CRMS liefert keine eigenen SQL-Skripte mit.
- Portabel. Aufzählungen liegen als Text in
VARCHAR-Spalten, nicht als datenbankeigenerENUM-Typ. Es gibt keine herstellerspezifischen Spaltendefinitionen. Deshalb läuft CRMS auf jeder Datenbank, die der CDMS-Rahmen anbietet. - Abfragen über die Criteria API. Kein Modul schreibt SQL oder JPQL als Text.
Die Tabellen heißen alle crms_…:
| Bereich | Tabellen |
|---|---|
| Vorlagenverwaltung | crms_template_edition, crms_template_variant, crms_template_entry, crms_template_content, crms_template_asset, crms_template_blob, crms_template_draft |
| Nachweis | crms_journal_entry, crms_journal_head, crms_anchor, crms_anchor_proof, crms_document_key |
| Dokumentablage | crms_document_entry, crms_document_payload, crms_document_retention |
Nur anhängen
Was einmal geschrieben ist, ändert CRMS nicht mehr. Die Entities dieser Tabellen sind @Immutable: Hibernate schreibt für sie nie ein UPDATE. Kein Modul ruft für sie Löschen, Zusammenführen oder Massenänderungen auf. Ein Architekturtest je Modul verlangt das.
Nur vier Tabellen werden geändert, jede aus einem benannten Grund:
| Tabelle | Was sich ändert |
|---|---|
crms_template_draft | der Entwurf einer Vorlage, beim Speichern des Entwurfs |
crms_journal_head | der Kopf eines Journals. Er wird beim Anhängen gesperrt, damit Schreibende nacheinander drankommen |
crms_document_key | nur das Vernichten eines Dokumentschlüssels. Die Zeile bleibt als Grabstein |
crms_document_retention | die Arbeitsliste der Aufbewahrung: done_at, wenn ein Dokument entfernt ist |
Was gegen Änderungen schützt, ist die Hash-Kette: Jeder Eintrag enthält den Hash des vorigen, und der Kopf jedes Journals bekommt einen Zeitstempel außerhalb der Datenbank. Wer mit Datenbankzugang eine Zeile ändert, wird beim Prüfen erkannt. Siehe Die Hash-Kette.