Module (NXM)
Daten und Aktualisierungen
Wo die Datensätze eines NXM-Moduls liegen, wie Paketdaten und Beispieldaten installiert werden, was eine neue Version ändern darf und was mit Ihren Daten beim Aktualisieren, Deaktivieren und Deinstallieren geschieht.
Ein NXM-Modul ist Code, den niemand im Mandanten selbst geschrieben hat, und es arbeitet mit Daten, die der Mandant nicht verlieren darf. Deshalb übernimmt nexxus die Verantwortung für diese Daten. Das Paket beschreibt seine Fachobjekte, die Plattform speichert, prüft, indiziert und migriert die Datensätze. Eine neue Version darf nur ändern, was sich gefahrlos ändern lässt. Jede Aktualisierung läuft in einer einzigen Transaktion, und bevor ein Modul deinstalliert wird, fragt nexxus, was mit seinen Daten geschehen soll.
Diese Seite begleitet einen Datensatz durch sein Leben: wie er gespeichert wird, wie ein Paket ihn bei der Installation anlegt, wie eine Aktualisierung ihn umbaut und was bleibt, wenn das Modul geht.
Wo die Datensätze liegen
Abschnitt betitelt „Wo die Datensätze liegen“nexxus hält die Datensätze aller Pakete in einem gemeinsamen Datensatzspeicher. Die Felder eines Datensatzes liegen dort als ein JSON-Dokument. Die Werte der Felder, die ein Paket als indexed oder unique kennzeichnet, und jeder Verweis werden in derselben Transaktion zusätzlich in typisierte Nachschlagetabellen geschrieben. Ein Paket zu installieren ändert deshalb nie das Datenbankschema: Es gibt keine Tabellen je Paket und kein DDL je Mandant.
Als Entwicklerin oder Entwickler merken Sie das an mehreren Stellen:
- Filtern und sortieren geht nur über indizierte Felder. Indiziert ist ein Feld mit
indexed: true, ein Feld mitunique, einsequence-Feld und jederref. Einen Filter auf ein anderes Feld lehnt nexxus mitNach '<feld>' lässt sich nicht filtern: das Feld ist nicht indexed.ab. - Auswerten geht ebenfalls nur über indizierte Felder. Jedes Fachobjekt ist eine Quelle für Kacheln, Benachrichtigungsregeln und den KI-Assistenten, siehe Quellen aus Paketen. Ein Feld, das dort auftauchen soll, braucht also
indexed: true. - Die Volltextsuche (
?q=in der API, das Suchfeld der Liste) durchsucht diesearchFieldsdes Fachobjekts, ohne auf Groß- und Kleinschreibung zu achten. Steht ein Verweis unter densearchFields, findet sie den Datensatz auch über den aktuellen Namen dessen, worauf er zeigt, und nur in dem, was die Person ohnehin sehen darf. - Eindeutige Werte vergleicht nexxus ohne Leerzeichen am Rand und ohne Rücksicht auf Groß- und Kleinschreibung.
12/26und12/26gelten als derselbe Wert. - Gelöschte Datensätze werden nur als gelöscht markiert. Der Datensatz verschwindet aus Listen und API, die Zeile bleibt in der Datenbank.
- In der globalen Suche erscheinen Datensätze von Paketen in dieser Version nicht.
So sieht ein Datensatz aus
Abschnitt betitelt „So sieht ein Datensatz aus“Ein Aktendokument aus der CuriaOS-Fallstudie, wie API und View-SDK es liefern. Die Werte stammen aus den Beispieldaten des Pakets, IDs, Datumsangaben und Person sind zur Veranschaulichung gewählt:
{ "id": 12, "module": "curiaos.kanzlei", "entity": "aktendokument", "title": "Vollmacht Sabine Vogl", "data": { "akte": 4, "dokument": 88, "titel": "Vollmacht Sabine Vogl", "typ": "vollmacht", "eingegangen_am": "2026-09-14", "status": "geprueft" }, "refs": { "akte": { "id": 4, "label": "2026/0184" }, "dokument": { "id": 88, "label": "2026-0184_vollmacht.pdf" } }, "version": 3, "createdAt": "2026-10-08T07:12:44Z", "updatedAt": "2026-10-08T09:30:02Z", "createdBy": { "id": 7, "name": "Jana Brandt" }, "updatedBy": { "id": 7, "name": "Jana Brandt" }}titleist der Wert destitleFielddes Fachobjekts, oder#<id>, wenn es keines gibt.refsliefert zu jedem Verweis eine lesbare Bezeichnung. Eine Ansicht muss die Verweise also nicht einzeln nachschlagen.dataenthält die kanonische Form jedes Werts: Datum alsYYYY-MM-DD, Zeitpunkte als ISO-8601 in UTC, Verweise als Zahl.
Versionen schützen vor dem Überschreiben
Abschnitt betitelt „Versionen schützen vor dem Überschreiben“Jeder Datensatz trägt eine version, die bei 0 beginnt. Schickt ein Client die Version, die er gelesen hat, mit seiner Änderung mit, lehnt nexxus das Schreiben ab, wenn jemand den Datensatz in der Zwischenzeit geändert hat. Die API antwortet mit HTTP 409, Code CONFLICT und der Meldung „Der Datensatz wurde inzwischen geändert (Version 4, gesendet 3). Bitte neu laden.“ Die Datensatzseite in der App zeigt „Jemand hat diesen Datensatz inzwischen geändert. Laden Sie ihn neu und tragen Sie Ihre Änderung danach erneut ein.“ mit der Schaltfläche Neu laden.
Eigene Ansichten sollten immer die gelesene Version mitschicken (nx.records.update(entity, id, patch, {version})). Dann kommt eine gleichzeitige Änderung als CONFLICT zurück und wird angezeigt, statt still überschrieben zu werden.
Werte, die nur die Plattform schreibt
Abschnitt betitelt „Werte, die nur die Plattform schreibt“Zwei Feldoptionen überlassen den Wert der Plattform:
readonly-Felder setzen Aktionen, Migrationsschritte, Paketdatendateien und Moduldienste, aber nie das Formular einer Person und nierecords.updateaus einer Ansicht. nexxus lehnt einen Schreibversuch einer Person nur ab, wenn sich der Wert wirklich ändert. Ein Formular, das den ganzen Datensatz unverändert zurückschickt, kommt also durch. CuriaOS nutzt das für den Status einer Frist: Auf „Erledigt“ setzt ihn nur die Vier-Augen-Aktion.sequence-Felder bekommen beim Anlegen die nächste Nummer, wenn das Feld leer ist. Das Format ist Text mit{yyyy},{yy}und genau einem{n}oder{n:<stellen>}, etwa{yyyy}/{n:4}für2026/0184. Der Zähler läuft je Mandant, Modul, Fachobjekt und Feld, und je Jahr, wenn das Format das Jahr enthält. Setzt eine Datendatei oder ein Moduldienst den Wert ausdrücklich, zieht der Zähler nach, und die nächste Nummer liegt darüber. Beim Bearbeiten eines Datensatzes vergibt nexxus keine Nummer. Einsequence-Feld ist immer eindeutig und schreibgeschützt.
Paketdaten und Beispieldaten
Abschnitt betitelt „Paketdaten und Beispieldaten“Ein Paket kann Datensätze mitbringen, in zwei Ordnern:
| Ordner | Wird installiert | Typischer Inhalt |
|---|---|---|
data/<entity>.json | immer, bei der Installation und bei jeder Aktualisierung erneut | Datensätze, die zum Produkt gehören: ein Anforderungskatalog, Standardkategorien |
demo/<entity>.json | bei der ersten Installation, wenn die Administration Beispieldaten anlegen anhakt; bei einer Aktualisierung die Zeilen, die die neue Version neu mitbringt, wenn sie Neue Beispieldaten anlegen anhakt | erfundene Musterdatensätze zum Ausprobieren |
demo/files/<name> | mit den Beispieldaten | Dateien (PDFs), auf die Beispieldatensätze verweisen |
Jede Datei ist ein JSON-Array. Jede Zeile hat einen paketinternen key und ein Objekt data mit den Feldwerten. Untereinander und auf Kerndaten verweisen die Zeilen über Platzhalter, die der Installer auflöst. Eine echte Zeile aus den CuriaOS-Beispieldaten:
{ "key": "d-0184-vollmacht", "data": { "akte": { "$key": "akte:2026-0184" }, "dokument": { "$file": "files/2026-0184_vollmacht.pdf" }, "titel": "Vollmacht Sabine Vogl", "typ": "vollmacht", "eingegangen_am": { "$date": "-17wd" }, "beteiligter": { "$key": "beteiligung:b-0184-vogl" }, "status": "geprueft" }}| Platzhalter | Wird zu |
|---|---|
{"$key": "<entity>:<key>"} | der ID des Datensatzes, der aus dieser Zeile des Pakets entstanden ist |
{"$key": "<entity>:<key>", "field": "<field>"} | dem Feldwert dieses Datensatzes statt seiner ID |
{"$file": "files/<name>.pdf"} | einem Dokument im Dateien-Ordner „<Modulname> (Beispieldaten)“ |
{"$partner": "<name>"} | dem Partner des Mandanten mit diesem Namen (ohne Rücksicht auf Groß- und Kleinschreibung); fehlt er, legt nexxus ihn wie das Partnerformular mit Nummer und Standard-Niederlassung an, sodass an ihn fakturiert werden kann |
{"$partner": "<name>", "email": "<adresse>"} | ebenso; ein Partner, den nexxus neu anlegt, bekommt diese E-Mail-Adresse (siehe unten) |
{"$project": "<bezeichnung>", "partner": "<name>"} | dem Projekt des Mandanten mit dieser Bezeichnung; fehlt es, legt nexxus es an, mit partner für diesen Partner |
{"$contact": "<vorname> <nachname>", "partner": "<name>", "email": "<adresse>"} | dem Kontakt dieses Namens bei diesem Partner; fehlt er, legt nexxus ihn mit dieser Adresse an (und optional "position"). partner und email sind Pflicht |
{"$currentUser": true} | der Person, die das Paket installiert |
{"$date": "<schritte>"} | einem Datum relativ zum Installationstag |
Musterkontakte mit E-Mail-Adresse
Abschnitt betitelt „Musterkontakte mit E-Mail-Adresse“Beispieldaten, die versendet werden sollen, etwa ein Schreiben an die Musterversicherung, brauchen einen Kontakt mit E-Mail-Adresse: {"$partner": "Muster Rechtsschutz eG", "email": "rsv@muster-rechtsschutz.example"}. Erlaubt sind nur Adressen unter den reservierten Top-Level-Domains .example, .test und .invalid, damit eine Demo nie eine echte Person anschreibt. Jede andere Adresse, und alles, was keine Adresse ist, lehnt nexxus beim Hochladen ab, etwa mit „E-Mail ‘rsv@muster-rechtsschutz.de’ ist nicht erlaubt: Kontakte aus Paketdaten bekommen nur Adressen unter .example, .test oder .invalid, damit keine echte Person erreicht wird“. Vor der Installation prüft nexxus noch einmal, bevor etwas angelegt wird. Ein Partner, den es unter diesem Namen schon gibt, wird so genommen, wie er ist, und behält seine eigene Adresse.
Relative Datumsangaben
Abschnitt betitelt „Relative Datumsangaben“Beispieldaten mit festen Datumsangaben sehen eine Woche später falsch aus: Fristen sind überfällig, Termine liegen in der Vergangenheit. $date zählt deshalb vom Tag der Installation aus (Zeitzone Europe/Berlin). Der Wert ist eine Folge von Schritten, die von links nach rechts gelten. Jeder Schritt besteht aus Vorzeichen, Zahl und Einheit:
| Einheit | Bedeutung | Beispiel |
|---|---|---|
d | Tage | "0d" ist der Installationstag |
w | Wochen | "+1w" |
m | Monate | "-1m" |
wd | Werktage: Montag bis Freitag ohne die bundesweiten Feiertage; 24. und 31. Dezember zählen als Werktage | "+2wd" |
Schritte lassen sich verketten: "+2wd-14d" heißt zwei Werktage vor, dann 14 Tage zurück. Bei einem datetime-Feld geben Sie daneben "time": "HH:MM" an (Standard 09:00). $date gibt es nur für date- und datetime-Felder, alles andere bricht die Installation ab.
In welcher Reihenfolge die Zeilen entstehen
Abschnitt betitelt „In welcher Reihenfolge die Zeilen entstehen“Ein $key findet nur eine Zeile, die der Installer schon angelegt hat. Er legt sie in dieser Reihenfolge an:
data/vordemo/. Eine Beispielzeile darf auf eine Zeile ausdata/verweisen. Umgekehrt geht es nicht, denn Beispieldaten sind freiwillig.- In jedem Ordner ein Fachobjekt nach dem anderen. Ein Fachobjekt, dessen
ref-Felder auf ein anderes Fachobjekt des Pakets zeigen, kommt nach diesem. Wo die Verweise die Wahl offen lassen, entscheidet die alphabetische Reihenfolge der Dateinamen. - In einer Datei von der obersten Zeile zur untersten. Eine Zeile, die auf eine andere Zeile desselben Fachobjekts verweist, etwa auf einen übergeordneten Datensatz, muss unter ihr stehen.
Zwei Fachobjekte, deren ref-Felder aufeinander zeigen, können nicht beide zuerst kommen. Der Installer nimmt sie dann alphabetisch, und ein $key vom ersten auf das zweite scheitert. Halten Sie den Verweis zwischen zwei Fachobjekten in einer Richtung; die andere Seite findet ihre Datensätze über eine Suche nach diesem Feld. Zeilen, die eine frühere Version oder eine Installation mit behaltenen Daten angelegt hat, zählen als angelegt (siehe den nächsten Abschnitt).
Findet ein $key noch kein Ziel, scheitert die ganze Installation mit einer Meldung wie demo/aktendokument.json 'd-0184-vollmacht'.akte: $key 'akte:2026-0184' gibt es nicht (oder er steht weiter hinten).
Doppelt installieren schadet nicht
Abschnitt betitelt „Doppelt installieren schadet nicht“Der Installer überspringt jede Zeile, deren Schlüssel es im Mandanten schon gibt, egal ob sie aus einer früheren Version stammt oder aus einer Installation, deren Daten behalten wurden. Deshalb darf data/ bei jeder Aktualisierung erneut laufen: Nur Zeilen mit neuen Schlüsseln legen Datensätze an. Daraus folgt auch: Ändern Sie eine bestehende Zeile in einer späteren Version, ändert sich der Datensatz nicht. Dafür gibt es Migrationsschritte.
Bei den Beispieldaten zählen auch gelöschte Datensätze: Einen Beispieldatensatz, den jemand gelöscht hat, legt eine Aktualisierung nicht wieder an, und ebenso wenig eine neue Zeile, die per $key auf ihn verweist.
Ein $key nennt nur eine Zeile desselben Pakets. Einen $key mit dem Schlüssel eines anderen Pakets davor lehnt nexxus beim Hochladen ab, weil Pakete nicht aufeinander aufbauen (siehe Aufbau eines Pakets). Datendateien dürfen schreibgeschützte und sequence-Felder direkt setzen. Lässt sich etwas nicht auflösen, scheitert die ganze Installation, und die Meldung nennt Datei, Zeile und Feld, zum Beispiel demo/frist.json 'f-0184-wv-regulierung'.faellig_am: '+2x' ist keine relative Angabe wie "+2wd" oder "+2wd-14d".
Versionen und was eine neue Version ändern darf
Abschnitt betitelt „Versionen und was eine neue Version ändern darf“Eine Paketversion ist eine SemVer-Nummer wie 1.1.0. Ist eine Version einmal hochgeladen, steht ihr Inhalt fest. Jede Korrektur, auch ein Tippfehler in einer Ansicht, braucht eine neue Version. Zwei weitere Felder des Manifests legen fest, wo eine Version laufen darf:
platformist ein Versionsbereich der nexxus-Plattform, zum Beispiel">=0.2.0 <1.0.0".requiresnennt eingebaute Module mit einem Versionsbereich, zum Beispiel"partners": ">=1.0.0". Ein solches Modul muss es in der Instanz in passender Version geben. Ein Paket setzt nie ein anderes Paket voraus.
Die Bereiche folgen der Schreibweise von npm: Durch Leerzeichen getrennte Vergleiche müssen alle zutreffen, || trennt Alternativen, ^ und ~ wirken wie bei npm.
Vor jeder Aktualisierung vergleicht nexxus die neue Version mit der installierten. Aus diesen Gründen lehnt es ab, mit genau dem Text, den der Dialog zeigt:
| Änderung | Text der Ablehnung |
|---|---|
| Die neue Version braucht eine andere Plattform | „Version 1.1.0 verlangt die Plattform >=1.0.0, hier läuft 0.2.0.“ |
| Die Hauptversion sinkt | „Die Hauptversion sinkt von 2 auf 1.“ |
| Die neue Version ist nicht neuer | „Version 1.0.0 ist nicht neuer als die installierte 1.0.0.“ |
| Ein Fachobjekt fehlt ohne neue Hauptversion | „Das Datenobjekt ‘notiz’ fehlt, das geht nur mit einer neuen Hauptversion.“ |
| Ein Feld fehlt ohne neue Hauptversion | „Das Feld ‘frist.ereignis’ fehlt, das geht nur mit einer neuen Hauptversion.“ |
| Ein Feld ändert seinen Typ | „Das Feld ‘frist.faellig_am’ ändert seinen Typ von date auf datetime; dafür braucht es ein neues Feld und eine Migration.“ |
Ein Feld ändert unique | „Das Feld ‘akte.aktennummer’ ändert die Eindeutigkeit (unique).“ |
| Ein Verweis zeigt woanders hin | „Der Verweis ‘notiz.aktendokument’ zeigt jetzt auf ‘akte’ statt auf ‘aktendokument’.“ |
Ein Feld ändert multiple | „Das Feld ‘frist.zustaendig’ ändert multiple.“ |
| Ein neues Pflichtfeld hat keinen Standardwert | „Das neue Pflichtfeld ‘frist.quelle’ hat keinen Standardwert.“ |
| Ein vorausgesetztes eingebautes Modul fehlt | „Das Modul ‘partners’ gibt es auf dieser Plattform nicht.“ |
| Ein vorausgesetztes eingebautes Modul hat eine andere Version | „Das Modul ‘partners’ läuft in Version 1.0.0, verlangt ist >=2.0.0.“ |
| Die neue Version stammt aus der Zeit vor geschlossenen Paketen und nennt ein anderes Paket | „Diese Version baut auf dem Paket ‘muster.akten’ auf. Pakete bauen nicht mehr aufeinander auf; was zusammengehört, kommt als ein Paket.“ |
Frei ändern darf eine Version: Fachobjekte, Felder, Ansichten, Aktionen, Menüeinträge und Rollen hinzufügen, Werte von Auswahllisten hinzufügen oder entfernen, jede Beschriftung ändern. Ein neuer Typ für ein Feld ist ein neues Feld plus ein Migrationsschritt, der die Werte hinüberkopiert. Eine Rückkehr zu einer älteren Version gibt es nicht.
Migrationsschritte
Abschnitt betitelt „Migrationsschritte“Müssen gespeicherte Daten mit einer Version umgebaut werden, beschreibt das Manifest die Schritte unter migrations, geordnet nach der Version, die sie einführt:
"migrations": { "1.1.0": { "pre": [ { "op": "renameValue", "entity": "geraet", "field": "kategorie", "from": "telefon", "to": "smartphone" } ], "post": [ { "op": "setDefault", "entity": "geraet", "field": "standort", "value": "buero" } ] }}op | Parameter | Wirkung | Erlaubt in |
|---|---|---|---|
setDefault | entity, field, value | füllt das Feld, wo es leer ist | jeder Version |
renameValue | entity, field, from, to | ersetzt einen Wert einer Auswahlliste, auch in multiple-Listen | jeder Version |
renameField | entity, from, to (Feldschlüssel) | verschiebt den Wert in ein anderes Feld | jeder Version |
copyField | entity, from, to (Feldschlüssel) | kopiert den Wert in ein anderes Feld | jeder Version |
deleteField | entity, field | entfernt den Wert des Felds aus jedem Datensatz | nur Hauptversionen (x.0.0) |
deleteEntity | entity | markiert alle Datensätze des Fachobjekts als gelöscht | nur Hauptversionen (x.0.0) |
pre oder post? Schritte unter pre laufen, solange noch die Beschreibung der alten Version gilt, Schritte unter post nach dem Wechsel auf die neue. Werte benennen Sie vor dem Wechsel um, neue Felder füllen Sie danach. Bei einer Aktualisierung von Version A auf Version B sammelt nexxus die Schritte jeder Version V mit A < V ≤ B: erst alle pre-Schritte in Versionsreihenfolge, dann alle post-Schritte in Versionsreihenfolge. Eine Version unter migrations darf nicht höher sein als die Version des Pakets selbst.
Zwei Dinge sollten Sie wissen:
- nexxus trägt jeden ausgeführten Schritt je Mandant in ein Protokoll ein, das jeden Schritt nur einmal zulässt. Ein Schritt, der schon gelaufen ist, wird übersprungen.
- Migrationsschritte schreiben ihre Werte so, wie sie im Manifest stehen. nexxus prüft sie nicht gegen Typ oder Auswahlwerte des Felds. Achten Sie selbst darauf, dass
toundvaluezur neuen Version passen.
Die Aktualisierung Schritt für Schritt
Abschnitt betitelt „Die Aktualisierung Schritt für Schritt“Die Administration startet die Aktualisierung auf der Paketseite (AdministrationBetriebModule, Reiter Pakete) mit Auf 1.1.0 aktualisieren. Den Dialog beschreibt Paketieren, installieren und aktualisieren. Hinter dieser Schaltfläche arbeitet die Plattform in dieser Reihenfolge:
Plan
Versionsregeln, vorausgesetzte eingebaute Module, neue Zustimmungen und ein Probelauf, der zählt, welche Datensätze jeder Schritt ändert.
Zustimmung
Jeden neuen Scope und jeden neuen Host eines Diensts hakt die Administration an.
pre-Schritte
Laufen, solange die alte Version gilt.
Wechsel und post-Schritte
Neue Version aktiv, post-Schritte, neu indizieren, Protokoll, Rollen, Skill für den KI-Assistenten, neue Paketdaten, auf Wunsch neue Beispieldaten.
Abschluss
Alles oder nichts. Die Dienste erfahren es danach.
- Plan. Bevor sich etwas ändert, zeigt der Dialog das Ergebnis des Plans: unter Was sich ändert die Einträge des Changelogs zwischen den beiden Versionen, unter Datenanpassungen je Migrationsschritt eine Zeile mit Phase („vor dem Wechsel“ oder „nach dem Wechsel“) und der Zahl der Datensätze, die er heute ändern würde („1 Datensatz“, „9 Datensätze“). Bringt die neue Version Beispielzeilen mit, die es im Mandanten noch nicht gibt, bietet der Dialog Neue Beispieldaten anlegen mit ihrer Zahl an; der Haken ist zu Beginn nicht gesetzt. Ablehnungsgründe stehen unter „Diese Aktualisierung ist nicht möglich:“ und sperren die Schaltfläche.
- Zustimmung. Will die neue Version Daten oder Dienste nutzen, denen die Administration noch nicht zugestimmt hat, stehen sie unter Neu zuzustimmen. Solange nicht jeder Punkt angehakt ist, bleibt das Paket auf der alten Version.
- Die Transaktion. nexxus führt alle
pre-Schritte aus, stellt die Installation auf die neue Version um, führt allepost-Schritte aus, schreibt die Nachschlagetabellen jedes Datensatzes nach der neuen Beschreibung neu, trägt die Schritte ins Protokoll ein, legt neue Rollen an, erweitert die eigenen Rollen des Moduls, schreibt den Skill für den KI-Assistenten aus den neuen Anweisungen neu und installiert neue Zeilen ausdata/, mit gesetztem Haken auch die neuen Zeilen ausdemo/. - Nach dem Abschluss. Die Plattform meldet die Aktualisierung an die Dienste des Moduls.
Scheitert etwas in Schritt 3, rollt nexxus die ganze Transaktion zurück. Installation, Datensätze und Rollen bleiben genau auf der alten Version, und der Dialog zeigt „Nicht aktualisiert:“ mit der Meldung des Servers, etwa Die Migration auf 1.1.0 ist gescheitert, 'acme.leihgeraete' bleibt auf 1.0.0: <Grund>.

Rollen nach einer Aktualisierung
Abschnitt betitelt „Rollen nach einer Aktualisierung“Neue Rollen im Manifest legt nexxus als neue Rollen an. Rollen, die das Modul früher angelegt hat, bekommen die Berechtigungen, die in dieser Version neu sind (neue Fachobjekte, neue zusätzliche Rechte), und das nur, wenn es die Rolle im Manifest schon in der alten Version gab. Was die Administration einer solchen Rolle entzogen hat, bleibt entzogen. Rollen, die nicht dem Modul gehören, fasst nexxus nie an. So bekommt durch eine Aktualisierung niemand Rechte, die die Administration nicht vergeben hat.
Ereignisse an Ihre Dienste
Abschnitt betitelt „Ereignisse an Ihre Dienste“Moduldienste, die Ereignisse zu Datensätzen abonniert haben, sehen jede Änderung eines Migrationsschritts: ein Ereignis je Datensatz und Schritt, versendet innerhalb der Aktualisierung. Ändern zwei Schritte denselben Datensatz, kommt er zweimal. Nach diesen Ereignissen erhält jeder Dienst der Installation installation.upgraded mit der previousVersion. Damit kann er nachholen, was er berechnet hätte, wäre er von Anfang an dabei gewesen. Die Inhalte der Ereignisse stehen unter Moduldienste.
Deaktivieren, deinstallieren, wieder installieren
Abschnitt betitelt „Deaktivieren, deinstallieren, wieder installieren“Die Administration hat drei Wege, ein Modul aus dem Betrieb zu nehmen. Sie unterscheiden sich darin, was bleibt:
| Aktion | Menü, Seiten, Werkzeuge für den KI-Assistenten | Datensätze | Rollen | Skill für den KI-Assistenten | Dienstkonto |
|---|---|---|---|---|---|
| Deaktivieren | für alle weg | bleiben, unsichtbar | bleiben | ausgeschaltet | gesperrt |
| Deinstallieren mit Daten behalten | weg | bleiben, unsichtbar | bleiben | entfernt | gesperrt |
| Deinstallieren mit Daten löschen | weg | als gelöscht markiert | gelöscht, samt Zuweisungen | entfernt | gelöscht, samt seiner Rolle |
- Deaktivieren ist eine Pause. Aktivieren stellt alles wieder her, wie es war.
- Daten behalten entfernt das Modul, lässt seine Datensätze aber liegen. Der Katalog führt es als „Entfernt, Daten behalten“, und die Paketseite bietet Wieder installieren an. Eine neue Installation hängt Datensätze und Rollen wieder an. Installiert die Administration dabei eine neuere Version als die behaltene, laufen die Migrationsschritte zwischen beiden Versionen als Teil der Installation.
- Daten löschen markiert die Datensätze als gelöscht, entfernt die Rollen des Moduls mit ihren Rechten und Zuweisungen, legt den Ordner mit den Beispieldokumenten in den Dateien als gelöscht ab und leert das Migrationsprotokoll. Partner, die aus Beispieldaten entstanden sind, bleiben, weil andere Datensätze des Mandanten inzwischen auf sie verweisen können.
Jedes Paket lässt sich für sich deaktivieren oder deinstallieren: Kein anderes Paket baut darauf auf.

Vor dem Deinstallieren exportieren
Abschnitt betitelt „Vor dem Deinstallieren exportieren“Der Deinstallationsdialog bietet Daten exportieren (ZIP) an. Die Datei <key>-export.zip enthält je Fachobjekt der installierten Version eine <entity>.json und eine module.json mit Schlüssel, Version und Zeitpunkt des Exports. Jeder Datensatz steht darin so:
{ "id": 12, "key": "d-0184-vollmacht", "data": { "titel": "Vollmacht Sabine Vogl", "typ": "vollmacht", "status": "geprueft" }, "version": 3, "createdAt": "2026-10-08T07:12:44Z", "updatedAt": "2026-10-08T09:30:02Z"}key ist der Schlüssel aus der Datendatei, wenn der Datensatz aus Paket- oder Beispieldaten stammt, und null bei Datensätzen, die Menschen angelegt haben.
Durchgerechnet: Leihgeräte 1.0.0 auf 1.1.0
Abschnitt betitelt „Durchgerechnet: Leihgeräte 1.0.0 auf 1.1.0“Das Tutorial-Paket aus Ihr erstes Modul zeigt eine vollständige Aktualisierung. Version 1.0.0 speichert Telefone mit dem Kategoriewert telefon. Version 1.1.0 benennt diesen Wert in smartphone um und ergänzt das Feld standort mit dem Standardwert buero. Ihr Block migrations ist genau der unter Migrationsschritte.
Die Beispieldaten von 1.0.0 enthalten drei Geräte, keines davon ein Telefon. In einem Mandanten, der 1.0.0 mit diesen Beispieldaten und sonst nichts installiert hat, zeigt der Dialog:
- unter Datenanpassungen:
renameValueaufgeraet.kategorie, „1.1.0 · vor dem Wechsel“, 0 Datensätze, undsetDefaultaufgeraet.standort, „1.1.0 · nach dem Wechsel“, 3 Datensätze; - keinen Abschnitt Neu zuzustimmen, denn 1.1.0 verlangt keinen neuen Datenzugriff;
- keine Ablehnung: Kein Feld fällt weg, kein Typ ändert sich, und das neue Feld hat einen Standardwert.
Wäre standort ein Pflichtfeld ohne Standardwert, lehnte der Dialog mit „Das neue Pflichtfeld ‘geraet.standort’ hat keinen Standardwert.“ ab.
Wenn etwas schiefgeht
Abschnitt betitelt „Wenn etwas schiefgeht“| Meldung | Bedeutung und Abhilfe |
|---|---|
| „Version 1.1.0 ist nicht neuer als die installierte 1.1.0.“ | Sie haben die installierte Version gewählt. Laden Sie eine höhere Versionsnummer hoch. |
| „Das Feld ‘frist.ereignis’ fehlt, das geht nur mit einer neuen Hauptversion.“ | In einer Nebenversion ist ein Feld weggefallen. Behalten Sie das Feld, oder veröffentlichen Sie eine neue Hauptversion mit einem Schritt deleteField. |
| „Das neue Pflichtfeld ‘frist.quelle’ hat keinen Standardwert.“ | Geben Sie dem neuen Pflichtfeld einen default, oder machen Sie es optional und füllen Sie es mit einem setDefault unter post. |
Zustimmung fehlt für: <Punkte> | In der Anfrage fehlte eine neue Zustimmung. Haken Sie jeden Punkt unter Neu zuzustimmen an. |
Die Migration auf 1.1.0 ist gescheitert, 'acme.leihgeraete' bleibt auf 1.0.0: <Grund> | Ein Schritt ist gescheitert, alles wurde zurückgerollt. Der Grund am Ende nennt das Problem. Korrigieren Sie den Schritt in einer neuen Version. |
| „‘acme.leihgeraete’ ist schon installiert (Version 1.0.0); für eine neue Version gibt es das Upgrade.“ | Das Paket ist schon installiert. Nutzen Sie auf der Paketseite die Schaltfläche zum Aktualisieren statt einer neuen Installation. |
| „‘acme.leihgeraete’ ist deinstalliert; eine neue Installation hängt die Daten wieder an.“ | Das Modul wurde mit behaltenen Daten deinstalliert. Nutzen Sie Wieder installieren. |