Global

Members

(constant) ACCOUNTING_TARGETS

Accounting target objects (normalized transition, flag-gated).
Source:

(constant) ACCOUNT_FIELD

Konten gehoeren dazu wie Adresse/E-Mail/Telefon: ein geteiltes Konto, das die Quelle nicht mehr fuehrt, verschwindet bei den Geschwistern. Nur der Vergleich laeuft anders — IBANs liegen verschluesselt vor, siehe `accountsEqual`.
Source:

(constant) AGE_UPDATE_STATS_PREFIX

Key-Präfix für die ageUpdate-Stats (gemeinsam von Bot + members-back genutzt). Per Env überschreibbar (`AGE_UPDATE_STATS_PREFIX`), damit parallele Umgebungen (z.B. Test-members-back neben Produktion) in SEPARATE Redis-Keys lesen und die Produktions-Statistik nicht mit Test-Läufen vermischen. Produktion nutzt den Default 'ageUpdate:stats:' (= Key-Aufbau des ageUpdate-SystemBots in basic-bots).
Source:

(constant) ALLOWED_ICON_MIME

Apps und Domains laufen über `registryService`; `service.js` bleibt als **Vault-Adapter** im Spiel (Lesefallback während der Umstellung) und für **Mail**. Die Validierung liegt bewusst auch im `registryService`: sie muss gegen denselben Bestand prüfen, in den sie schreibt. Eine Fassung, die noch den Vault-Bestand las, sah in der Datenbank längst aufgelöste Domains nicht — eine Domain ließ sich damit zweimal vergeben. `registryService` entscheidet selbst über `REGISTRY_READ_MODE`, ob er die DB oder (bei `vault`) den Vault bedient. Die HTTP-Oberfläche bleibt in beiden Fällen identisch — genau das macht `admin` zum Abnahmewerkzeug.
Source:

(constant) APP_BASE_DOMAIN_DEFAULT

Basis-Domain, aus der interne Hosts gebildet werden (`APP_BASE_DOMAIN`).
Source:

(constant) BYTEA_COLUMNS

Known binary/bytea columns.
Source:

(constant) CAST

UID-Spalten als `UUID-…`, `Data` als Objekt (§ registryTypes: Cast-Regeln)
Source:

(constant) CREATE_APP_RELEASE

`AppKey` ist die App-Kennung aus dem Registry (`Data.appId` des `app`-Objekts), nicht eine UID: die Registry vergibt `appId` als stabilen Schlüssel (§ registryTypes), und genau er adressiert ein Release über Organisationen hinweg. Die App-Objekte selbst bleiben in `ObjectBase`.
Source:

(constant) CREATE_ORG_RELEASE_OVERRIDE

`(AppKey, OrgUID)` als Primärschlüssel: eine Organisation kann pro App nur auf **ein** Canary-Release zeigen. Genau eine Zeile ist damit der Canary, und ein Rollback ist ein `DELETE`. `OrgUID` folgt dem Haus-Format `BINARY(16)` und wird über `U_UUID2BIN(?)` adressiert (41-stellige `UUID-…`-Form, § registryTypes: Cast-Regeln). `AddedAt` steht ohne `ON UPDATE` — es ist der Zeitpunkt, ab dem der Canary gilt, und soll sich beim Lesen nicht verändern.
Source:

(constant) DATA_BUCKET

Bucket for org data/manifest assets (PWA icons, manifests, etc.)
Source:

(constant) DOMAIN_TYPE_INTERNAL

Eine Domain trägt **zwei** unabhängige Aussagen. Sie lagen früher in einem einzigen Feld: in Vault stand `{"kpe.de":"verified","ct":"internal"}` — eine Domänenart neben einem Prüfstand. Das ging nicht auf, denn es sind zwei Achsen: | Achse | Werte | Frage | |---|---|---| | `type` | `internal` \| `external` | Wo liegt der Host? | | `status` | `pending` \| `verified` | Ist er nachgewiesen? | In einem Feld führte das zu einem stillen Widerspruch: die Oberfläche bot `internal`/`external` an, der Bestand enthielt `verified`, und `validateDomains` wies damit **den eigenen Bestand** als ungültig zurück. Getrennt ist jede Achse für sich prüfbar — und der DNS-Nachweis hat einen Platz, ohne ein dritter „Typ" zu werden.
Source:

(constant) DRY_RUN

Set to false to actually write changes
Source:

(constant) DRY_RUN

Set to false to actually write changes
Source:

(constant) ENTRY_SPLIT_REASON

`memberALinkDecision` flags a multi-list `entry` with this prefix. Those are the objects the link repair must not decide — the entry has to be split, not trimmed.
Source:

(constant) EXTERNAL_RE

extern: mindestens zwei Labels, gültige TLD
Source:
Filter-Objekte tragen ihre Zielbindung generisch als `list`-Link.
Source:

(constant) FILTER_TYPES_SQL

Die Filter-Typen, die Rechte vergeben.
Source:

(constant) GENERIC_VISIBLE_TARGETS

The full set of target types handled by the generic visible/changeable path.
Source:

(constant) ICON_EXT

MIME type → extension für akzeptierte Icon-Formate
Source:

(constant) ICON_EXT

MIME type → file extension map for accepted icon formats
Source:

(constant) INTERNAL_RE

intern: Kleinbuchstaben, Ziffern, Bindestriche — kein führender/letzter Bindestrich
Source:

(constant) JSON_COLUMNS

Known longtext JSON columns.
Source:

(constant) KNOWN_ACTIONS

Actions that function templates may grant (extend as new rights are added).
Source:

(constant) LEGACY_GENERIC_TARGETS

Legacy generic list-type targets that already used the visibilityList path.
Source:
Accepted `linkType` values in requests (legacy alias for the share mode).
Source:
Link-Typen für das App-Registry (Links.Type). `app` selbst ist kein Link-Typ — eine App wird nicht verlinkt, sie ist das Ziel. Domains und Assets hängen über Links an der App.
Source:
Verbindet eine **App** (als Link-`UID`) mit einem **Asset** (`UIDTarget`).
Source:
Verbindet eine **App** (als Link-`UID`) mit einer **Domain** (`UIDTarget`). Richtung ist bewusst „von der App weg" — und damit **gleich** wie bei `appAsset`. Ein gemischtes Modell (App→Asset, Domain→App) hätte jede Abfrage zu einer Frage der Erinnerung gemacht. Der Preis ist eine Umkehrung beim Auflösen: „welche App hängt an diesem Host" muss über den `UIDTarget` der Domain suchen, nicht über ihren `UID`.
Source:

(constant) MAIL_THROTTLE_MS

Mindestabstand zwischen zwei Fehler-Mails. Ein Fehlersturm darf kein Mailsturm werden: `errorLogger` wird pro fehlgeschlagenem Request gerufen, und ein einziger kaputter Aufrufpfad kann das im Sekundentakt ausloesen.
Source:

(constant) MAX_PENDING_MESSAGES

Obergrenze pro Client, damit eine sehr lange Trennung nicht unbegrenzt waechst.
Source:

(constant) MIGRATION_API

API passed into each migration's migrate() function. Migrations can use SQL queries, transactions, or pure JS logic.
Source:

(constant) OBJECT_IN_ORG_PARAMS

The number of `?` placeholders `objectInOrgSql` expects.
Source:

(constant) OBJECT_TYPES

Objekttypen für das App-Registry (ObjectBase.Type)
Source:

(constant) OBJ_TYPE_APP

Eine App (Auslieferungseinheit). `UIDBelongsTo` → Organisation.
Source:

(constant) OBJ_TYPE_APP_ASSET

Ein App-Artefakt (Icon, Favicon, …). `UIDBelongsTo` → App.
Source:

(constant) OBJ_TYPE_APP_DOMAIN

Eine Domain/Host-Zuordnung. `UIDBelongsTo` → Organisation.
Source:
Link types that connect a share with its project. The target model has exactly one (`memberA`); `member` is tolerated while old rows exist. The owner link (share -> person) uses the same type but a different target type (person), so it is never matched by these predicates.
Source:
Type:
  • const
Source:

(constant) PROJECT_TARGETS

Project scope (new feature, always active).
Source:

(constant) PUBLIC_BUCKET

Bucket for publicly readable assets (app icons, etc.)
Source:

(constant) PWA_ICON_SIZES

PWA-Icon-Varianten im data bucket — Pfade, die der Static-Server erwartet
Source:

(constant) PWA_ICON_SIZES

Standard PWA icon variants written to the data bucket under manifests path
Source:

(constant) READ_ONLY_MODES

Stored `metadata.mode` values that mean "read only". `reference` is the legacy spelling.
Source:

(constant) REBUILD_CLEANUP_EXCLUDE

Was der Personen-Rebuild **loeschen** darf. Muss genau die Menge sein, die `personListRebuildAccess` danach wieder aufbaut — sonst loescht der eine Lauf, was der andere nicht zurueckholt. Genau das war der Fehler: die Loesch-Menge stand auf den Legacy-Typen fest, waehrend die Wiederaufbau-Menge um `project` und die Share-Typen gewachsen ist. Ein Projekt/ein Share verlor damit seine Personen-Zeile, ohne dass sie neu entstand. Accounting-Ziele sind ausgenommen, solange die normalisierte Ueberfuehrung laeuft — sie werden getrennt gerechnet.
Source:

(constant) RECONNECT_RETENTION_MS :number

Schonfrist fuer getrennte Clients. Beim `disconnect` wird der Client nicht mehr sofort geloescht, sondern als getrennt markiert und fuer diese Dauer behalten. Meldet er sich in der Zeit mit derselben `?id=` neu an (Socket.IO behaelt die Query bei), bekommt er die waehrend der Trennung aufgelaufenen Nachrichten in Reihenfolge nachgeliefert. Das deckt den Normalfall ab (Tab kurz offline, Reconnect innerhalb von Sekunden). Nach Ablauf raeumt sweepDisconnectedClients() auf.
Type:
  • number
Source:

(constant) RESERVED_PREFIXES

Präfixe, die eine Organisation nicht belegen darf. Sie liegen im System-Namensraum: `admin`, `api`, `auth` … würden mit Infrastruktur-Hosts verwechselt, die von der Plattform selbst vergeben werden. Eine Organisation, die `admin` beansprucht, bekäme `admin.{app}.commtool.org` — und damit einen Host, der wie die Administrationsumgebung aussieht.
Source:

(constant) RETENTION_YEARS

MariaDB temporal history guarantee (contract: 13 years).
Source:

(constant) RUNNER_MODES :const

Type:
  • const
Source:

(constant) RUNNER_MODES :const

Type:
  • const
Source:

(constant) SCHEMA_VERSION

Common HTTP envelope for the new Members service endpoints (Projects, Shares, Snapshots, Event replay). See 080-Workspaces/018-Cross-Service-Contracts.mdx. Success: { success: true, result, request_id, schema_version } Error: { success: false, error: { code, message, details }, request_id, schema_version } Legacy routes keep their own envelope; only the new endpoints use this one.
Source:

(constant) SENSITIVE_PATTERNS

Regex patterns for detecting sensitive information in strings
Source:

(constant) SHARED_FIELDS

Kontaktfelder, deren Eintraege mit der Familie geteilt werden.
Source:

(constant) SHARE_IS_BASE_SQL

SQL-Ausdruck: ist die Zeile selbst die Basis (kein Ableger)?
Source:

(constant) SHARE_PROJECT_MAP

Zuordnung Share -> Projekt, tolerant gegen **beide** Link-Richtungen (alt: Projekt -> Share, neu: Share -> Projekt).
Source:

(constant) SHARE_ROOT_SQL

SQL-Ausdruck: der **Root** (Basis-Share) einer Share-Zeile — die Index-Identitaet des Repos (`UIDBelongsTo`-Kette bis zur Selbstreferenz). Nur **eine** Vererbungsstufe ist vorgesehen: Basis ist die Zeile, wenn `UIDBelongsTo` leer ist, auf die eigene UID zeigt **oder** auf kein Share-Objekt zeigt (Altbestand: dort stand die Organisation). Sonst ist `UIDBelongsTo` die Basis. Bewusst in SQL: `binary(16)`-Werte sollen nicht als Buffer/Hex-String durch JS-Vergleiche laufen.
Source:

(constant) SHARE_TARGETS

Share scope. Shares tragen keine eigenen Filter: sie **spiegeln** den Filter-Satz ihres Projekts (./../../RouterProject/projectShare/access.js) und werden ueber denselben Rebuild materialisiert. Sie muessen deshalb im generischen Ziel-Set stehen — sonst wuerde ein Personen-Rebuild die Share-Zeilen der Person nicht nachziehen.
Source:

(constant) SHARE_TYPES

Enum-Werte der Share-Objekte in `ObjectBase.Type`.
Source:

(constant) SHARE_TYPES_SQL

SQL-Liste der Share-Typen.
Source:

(constant) SHARE_TYPES_SQL

Enum-Werte der Share-Objekte in `ObjectBase.Type`.
Source:

(constant) SHARE_TYPES_SQL

Enum-Werte der Share-Objekte in `ObjectBase.Type`.
Source:

(constant) SHARE_TYPES_SQL

Enum-Werte der Share-Objekte in `ObjectBase.Type`.
Source:

(constant) TABLES

Tables to compress with their entity keys (columns that define a unique entity)
Source:

(constant) TIMESTAMP_COLUMNS

Known timestamp columns that need timestamptz handling.
Source:

(constant) TRIGGER_DDL

Die Trigger-DDL selbst — **eine** Quelle fuer Migration und Test-Fixtures, damit beide nie auseinanderlaufen. Zwei Fallstricke stecken hier drin: - `SIGNAL ... SET MESSAGE_TEXT = CONCAT(...)` ist **nicht** erlaubt ("Undeclared variable: CONCAT"): die SET-Klausel von SIGNAL akzeptiert nur Literale oder Variablen, keine Ausdruecke. Deshalb erst die Meldung per `SET` (dort sind Funktionen erlaubt) in eine Variable schreiben und diese an SIGNAL uebergeben. So bleibt die Objekt-UID in der Fehlermeldung und der Verursacher ist ohne Nachfrage im Log identifizierbar. Die Meldung ist 85 Zeichen — unter dem Limit von 128 fuer MESSAGE_TEXT. - `UIDTarget <> NEW.UIDTarget` ist Pflicht. Der Trigger feuert *vor* der Duplikatspruefung, ein zweiter `INSERT IGNORE` **desselben** Links (heute ein stiller No-Op) wuerde sonst 1644 werfen und idempotente Re-Inserts an ~20 Stellen brechen.
Source:

(constant) TRIGGER_NAME

Name des Triggers — auch fuer die Idempotenz-Pruefung. Exportiert, damit Test-Fixtures die Invariante **befristet** ausschalten koennen, wenn sie Altbestand simulieren muessen. Siehe `src/__tests__/.helpers/memberAInvariant.js`.
Source:

(constant) TRUTHY

Query parameter values that switch from report-only to repair mode.
Source:

(constant) TRUTHY

Query parameter values that switch from report-only to repair mode.
Source:

(constant) UUID_COLUMNS

Known binary(16) columns that need uuid conversion.
Source:

(constant) UUID_STRING_RE

`UUID-`-präfixierte Form, wie sie `U_UUID2BIN()` und die JS-Casts erwarten
Source:

(constant) addFamilyAction

Handles the `family` and `familyB` add actions. Fired when a family member is added to a family and the organisation uses family-based fees. Recalculates membership fees and updates family indices for the target family.
Source:

(constant) addFamilySyncAction

Handles the `familySync` add action. Syncs addresses, phone numbers, email addresses, and accounts between family members when a family-shared contact detail is created or modified.
Source:

(constant) addFamilyUpdate

Adds family updates to a new member when they join a family Synchronizes family data (address, email, phone, accounts) from existing family members to the newly added family member.
Source:

(constant) addFilter

Add a filter to a list
Source:

(constant) addFilter

Adds a filter to a target and executes the filtering logic
Source:

(constant) addFilterAction

Handles filter-type add actions: visible, changeable, include, exclude, intersect. A filter object (`action.UIDObjectID`) is attached to a source (`action.UIDBelongsTo`). The filter targets either a dlist (include/exclude/intersect) or a user (visible/changeable). After applying the filter, the target list is flagged for WebSocket update.
Source:

(constant) addFunctionAccountingVAction

Handles the `functionAccountingV` add action. Fired when a function template's accounting rules (accountingAccess, accountingWriteAccess, financialMaster) are modified. Deletes and rebuilds only the accounting filter entries for every job linked to this function template.
Source:

(constant) addFunctionAction

Handles the `function` add action. Fired when a function template is created or modified with respect to its qualification requirements. Re-qualifies all jobs based on this template.
Source:

(constant) addFunctionVAction

Handles the `functionV` add action. Fired when a function template is modified with respect to its visibility or changeability requirements. Deletes and rebuilds all visibility/changeability filter entries for every job linked to this function template, then refreshes the holding person's access.
Source:

(constant) addGroupGuest

Erstellt eine Gastgruppe für eine Zielgruppe und übernimmt Mitglieder/Jobs als Gäste.
Source:

(constant) addGroupToEventController

Add group to event controller Handles PUT /:UIDevent
Source:

(constant) addGroupVisibility

Add group visibility to an event
Source:

(constant) addGuests

Fügt mehrere Gäste oder Gastgruppen zu einer Gruppe hinzu.
Source:

(constant) addListAbo

Adds a list UID to the monitoring set of a connected client. The UID is authorisation-checked via isObjectVisible before being added. An unauthorised UID is silently skipped. Passing `'quit'` or `null` clears the entire `updateAbo` Set, which is the same effect as the frontend sending `monitor { UID: null }` during a subscription re-sync. Once registered, the backend will push `{ update: true, UID, timestamp }` messages via addUpdateList / broadcastUpdate whenever the list changes.
Source:

(constant) addListEntryAction

Handles the `list` add action. Fired when an entry is added to a list. Matches the entry object against every filter defined on the list and adds it to the corresponding dlists.
Source:

(constant) addListMemberAction

Handles the `listMember` add action. Evaluates to which dlists an object should belong and which users can see/modify it when the object is newly created or its list membership changes. Checks all filters and updates visibility/changeability for the relevant users.
Source:

(constant) addListVisibilityAction

Handles the `listVisibility` add action. Fired when a visibility or changeability filter defining access for a list/dlist/email/event/eventT has been modified or added. Rebuilds the full access table for the affected list.
Source:

(constant) addMemberAction

Handles tree-structural add actions: adding an object to a group hierarchy. Supported types: `group`, `person`, `extern`, `job`, `guest`, `ggroup`, `eventJob`. The function: 1. Resolves the transitive group memberships of the target group (delta). 2. Applies type-specific logic (guest deduplication, group cascade, person guest-group handling, job visibility filter creation). 3. Inserts missing `member` Links for non-person types. 4. Adds the object to any guest groups (ggroups) defined on the target. 5. Fires WebSocket and event-bus notifications.
Source:

(constant) addObjectAbo

Adds one or more object UIDs to the monitoring set of a connected client. Each UID is authorisation-checked via isObjectVisible before being added. Unauthorised UIDs are silently skipped. Passing `'quit'` or `null` clears the entire `objectAbo` Set, which is the same effect as the frontend sending `monitorObject { UID: null }` during a subscription re-sync. Once registered, the backend will push `{ object: true, value }` messages via addUpdateEntry whenever the object changes.
Source:

(constant) addPersonFilterAction

Handles the `personFilter` action type: re-evaluates dynamic list memberships and filter entries for a person/extern whose data-relevant fields changed. Unlike `addMemberAction` for `person`/`extern`, this does NOT insert new member Links and does NOT publish `/add/group/…` events — the person is already in the tree; only their list/filter placement needs to be refreshed.
Source:

(constant) addPersons

Helper function to add persons to an email
Source:

(constant) addPersonsToEmail

Add persons to email
Source:

(constant) addShare

Add a share to a project. Requires **changeable** on the project. Creates the share as a base share (`UIDBelongsTo` = own UID), links it to the project (`memberA`) and records the creator as owner (`member` link + `Visible.admin`). Legacy `linkType` in the body (`member`/`read`) is translated into `metadata.mode = readOnly`.
Source:

(constant) addSingleGuest

Adds a single person as guest to a group
Source:

(constant) addTailnetRunner

Assign a runner to a tailnet network (explicit link).
Source:

(constant) addTailnetRunner

PUT /api/tailnets/:UID/runners/:runnerUID
Source:

(constant) addUpdateEntry

Pushes an object-change payload to all clients that have registered the object via `monitorObject` / addObjectAbo. Iterates `clientData.objectAbo` (a `Set`) for each connected client and emits `{ object: true, value }` to matching sockets. Called by API routes whenever an object's data changes (e.g. after a PATCH).
Source:

(constant) addUpdateList

Notifies clients that one or more lists have changed, with leading-edge debouncing to prevent update storms. **Debounce strategy (per list UID):** - First change: sends `{ update: true, UID, timestamp }` immediately to all subscribed clients and records the UID in `delayedUpdateTimestamps`. - Subsequent changes within the debounce window: refreshes the timestamp but does NOT send again immediately. - monitorDelayedUpdates (called by a periodic interval) flushes any entry that has been quiet for the configured debounce period. Clients subscribed via `monitor` / addListAbo have the matching UID in their `updateAbo` Set and receive the notification.
Source:

(constant) addVisibility

Setzt Sichtbarkeit fuer die Filter, die an `sources` haengen, und **meldet** die Zeilen, die dabei entstehen oder verschwinden.
Source:

(constant) addVisibility

Add visibility filters for a location
Source:

(constant) addVisibilityFilter

Add visibility filters for event template
Source:

(constant) adminDlistCheck

Controller for GET /dlist/admin/:UID
Source:

(constant) adminListCheck

Controller for GET /list/admin/:UID
Source:

(constant) ageUpdate

Updates the age (`dindex` field) of persons associated with a given root UID
Source:

(constant) ageUpdatePersons

Recalculate `dindex` (numeric age) for every person in the organisation whose stored age differs from today's computed value.
Source:

(constant) ageUpdateStats

Reads the ageUpdate statistics stored by the ageUpdate SystemBot (basic-bots) in the shared Redis (last 7 nightly runs per organisation, 7-day TTL). GET /person/ageUpdate/stats
Source:

(constant) alternativeRoot

Alternative root finding logic when no specific organization is provided
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Router

Type:
  • express.Router
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) api :express.Express

Type:
  • express.Express
Source:

(constant) apiError

Create an ApiError carrying an HTTP status and a machine-readable code.
Source:

(constant) appHostFor

Baut den Host, unter dem eine App erreichbar ist. Der **Punkt entscheidet**, und das ist keine eigene Erfindung: dieselbe Regel steht in `shared-auth` (`organizationDomains.js`) und im Portal-Bot (`portal.controller.js` → `buildAppUrl`). Sie wird hier nur nachgebildet, damit Routing und Anmeldung nicht auseinanderlaufen. | `domain` der App | Ergebnis | |---|---| | `db.app.kpe.de` (mit Punkt) | `db.app.kpe.de` — eine Kunden-Domain gilt, wie sie steht | | `sjm` (ohne Punkt) | `sjm.admin.app.commtool.org` — Präfix, App-Kennung, Basis |
Source:

(constant) appIdFromData

Liest die `appId` aus dem `Data`-Feld eines App-Objekts. Die `appId` (z.B. `member.app`) ist **keine** UID: sie ist der logische, menschenlesbare Schlüssel aus Vault (`orgas/data/{orgId}/apps` → Map-Key) und wird auch in der API (`admin`) als Map-Key verwendet. Sie liegt deshalb als Feld in `Data` und nicht im Primärschlüssel (§6.1 der Planung).
Source:

(constant) appTitles

Baut die Objekt-Titel-Felder aus `appId` und Anzeigetitel. `Title`/`Display` tragen den **Anzeigetitel**, `SortName` dessen Kleinschreibung — die App-ID liegt in `Data.appId`. Den Schlüssel in `Title` zu legen wäre verlockend (er wäre dann indexiert), würde aber Anzeigename und Identität vermischen: ein umbenannter Titel hätte den Lookup zerbrochen.
Source:

(constant) applyFilterToEmail

Apply filter to email
Source:

(constant) applyVisibilityAndMatching

Applies visibility records and object-list matching for supported types.
Source:

(constant) approveRegistration

Approve registration: bind pending code to org (already tenant-bound at create). Optional publicKey from connector may be attached before exchange.
Source:

(constant) approveRegistration

POST /api/runners/registrations/:code/approve
Source:

(constant) authenticateRunner

Verify runner request: credentialId + signature over timestamp+method+path+bodyHash. Credential liegt im Companion-Slot (`Member.lookup_key`), der publicKey in `ObjectBase.Data`; revoked Runner werden über den ObjectBase-Status abgewiesen.
Source:

(async, constant) authorizeUser

The function retrieves all jobs associated with the user from the database, applies the provided filter to these jobs, and determines if the user has the necessary permissions to manage achievements for a person. This is used to control who can add, modify, or delete achievement records based on their job roles and permissions.
Source:

(constant) broadcastUpdate

Immediately emits a list-update notification to all clients monitoring `UID`, bypassing the debounce logic of addUpdateList. Use this when the update must arrive without delay (e.g. after a server-side transaction completes and the client needs to refresh right away). Emits `{ update: true, UID, timestamp }` via the `update` event.
Source:

(constant) buildDeltaVisual

Merges `delta` and `secondLevel` into a deduplicated `deltaVisual` array.
Source:

(constant) buildEventPayload

Build the wire payload for an event. The payload keeps the existing members event contract: `{ data, UIDorga, backDate, timestamp }`.
Source:

(constant) buildMemberAConsistencyReport

Builds the report and, with `fix`, removes the surplus links. Exported separately from the HTTP handler so the same logic can be run against a database directly (dry run on a production copy) without going through the API.
Source:

(constant) buildTranslateObject

Recursively builds a translation object by extracting translatable properties (content, label, placeholder, html) from a serialized input object and its nested children. Ensures that existing entries in the translation object are not overridden.
Source:
Example
const serialized = {
  component1: {
    paras: { content: "Hello", label: "Greeting", html: "<p>Welcome</p>" },
    children: [
      { component2: { paras: { content: "World", label: "Planet" } } }
    ]
  }
};
const translateObject = {};
buildTranslateObject(serialized, translateObject);
console.log(translateObject); 
// { Hello: "Hello", Greeting: "Greeting", "<p>Welcome</p>": "<p>Welcome</p>", World: "World", Planet: "Planet" }

(constant) bulkAddGuests

Bulk add guests to a group
Source:

(constant) checkEmailAdmin

Check if user is email admin
Source:

(constant) checkExpire

Middleware to check file expiration parameters
Source:

(constant) checkFamilies

Checks family consistency
Source:

(constant) checkFileVisible

Middleware to check file visibility permissions
Source:

(constant) checkGroupAdmin

GET /admin/:UID — check whether the current user has admin rights for a group.
Source:

(constant) checkGroupAdminStatus

Checks whether the current user has admin rights for the specified group.
Source:

(constant) checkIsAdmin

Check if user is admin
Source:

(constant) checkIsMember

Check whether a specific person is a (current) member of a group.
Source:

(constant) checkIsMemberController

Check whether a person is currently a member of a group.
Source:

(constant) checkRoot

Check and set the organization root for the current request Uses Keycloak organization as single source of truth Answers the request itself (does not call `next`) when the organization context is unusable: - `400` with `missingOrga: true` - `x-organization`/`x-orga` missing or not a UUID - `403` - `x-user-uid` was sent, but that user is not valid for the organization - `500` - the organization config could not be loaded
Source:

(constant) cleanFilters

Cleans unused filters
Source:

(constant) cleanupSocketData

Clears all in-memory state managed by this module. Empties both clientDataStore and delayedUpdateTimestamps. Intended for use during a graceful server shutdown or in test teardown to prevent state leaking between test cases. Does NOT close existing socket connections — call `io.close()` separately if a full shutdown is required.
Source:

client

Source:

(constant) clientDataStore :Map.<string, any>

Type:
  • Map.<string, any>
Source:

(constant) compressHistory

Compress history for all configured system-versioned tables. GET /maintenance/compressHistory Query params: ?apply=true — actually create _new tables and compress (default: dry-run, no writes) ?swap=true — also perform the RENAME TABLE swap (requires apply=true) ?chunkSize=N — rows per chunk (default: 50000)
Source:

configLoadPromise

Gemeinsames Init-Promise: `loadAllConfigs()` darf nur einmal gleichzeitig laufen. Vorher guardete `getConfig()` nur mit `if(!configs.admin)` (Check-then-Act). Da ein Durchlauf Dateien aus S3 liest und DB-Queries fahrt, sahen parallele Requests denselben unfertigen Zustand, starteten jeweils einen eigenen Durchlauf, und der zweite Lauf leerte `configs[app] = {}` mitten im ersten. Ergebnis waren sporadische "Table 'Member' doesn't exist" bzw. unvollstaendige `mergedConfigs`. Das Promise wird memoisiert: Boot (server.js) und Lazy-Init aus `getConfig()` teilen sich genau einen Durchlauf. Nach Erfolg bleibt es bestehen — ein erneuter Voll-Durchlauf ist nicht noetig, Config-Aenderungen laufen ueber `remergeConfig()` (siehe `triggerConfigUpdates`). Nur nach einem Fehler wird zurueckgesetzt, damit ein Retry moeglich bleibt.
Source:

(constant) configLoggers

Initialize all rotating file streams using env configuration.
Source:

connecting :Promise.<boolean>

Type:
  • Promise.<boolean>
Source:

corroborated

The object also holds a `member`-family link to this target — the tie breaker when the `ValidFrom` comparison cannot decide (see `memberALinkDecision.js`).
Source:

corroborated

The object also holds a `member`-family link to this target. Surfaced so a reader of the report can see WHY a `ValidFrom` tie was decided the way it was.
Source:

(constant) createAction

Create or update an action from a template and trigger
Source:

(constant) createActionFromTemplate

Create an action instance from a template and trigger, without Express req/res. Mirrors the core logic of createAction in controller.js but takes plain parameters instead of Express objects. No template rendering, no events.
Source:

(constant) createBirthdayFilter

re-assesses birthday filter
Source:

(constant) createCredential

Create a credential: generates an ed25519 key pair and persists it entirely in Vault. `ref` (= credentialsRef) is `{orgId}/{name}` for org scope and `{userUID}/{name}` for user scope.
Source:

(constant) createDB

Create a new database Endpoint to initialize a new database schema. Protected by employee rights.
Source:

(constant) createEventController

Create event controller Handles PUT /:group/:template
Source:

(constant) createFreeJobController

Create free job without template Handles PUT /:member/:event
Source:

(constant) createGuestGroup

Create guest group from existing group
Source:

(constant) createJobWithTemplateController

Create job with template Handles PUT /:member/:event/:function
Source:

(constant) createNewExtern

Insert a brand-new extern member into ObjectBase, Member, Links, and Visible. Fires tree queue and starts a non-blocking AI-embedding job.
Source:

(constant) createNewPerson

Insert a brand-new person into ObjectBase, Member, Links, Visible, create the initial family record, and publish the join event. Note: session values are passed explicitly so this function has no HTTP dependency.
Source:

(constant) createOrChangeFamily

Create or change family membership (PUT /:famMember/:member) Handles the creation or assignment of a family for a member. Can create new families or assign members to existing families. Supports rebate mode for family fee calculations.
Source:

(constant) createOrUpdateAchievementTemplate

Creates or updates an achievement template
Source:

(constant) createOrUpdateEmail

Create or update an email
Source:

(constant) createOrUpdateEventTemplate

Create or update an event template
Source:

(constant) createOrUpdateEventTemplateController

Controller for creating or updating an event template (PUT)
Source:

(constant) createOrUpdateExtern

PUT /:group — Create or update an extern in a group.
Source:

(constant) createOrUpdateFilter

Create or update filter (PUT /:source/:target/:type) * @param {ExpressRequestAuthorized} req - Express request object * @param {ExpressResponse} res - Express response object
Source:

(constant) createOrUpdateGroup

Creates a new group under a parent, or updates an existing group by UID. When the group UID from the request body does not yet exist in the DB a new group is inserted as a child of UIDparent. When it already exists (update path) its Member data is refreshed and sister-group links are re-evaluated.
Source:

(constant) createOrUpdateJobTemplateController

Create or update job template Handles PUT /:UIDeventTemplate
Source:

(constant) createOrUpdateLocation

Create or update a location
Source:

(constant) createOrUpdateLocationController

Controller for creating or updating a location
Source:

(constant) createOrUpdatePerson

Creates or updates a person entry in the database
Source:

(constant) createProject

Create a new project. Mirrors the list/dlist pattern (`Router/list/service.js`): - `memberA` link points to the project group (owner group), not the organization - `member` link points to the creating user - creator gets `admin` in Visible - a default visibility filter rule is created via `addVisibility`, so all job holders of the project group (and super admins) see the project
Source:

(constant) createRegistration

Create a one-time registration code for the current tenant. The admin may already decide the connector's mode (`personal`|`team`|`shared`), its owner group (`groupUID`) and a tailnet network (`tailnetUID`) — the connector cannot know these during the credential exchange, so they are bound to the code (Redis, transient, TTL 30 min).
Source:

(constant) createRegistration

GET /api/runners/registrations
Source:

(constant) createRunner

Create a runner object after registration approval / exchange. Mirrors the project/list creation pattern: - `team`/`shared` get a `memberA` link to their owner group (team = given group, shared = org root group) - the creator always gets `Visible admin` - `personal` keeps the existing `member` link to the owning user - for `team`/`shared` a default visibility rule is created via `addVisibility` so job holders of the group see the runner
Source:

(constant) createTailnet

Create a tailnet network under an owner group. Mirrors the project/list creation pattern: - `memberA` link to the owner group - creator gets `Visible admin` - default visibility rule via `addVisibility` (group job holders see it)
Source:

(constant) createdTimestamp

GET /createdTimestamp/:UID — return the creation allowed backdate timestamp (ms) for a group object, constrained by its latest history row.
Source:

(constant) createdTimestampCheck

Checks created timestamp to avoid something is linked to before the creation of the target
Source:

(constant) dbErrorLogger

Logs database errors using the DB logger stream.
Source:

(constant) dbLogger

Custom database logger
Source:

(constant) debounceDelay :number

Type:
  • number
Source:
Source:

(constant) delayedUpdateTimestamps :Map.<string, number>

Type:
  • Map.<string, number>
Source:

(constant) deleteAchievement

This function deletes an achievement from the database. It performs the following steps: 1. Retrieves the achievement data using the provided UID 2. Checks if the user is authorized to delete the achievement 3. Deletes the achievement and related links from the database 4. Updates the achievement queue and list membership 5. Updates the client with the changes Authorization is based on either template-defined filters or admin status.
Source:

(constant) deleteAchievement

Deletes an achievement from the database
Source:

(constant) deleteAchievementTemplate

Deletes an achievement template
Source:

(constant) deleteAction

Delete an action
Source:

(constant) deleteActionTemplate

Delete action template (DELETE /:UID)
Source:

(constant) deleteActionTemplatesForBotNotInOrgs

Delete all action Templates for a specific bot, where the organizations are not in the provided list (DELETE /bot/:botUID)
Source:

(constant) deleteCredential

Delete a credential: removes the Vault secret.
Source:

(constant) deleteCredential

DELETE /project/credential/:ref
Source:

(constant) deleteDirectory

Delete directory (DELETE /dir/:UID/:prefix)
Source:

(constant) deleteDlistUID

Controller for DELETE /dlist/:UID
Source:

(constant) deleteEmail

Delete an email
Source:

(constant) deleteEmailShare

Delete email share (delegate to list share function)
Source:

(constant) deleteEntries

Delete entries function
Source:

(constant) deleteEntry

Remove one or more persons from a static list
Source:

(constant) deleteEntryController

Handle DELETE /list/person/:UIDlist — remove persons from a static list
Source:

(constant) deleteEventController

Delete event controller Handles DELETE /:UID
Source:

(constant) deleteEventTemplate

Delete an event template
Source:

(constant) deleteEventTemplateController

Controller for deleting an event template
Source:

(constant) deleteEvents

Deletes all events
Source:

(constant) deleteExtern

DELETE /:UID — Delete an extern and all associated data.
Source:

(constant) deleteExternById

Delete an extern and all its child objects (guest, job, entry) plus associated links.
Source:

(constant) deleteFilter

Delete filters by source, target and type
Source:

(constant) deleteFiltersByType

Delete filters by source, target and type (DELETE /:source/:target/:type)
Source:

(constant) deleteGroup

DELETE /:UID — delete a group if it has no remaining members.
Source:

(constant) deleteGroupById

Deletes a group if it has no remaining members. Responds with the list of remaining members if deletion is blocked.
Source:

(constant) deleteGroupFromEventController

Delete group from event controller Handles DELETE /:UIDevent/:UIDgroup
Source:

(constant) deleteGuest

Delete a guest or guest group
Source:

(constant) deleteJob

Deletes a job from the database.
Source:

(constant) deleteJobController

Delete job Handles DELETE /:UID
Source:

(constant) deleteJobTemplateController

Delete job template Handles DELETE /:UID
Source:

(constant) deleteLanguageFileController

Delete a language file from the object store. Handles DELETE /:app/:filename and DELETE /:app/:UIDroot/:filename
Source:

(constant) deleteLeaderJobsController

Delete all jobs for person in event Handles DELETE /leader/:UIDevent/:UIDperson
Source:
Delete links for filters
Source:

(constant) deleteList

Delete a list/dlist
Source:

(constant) deleteListUID

Controller for DELETE /list/:UID
Source:

(constant) deleteLocation

Delete a location
Source:

(constant) deleteLocationController

Controller for deleting a location
Source:

(constant) deleteMultipleFiles

Delete multiple files (DELETE /:UID)
Source:

(constant) deletePortalPending

Delete pending portal link and token payload.
Source:

(constant) deletePortalPendingController

Source:

(constant) deletePrivateRailFiles

Delete private rail files (DELETE /rail/:UID/:prefix/:filename)
Source:

(constant) deleteProject

Delete a project (requires admin on the project). **Nur bei leeren Root-Shares.** Haengt an einer Basis dieses Projekts ein Ableger in einem anderen Projekt, bricht der Aufruf mit `409 PROJECT_HAS_DEPENDENT_SHARES` ab und nennt die betroffenen Repositories samt ihrer abhaengigen Projekte. Der Aufrufer muss sie vorher aufloesen: die Zuordnung mit `successor` entfernen (der Root wandert dann in eines der abhaengigen Projekte) oder den Ableger loesen. Danach ist der Root leer, und das Projekt kann weg. Die Alternative waere, die Basis still stehen zu lassen — dann haengt sie projektlos im Raum, und niemand sieht, dass sein Repository woanders verwurzelt ist.
Source:

(constant) deleteProject

DELETE /project/project/:UID
Source:

(constant) deletePublicFiles

Delete public files (DELETE /public/:expire/:prefix/:filename)
Source:

(constant) deletePublicRailFiles

Delete public rail files (DELETE /rail/:app/:prefix/:filename)
Source:

(constant) deleteRunner

Hard-delete a runner: the topology object, its `Member` companion row, all links and the visibility grants/filters. `revokeRunner` is the graceful path (soft-delete, keeps the object for audit); this is the cleanup path — e.g. for runners that are already `revoked` and would otherwise accumulate forever. Publishes `/remove/runner/{uid}` so runnerSync drops the registry entry (contract 090-Runner-Events §2.3) — without it the ide-server would keep accepting a credential that no longer exists in members.
Source:

(constant) deleteRunner

DELETE /api/runners/:UID Hard-delete a runner (cleanup; `revoke` is the soft path).
Source:

(constant) deleteShare

Eine Zuordnung aus einem Projekt entfernen. Ist das Objekt die **Basis** („Root") und haengen Ableger daran, wird **nicht stillschweigend** die Basis behalten: der Aufrufer bestimmt mit `successor` (`body.successor` oder `?successor=`), **welcher Ableger die neue Basis wird** — also in welches Projekt der Root wandert. Ohne diese Angabe antwortet der Endpunkt mit `409 SHARE_ROOT_NEEDS_SUCCESSOR` und der Liste der moeglichen Nachfolger, damit die Oberflaeche waehlen kann. Der Aufruf bleibt idempotent-tolerant: zeigt der `successor` nicht auf einen Ableger dieses Roots, ist das ein `422 INVALID_SUCCESSOR`.
Source:

(constant) deleteShare

DELETE /project/project/:projectUid/shares/:shareUid
Source:

(constant) deleteSpecificFilter

Delete specific filter by UID (DELETE /:UID)
Source:

(constant) deleteTailnet

Delete a tailnet network. Assigned runners are unlinked (no cascade to the runners themselves — they just lose this network assignment).
Source:

(constant) deleteTailnet

DELETE /api/tailnets/:UID
Source:

(constant) deleteUserByPerson

Remove identifyer link for one person.
Source:

(constant) deleteUserController

Source:

(constant) deleteUsers

Remove identifyer links for selected users.
Source:

(constant) deleteUsersController

Source:

(constant) deleteVisibilityFilter

Delete visibility filters for event template
Source:

(constant) dependentsOfRoots

Die **Ableger** mehrerer Basis-Shares (mit ihrem Projekt) — die Gegenfrage zu „wo kommt der Ableger her": „welche Projekte haengen an dieser Basis?"
Source:

(constant) diffMaps

Vergleicht zwei flache Maps (appId bzw. domain → Wert) und beschreibt die Unterschiede. Bewusst auf Schlüssel-Ebene: „Zahl stimmt, Inhalt nicht" ist der Fall, der bei einem reinen Zähler-Vergleich durchrutscht.
Source:

(constant) disabled

Set to false (or delete this line) when ready to apply
Source:

(constant) disabled

Set to false (or delete this line) when ready to apply
Source:

(constant) dispatchRecreate

Dispatches recreate logic to the appropriate handler based on object type.
Source:

(constant) doCheckVisible

Checks the visibility of a person and retrieves related job and member data
Source:

(constant) drainRunner

Mark runner draining — der Zusteller (ide-server) weist einem drainenden Runner keine neuen Sessions mehr zu. Reine Topologie-Markierung.
Source:

(constant) drainRunner

POST /api/runners/:UID/drain
Source:

(constant) emailValues

Extract all email addresses from a Data.email array into a lowercased string list.
Source:

(constant) ensureConfigsLoaded

Wartet, bis der Config-Bestand vollstaendig geladen ist. Race-frei und idempotent: parallele Aufrufe haengen sich an denselben Durchlauf, spaetere Aufrufe sind ein No-Op.
Source:

(constant) errorLogger

Logs generic application errors.
Source:

(constant) errorLoggerRead

Logs read-specific errors (legacy entry point).
Source:

(constant) errorLoggerUpdate

Logs update-specific errors (legacy entry point).
Source:

(constant) eventList :express.Express

Type:
  • express.Express
Source:

(constant) exchange

POST /api/runner/v1/register/exchange
Source:

(constant) exchangeRegistration

Exchange approved/pending code + publicKey for runner credential. Creates ObjectBase runner + `Member` companion row (lookup_key).
Source:

(constant) execDListFilter

Executes a dynamic list filter (include/exclude/intersect) on a target list
Source:

(async, constant) expireAchievements

Expires achievements based on their renewal period This function checks all achievements linked to a membership organization (root entity) and expires those whose renewal period has elapsed. For each expired achievement, it updates the dindex to mark it as expired and then updates the achievement lists for affected persons.
Source:

(constant) extractUIDefaults

Recursively extract defaultValue entries from UIaction form field definitions. Returns a flat object mapping field name → defaultValue.
Source:

(constant) familyAddress

Synchronizes family-shared data (address, email, phone, accounts) across all family members When a person/extern/family object is updated with family data, this function propagates those changes to all other members of the same family. Handles: - Family addresses - Family email addresses - Family phone numbers - Family accounts (including familyFees accounts) Only the fields listed in `object.Touched` are reconciled (i.e. shared entries the source no longer carries are removed there). Without `Touched` the sync is purely additive, as it always was.
Source:

(constant) fetchGroup

Fetch a group record (ObjectBase + Member) by its binary UID. Shared entry point for person and extern create/update flows.
Source:

(constant) fetchLatestObjectValidFrom

Return the UNIX timestamp (seconds) of the most recent ObjectBase row for a UID across all system-time history. Used to prevent backdated type-change operations (extern → person or person → extern) from landing before existing history rows, which would create impossible temporal ordering in the versioned table.
Source:

(constant) fetchMemberExists

Check whether a person or extern record already exists for the given binary UID. Shared by both person and extern create/update flows.
Source:

(constant) filterGuestDelta

Filters out delta groups where the person/guest is already a member. Used for `guest` and `ggroup` action types.
Source:

(constant) findDomainConflict

Sucht einen Konflikt zwischen einer Domain und dem Bestand **anderer** Organisationen. Verglichen wird nur die Achse `type`. Ob eine Domain verifiziert ist, ändert nichts daran, wem sie gehört — würde der Status mitgezählt, ließe sich dieselbe Domain zweimal vergeben, solange eine Seite den Nachweis noch nicht erbracht hat. Zwei Regeln: - gleiche Art + gleicher Name → direkter Konflikt - intern `foo` ↔ extern `foo.*` → Präfix-Konflikt (dieselbe Wurzel)
Source:

(constant) findPersonalRunnerForUser

Persönlicher Runner einer Person (mode=personal, `member`-Link → Person, nicht revoked) in derselben Orga. Für die Session-Auflösung „mein Personal-Runner" (Soll: Projekt-Runner → Personal-Runner des Users).
Source:

(constant) generateMultipleUIDs

Generate multiple unique identifiers (UIDs)
Source:

(constant) generateUID

Generate a single unique identifier (UID)
Source:

(constant) geocodePlace

Forward geocode a place name to coordinates
Source:

(constant) geocodePlaceController

Forward geocode: place name → coordinates
Source:

(constant) getAchievement

Retrieves a specific achievement by UID
Source:

(constant) getAchievementTemplates

Gets all achievement templates for the organization
Source:

(constant) getAchievements

Gets achievements for the organization
Source:

(constant) getAchievementsDuplicates

Gets duplicate achievements
Source:

(constant) getAchievementsTree

Gets achievements tree structure
Source:

(constant) getAction

Get a specific action by UID
Source:

(constant) getActionCatalog

Katalog der von Funktionsvorlagen gewährbaren Aktionsrechte mit fachlicher Beschreibung. Wird über `GET /api/kpe20/function/actions` an die Admin-App ausgeliefert (Phase 3: "Die Auswahl wird aus einem Backend-Katalog geladen").
Source:

(constant) getActionTemplate

Get specific action template (GET /:UID)
Source:

(constant) getActionTemplateForBotInOrg

Get action template for a specific bot in the current organization (GET /bot/:botUID/org) Returns the single template linked to the bot that belongs to the requesting org.
Source:

(constant) getActionTemplates

Get all action templates for organization (GET /)
Source:

(constant) getActionTemplatesForBot

Get all action templates for a specific bot (GET /bot/:botUID)
Source:

(constant) getActionsByTemplate

Get actions by template
Source:

(constant) getActionsByTrigger

Get actions by trigger
Source:

(constant) getAddedListing

Retrieve entries that have been added to a list since the given timestamp. Works for both static and dynamic lists. The result is deduplicated and entries with `member0` link type are excluded. Where a member appears multiple times (multiple links), their Data objects are merged.
Source:

(constant) getAddedListingController

GET /list/added/:UID/:timestamp — entries added to a static list since timestamp GET /dlist/added/:UID/:timestamp — entries added to a dynamic list since timestamp
Source:

(constant) getAddedPersons

Return persons that were **added** to a group after `timestamp`.
Source:

(constant) getAddedPersonsController

Return persons added to a group after the given timestamp.
Source:

(constant) getAdminEventTemplates

Get all templates the user can administer
Source:

(constant) getAdminEventTemplatesController

Controller for getting administrable event templates
Source:

(constant) getAllEmailShares

Get all email shares (delegate to list share function)
Source:

(constant) getAllEventTemplates

Get all templates for the organization
Source:

(constant) getAllEventTemplatesController

Controller for getting all event templates
Source:

(constant) getAllEventTemplatesWithData

Get all templates with data for the organization
Source:

(constant) getAllEventTemplatesWithDataController

Controller for getting all event templates with data
Source:

(constant) getAllFamilies

Get all families (GET /) Administrative endpoint to retrieve all families. Requires admin privileges.
Source:

(constant) getAllFilters

Get all filters (GET /)
Source:

(constant) getAllIdentifyers

Get all identifyer links for the current organisation.
Source:

(constant) getAllIdentifyersController

Source:

(constant) getAppsController

GET /kpe20/orgaSettings/apps Returns the app registry for the current organisation.
Source:

(constant) getBulkFamilies

Bulk family retrieval (POST /families) Retrieves family information for multiple UIDs at once. Supports both current and historical data retrieval.
Source:

(constant) getCachedUserData

Get user data from cache or members API
Source:

(constant) getCollectionCounts

Get membership counts for collections.
Source:

(constant) getCollectionsController

Controller for GET /
Source:

(constant) getCollectionsListing

Get collections listing based on filter/query input.
Source:

(constant) getCollectionsUIDController

Controller for GET /:UID
Source:

(constant) getCredential

Get a single credential.
Source:

(constant) getCredential

GET /project/credential/:ref
Source:

(constant) getDlistPersonsController

Handle GET /dlist/persons/:UID — retrieve all persons in a dynamic list
Source:

(constant) getDlistPersonsPaginatedController

Handle GET /dlist/persons/:UID (paginated) — pass through to next if no __page param
Source:

(constant) getDlistUID

Controller for GET /dlist/:UID
Source:

(constant) getDomainsController

GET /kpe20/orgaSettings/domains Returns the domain settings for the current organisation.
Source:

(constant) getEmail

Get a specific email
Source:

(constant) getEmailPersons

Get persons in email (with pagination support)
Source:

(constant) getEmailShare

Get email share details (delegate to list share function)
Source:

(constant) getEmailShares

Get email shares for specific list (delegate to list share function)
Source:

(constant) getEmailsForPerson

Get emails for a person
Source:

(constant) getEnteredPersons

Return persons who **entered** a group (became member from extern) after `timestamp`.
Source:

(constant) getEnteredPersonsController

Return persons who transitioned from extern to person (entered) after the timestamp.
Source:

(constant) getEventController

Get event controller Handles GET /:UID
Source:

(constant) getEventForList

Get the event that a list belongs to
Source:

(constant) getEventJobsController

Get all jobs for a function template Handles GET /eventJobs/:UID
Source:

(constant) getEventLists

Get all lists for an event with participants
Source:

(constant) getEventListsController

Controller for getting event lists with participants
Source:

(constant) getEventLog

Gets event logs
Source:

(constant) getEventParticipantLists

Manages event participant lists
Source:

(constant) getEventTemplateByEventUID

Get the template for an event with that UID
Source:

(constant) getEventTemplateByEventUIDController

Controller for getting the template for an event
Source:

(constant) getEventTemplateByUID

Get a specific event template by UID
Source:

(constant) getEventTemplateByUIDController

Controller for getting a specific event template by UID
Source:

(constant) getEventVisibility

Rebuilds event visibility
Source:

(constant) getEvents

GET /events?organization=&after=&limit=
Source:

(constant) getExcludeObjects

Gets objects that match exclude/intersect filter criteria
Source:

(constant) getExitedPersons

Return persons who **exited** (changed from person to extern) after `timestamp`.
Source:

(constant) getExitedPersonsController

Return persons who transitioned from person to extern (exited) after the timestamp.
Source:

(constant) getExtern

GET /:UID — Delegates to person controller (same data structure)
Source:

(constant) getExternAdmin

GET /admin/:UID — Delegates to person controller (same admin check)
Source:

(constant) getExternDuplicates

GET /duplicates/:firstName/:lastName — Delegates to person controller
Source:

(constant) getExternHistory

GET /history/:UID — Delegates to person controller (same history logic)
Source:

(constant) getFakeUser

Get fake user data for impersonation (admin only) Uses Redis caching to avoid database queries on every API call
Source:

(constant) getFamily

Get family information (GET /:UID) Retrieves family data including current information or historical data for a specific year. Supports fee calculation and historical data retrieval.
Source:

(constant) getFamilyData

Gets family data or processes family corrections
Source:

(constant) getFamilyListForGroup

Get family listing for a group (GET /list/:group) Retrieves families associated with a specific group. Supports pagination and various filtering options.
Source:

(constant) getFamilyListing

Helper function to get family listing Core function that builds family listings with various filtering and data options. Supports historical data, person data inclusion, fee information, and visibility filtering.
Source:

(constant) getFileWithPrefix

Get files with prefix (GET /:UID/:prefix/:filename)
Source:

(constant) getFilter

Get specific filter by UID (GET /:UID)
Source:

(constant) getFilterData

Gets filter data and source information for a filter
Source:

(constant) getFilters

Retrieves all filters for the supplied sources
Source:

(constant) getFunctionActions

GET /function/actions — Katalog der gewährbaren Aktionsrechte. Basis für die Auswahl im ActionPermissionsSection der Admin-App (Phase 3).
Source:

(constant) getGroup

GET /:UID — fetch group details, optionally with parent and/or sibling data.
Source:

(constant) getGroupById

Retrieves a group by UID with optional parent and sibling data.
Source:

(constant) getGroupGuests

Get all guests from a group
Source:

(constant) getGroupTreeGraph

Gets a Kroki graph representation of groups connected via memberA/memberS links.
Source:

(constant) getIncludeObjects

Gets objects that match include filter criteria
Source:

(constant) getJobController

Get single job Handles GET /:UID
Source:

(constant) getJobTemplatesController

Get all function template names and UIDs Handles GET /:UID
Source:

(constant) getJobTemplatesWithDataController

Get all function templates with full data Handles GET /Data/:UID
Source:

(constant) getLanguageFileController

Stream a language file to the client. Handles GET /:app/:filename and GET /:app/:UIDroot/:filename The organization layer is only readable for the organization of the session. The portal routes in `http-server.js` run without `checkRoot`, so the check has to happen here.
Source:

(constant) getList

Get list/dlist details
Source:

(constant) getListEntry

Get entry data for a specific person in a list
Source:

(constant) getListEntryController

Handle GET /list/entry/:UIDlist/:UIDperson — get entry data for a specific person in a list
Source:

(constant) getListPersonsByUIDsController

Handle POST /list/persons/:UID — retrieve specific persons in a list by UID list
Source:

(constant) getListPersonsController

Handle GET /list/persons/:UID — retrieve all persons in a static list
Source:

(constant) getListPersonsPaginatedController

Handle GET /list/persons/:UID (paginated) — pass through to next if no __page param
Source:

(constant) getListUID

Controller for GET /list/:UID
Source:

(constant) getListVisibleSql

Build the SQL snippet that restricts the `Visible` table join to the correct user / admin context. - Super-admins: restricted to the super-admin visible user - Org-admins: `changeable` visibility only for non-group targets - Normal users: full visibility of their own objects
Source:

(constant) getListVisibleSql

Get SQL for visible list filtering
Source:

(constant) getListing

List projects the user can see (visible | changeable | admin). Org admins and bots see all projects of the organization. Optional `group_uid` query filter: only projects whose owner group matches (used by the project group tab).
Source:

(constant) getListing

Get email listing (persons in email)
Source:

(constant) getListing

Get all persons in a list with optional field selection, filtering, and temporal queries
Source:

(constant) getListing

Retrieve members/objects belonging to a group or object identified by `UID`. Supports siblings query, temporal snapshots (`timestamp`, `since`), data field projections, optional grouping and filtering.
Source:

(constant) getListing

Get listing of locations with optional filters
Source:

(constant) getListingByUIDs

Get specific persons (by UID) from a list with optional field selection and temporal queries Behaves like getListing but additionally filters the result to only those entries whose person UID (`UIDBelongsTo`) or entry UID (`ObjectBase.UID`) appears in the array of UUIDs supplied in `req.body`.
Source:

(constant) getListingController

Return the full list of persons belonging to a group / object.
Source:

(constant) getListingPaginatedController

Return a paginated list of persons belonging to a group. Only invoked when `__page` query parameter is present.
Source:

(constant) getLocation

Get a single location by UID
Source:

(constant) getLocationController

Controller for getting a single location
Source:

(constant) getLocationListingController

Controller for getting location listing (with pagination support)
Source:

(constant) getLocationTemplates

Get location criteria templates
Source:

(constant) getLocationTemplatesController

Controller for getting location templates
Source:

(constant) getLogFiles

Get log files (GET /:api/logs)
Source:

(constant) getMailController

GET /kpe20/orgaSettings/mail Returns the SMTP settings for the current organisation (password masked).
Source:

(constant) getMissedEventsByKey

Get missed events by key and timestamp
Source:

(constant) getMissedEventsByKeys

Get missed events by multiple keys and timestamp
Source:

(constant) getMissedEventsByPattern

Get missed events by pattern and timestamp
Source:

(constant) getMissedEventsByTemplate

Get missed events by template and timestamp
Source:

(constant) getMultipleActions

Get multiple actions by UIDs
Source:

(async, constant) getObjects

Retrieves objects based on the provided ObjectUID(s). This function queries the database to fetch objects and their associated data. It supports both single ObjectUID and an array of ObjectUIDs. The returned data includes details such as UID, type, associated member data, extra data, main base data, title, and validity timestamps.
Source:

(constant) getObjectsByGroupOwner

Resolve objects of a specific type for an organization through owner group links. Traversal: object(memberA)->group(member)->organization.
Source:

(constant) getOrganizationForGroup

Get the organization UID for a given group UID
Deprecated:
  • Use getOrganizationForObject instead (works for all object types due to link propagation)
Source:

(constant) getOrganizationForList

Get the organization UID for a given list UID
Deprecated:
  • Delegates to getOrganizationForObject, which covers the list/project case (object → group → organization) as its second step.
Source:

(constant) getOrganizationForObject

Get the organization UID for any PROPAGATED object UID (group, person, extern, job, guest) Works because these object links are propagated to their organization via member links. Link Propagation Flow: Propagated Object → member link → ... → Organization (Data.root=true) For NOT propagated objects (list, project) the single hop is not enough: they only link to their group. The second query below covers that case (object → group → organization), so this function answers for all object types except shares — a share's organization is the one of its project.
Source:

(constant) getOrganizationForShare

Get the organization UID for a share (repositoryShare / directoryShare). A share carries **no** organization link: the organization is derived over its project (`Share → memberA → Projekt → Owner-Gruppe → Organisation`). While the old model is still in the database (project → share link, `UIDBelongsTo` = org), both link directions and the direct `UIDBelongsTo` fallback are tolerated, so the function answers before, during and after the migration.
Source:

(constant) getPaginatedFamilyList

Get paginated family listing (GET /list/:group with __page parameter) Returns paginated family data for a group.
Source:

(constant) getPendingEmails

Get pending emails (admin only)
Source:

(constant) getPerson

Retrieves detailed information about a person, job, guest, or extern object
Source:

(constant) getPersonActions

Load the action names granted to a person through her jobs in an organization.
Source:

(constant) getPersonByEmail

Find persons/externs by exact email match using the SearchIndex table. Returns all matches within the organisation.
Source:

(constant) getPersonByEmailController

Source:

(constant) getPersonIdentifyer

Get identifyer UID for a person.
Source:

(constant) getPersonIdentifyerController

Source:

(constant) getPersonLists

Get all lists containing a specific person
Source:

(constant) getPersonListsController

Handle GET /list/lists/:UIDperson — get all lists containing a specific person
Source:

(constant) getPersonMinBackdate

Return the minimum allowed backdate timestamp (seconds) for adding a person/extern to a target group. addToTree inserts Links rows from the person to the target group AND all its ancestor groups (discovered via the group's own member/memberA links). If the person was previously a member in any of those same groups, historical link rows already exist in the system-versioned Links table. Backdating a new insertion before the latest existing validFrom of those overlapping links would create an impossible temporal ordering. The floor is therefore MAX(validFrom) across all historical Links rows where UID = personUID AND UIDTarget IN (targetGroup + all its ancestor groups).
Source:

(constant) getPersonsByGroups

Fetch persons belonging to one or more groups supplied in `req.body` as UUID array.
Source:

(constant) getPersonsByGroupsController

Return persons belonging to one or more groups supplied as UUID array in body.
Source:

(constant) getPersonsByUIDs

Fetch multiple person objects by an array of UIDs supplied in `req.body`. Used when the caller already knows specific UIDs instead of querying by group.
Source:

(constant) getPersonsByUIDsController

Return persons matching an array of UIDs supplied in the request body.
Source:

(constant) getPortalPendingByKcUID

Get pending portal link details by KC UID and root orga.
Source:

(constant) getPortalPendingByKcUIDController

Source:

(constant) getPrivateRailFiles

Get private rail files (GET /rail/:UID/:side/:filename)
Source:

(constant) getProject

Get a single project (requires at least visible).
Source:

(constant) getProject

GET /project/project/:UID
Source:

(constant) getProjectCapabilities

GET /project/project/capabilities
Source:

(constant) getPublicFiles

Get public files with expiration (GET /public/:expire/:UID/:filename)
Source:

(constant) getPublicLanguageFiles

Get public language/config files (GET /:api/prefix1:(languages|config)/:filename/)
Source:

(constant) getPublicRailFiles

Get public rail files (GET /rail/:app/:side/:filename)
Source:

(constant) getQueueCount

Get the count of pending items in the processing queue
Source:

(constant) getRemovedListing

Retrieve entries that have been removed from a list since the given timestamp. Works for both static and dynamic lists. The result is deduplicated and entries with `member0` link type are excluded. Where a member appears multiple times (multiple links), their Data objects are merged.
Source:

(constant) getRemovedListingController

GET /list/removed/:UID/:timestamp — entries removed from a static list since timestamp GET /dlist/removed/:UID/:timestamp — entries removed from a dynamic list since timestamp
Source:

(constant) getRemovedPersons

Return persons that were **removed** from a group after `timestamp`.
Source:

(constant) getRemovedPersonsController

Return persons removed from a group after the given timestamp.
Source:

(constant) getRepoLanguageController

Ein Bot-Repo mit getrennten Ebenen (Editor). Handles GET /:repo?lang=de
Source:

(constant) getRunner

Source:

(constant) getRunner

GET /api/runners/:UID
Source:

(constant) getSearchData

Search users for UI selector.
Source:

(constant) getSearchDataController

Source:

(constant) getSharedEmailData

Get shared email data (delegate to list shared function)
Source:

(constant) getSignedUrl

Generate a pre-signed S3 URL (GET /:UID/:prefix/:filename/signed) Returns a short-lived URL that the browser can use to download the file directly from S3 without needing auth headers.
Source:

(constant) getSingleFile

Get single file (GET /:UID/:filename)
Source:

(constant) getSnapshotAsOf

GET /projects/:projectUid/snapshot?asOf=...
Source:

(constant) getTailnet

Source:

(constant) getTailnet

GET /api/tailnets/:UID
Source:

(constant) getTimestamp

Get current server timestamp
Source:

(constant) getTree

Rebuilds the membership tree for the given type. Delegates to rebuildMembershipTree() for the core logic (virtual transaction diff).
Source:

(constant) getType

Parse and validate the `type` query parameter. Falls back to `['person']` when the parameter is absent or invalid. Only allowed types are returned to prevent injection via illegal type values.
Source:

(constant) getTypes

Determines what types of objects to select based on source type and filter
Source:

(constant) getUser

Get user object for the logged-in user for their organizations Uses Redis caching to avoid database queries on every API call with Bearer auth
Source:

(constant) getUserByUID

Get user object by identifyer UID in current orga.
Source:

(constant) getUserByUIDController

Source:

(constant) getUsersWithVisibility

Get users who have specific visibility permissions for an entity
Source:

(constant) getUsersWithVisibilityData

Get users and their data who have specific visibility permissions for an entity
Source:

(constant) getVisibility

Rebuilds visibility settings for objects
Source:

(constant) getVisibleFilter

Build the Visible JOIN fragment based on the current user's permission level. Admins get no filter; changeable/admin visibility users see all entries; read-only users only see entries where they have changeable rights.
Source:

(constant) handleGroupMembershipMigration

Handles group membership migration for both person and extern types
Source:

(constant) handleGroupType

Handles the `group` type cascade: queues member actions for all current members of the added group, and pre-inserts delta member Links for persons/externs.
Source:

(constant) handleJobType

Handles the `job` type: creates `visible` and `changeable` filter objects based on the function template attached to the job.
Source:

(constant) handlePersonType

Handles the `person` type: removes duplicate guest memberships and creates guests for `memberGA` groups within a transaction.
Source:

(constant) hasActionPermission

Whether the current user has a given action right (e.g. `project.create`) in the current organization context.
Source:

(constant) hasDerivedShares

Haengt ein **anderes** Share-Objekt an dieser UID (ist sie eine Basis, die noch gebraucht wird)? Letzte Absicherung beim Loeschen: lieber den Root behalten als einem Ableger den Boden wegziehen.
Source:

(constant) heartbeat

POST /api/runner/v1/heartbeat — Topologie-Heartbeat in die Companion-Zeile.
Source:

(constant) id

AP 30 — Projekt-/Share-Zielmodell. Alt (Ist): - `ObjectBase.UIDBelongsTo` trug die **Organisation** (Org-Gruppe) - der Projekt-Link zeigte vom Projekt zum Share (`Links.UID` = Projekt, `UIDTarget` = Share, Type `memberA`/`member`/`projectShare`) - die Lesestufe steckte im Link-Typ (`memberA` = schreiben, `member` = lesen) Neu (Ziel, normativ seit 2026-09-24): - `UIDBelongsTo` = eigene UID. Es transportiert **keine** Organisation mehr; die Org wird ueber die `memberA`-Kette abgeleitet (`getOrganizationForObject`, siehe 080-Workspaces/051-Migrationsplan-Komponenten). Ein Ableger zeigt auf seinen Basis-Share (bleibt unveraendert). - der Projekt-Link zeigt vom Share zum Projekt (`UID` = Share, `UIDTarget` = Projekt) - die Lesestufe ist eine Eigenschaft des Shares: `metadata.mode` (`readOnly` sperrt, alles andere ist editierbar) Die Migration ist idempotent und laeuft ueber den normalen Migrationslauf (`dbVersion`). Sie aendert ausschliesslich Basisobjekte: ein Share/Projekt, dessen Elternobjekt selbst ein Share/Projekt ist, bleibt ein Ableger.
Source:

(constant) id

AP 30 — Owner-Backfill fuer Bestands-Shares. Neue Shares bekommen ihren Owner beim Anlegen (`addShare`: `member`-Link Share -> Person + `Visible.admin`) — der Anleger ist der Owner ([Shares eines Projekts](https://members.app.commtool.org/-/001-Backend/Datenstruktur/dProjectShares)). Der **Bestand** hat weder Link noch `Visible`-Zeile. Ohne Owner greift die dokumentierte Voreinstellung "Shares erben die Rechte des Projekts" — das ist richtig, laesst aber den Besitz-Anspruch des Anlegers verfallen (er koennte den Share nicht mehr administrieren, sobald er das Projekt-Recht verliert). Dieses Modul zieht den Owner nach. Es ist bewusst **regelbasiert** und enthaelt keine UID: Owner werden die **Personen**-Konten mit `Visible` am Projekt. Das sind echte Nutzer; die Projekt-`admin`-Zeile traegt haeufig ein **Bot-/Systemkonto** (`Type='extern'`), das kein Besitzer eines Shares sein soll. Idempotent (`INSERT IGNORE`), akzeptiert beide Link-Richtungen — die Reihenfolge zum Modul `20260924-project-share-target-model` ist damit gleichgueltig.
Source:

(constant) id

Stable unique identifier — never change this after the migration has been applied
Source:

(constant) id

Migration: Add EmailIndex column to Member table Adds a dedicated VARCHAR(512) column for email lookups, populated with all lowercased emails from Member.Data.email[].email, space-separated. Same pattern as FullTextIndex / PhonetikIndex — a denormalized search column maintained on person save. Backfills existing rows from the JSON Data field.
Source:

(constant) id

Migration: Convert TreeQueue.Type from ENUM to VARCHAR(64) The ENUM constraint required a schema change every time a new queue type was added. Converting to VARCHAR(64) removes that friction and allows new action types (e.g. 'personFilter') to be introduced in application code alone. Existing values are preserved; the column is made NOT NULL with no default, matching the previous ENUM behaviour.
Source:

(constant) id

Migration: Replace EmailIndex column with a generic SearchIndex table The previous approach stored a space-separated string of all emails in a VARCHAR(512) column on Member and queried it with LIKE '%email%'. That cannot use a B-tree index (leading wildcard) and cannot be extended to other object types or index categories without adding more columns. This migration: 1. Drops the EmailIndex column if it was added by the dev-only migration 20260419-member-emailindex (safe no-op in production where it never ran). 2. Creates a generic SearchIndex table with one row per indexed value, scoped by object type and index category. 3. Backfills all person/extern email entries from Member.Data. Table design: SearchIndex (UID, ObjType, IndexType, Value) UID – Member.UID (= ObjectBase.UID for person/extern) ObjType – object type: 'person', 'extern', 'group', … IndexType – index category: 'email', 'phone', … Value – lowercased, trimmed indexed value The composite index idx_lookup (IndexType, ObjType, Value) covers the primary search pattern: WHERE IndexType = ? AND ObjType IN (…) AND Value = ? which is a point lookup — no LIKE required.
Source:

(constant) id

Migration: Backfill FullTextIndex for accounting entities Accounts und FiscalYears wurden bisher ohne FullTextIndex angelegt, weil die accounting-backend Services (accountService, fiscalYearService) die Spalte nicht befuellt haben. Dadurch findet MATCH...AGAINST auf ObjectBase.FullTextIndex diese Eintraege nicht, da der Wert NULL ist. Diese Migration setzt FullTextIndex auf den Display-Wert fuer: - Type = 'account' (Display = "1200 - Kassenbestand") - Type = 'fiscalyear' (Display = "2025") - Type = 'costcenter' (Display der Group/Event)
Source:

(constant) id

Migration: Add FULLTEXT index on ObjectBase.FullTextIndex ObjectBase hat das Feld `FullTextIndex`, aber bisher keinen FULLTEXT-Index darauf. Dadurch versagen MATCH...AGAINST Queries mit "Can't find FULLTEXT index matching the column list". Diese Migration: 1. Setzt system_versioning_alter_history = KEEP (ObjectBase ist system-versioned) 2. Erstellt einen FULLTEXT-Index auf `FullTextIndex`
Source:

(constant) id

Migration: Swap lat/lng in Member.Geo for all rows Der Code hat bisher POINT(lat lng) geschrieben, MariaDB/MySQL erwartet aber POINT(lng lat). Alle bestehenden Geo-Einträge sind daher falsch herum. Diese Migration: 1. Liest jedes Member.Geo (POINT) 2. Schreibt es mit getauschten Koordinaten zurück: POINT(ST_Y, ST_X) 3. Member ist nicht system-versioned, daher kein SET HISTORY nötig
Source:

(constant) id

Invariante: **genau ein aktiver `memberA`-Link pro Objekt.** Diese Migration ist der kanonische Ort der Regel. Sie stand bisher weder in der Doku (`DB-Docu > Backend > Datenstruktur > Link-Legende` beschreibt `memberA` als "Administrative (erste Ebene) Mitgliedschaft", sagt aber nichts zur Eindeutigkeit) noch strukturell in der Datenbank. Durchgesetzt war sie nur als App-Guard in **einem** Pfad (`personHelpers.js` → `handleGroupMembershipMigration`), und dort dreifach eingeschraenkt: nur beim Uebertritt, nur fuer Quelle `person`/`extern`, nur fuer Ziel `group`/`ggroup`. Die uebrigen ~20 Insert-Stellen (`entry`, `group`, `location`, `job`, `email`, `list`, `dlist`, `guest`, `event`, `project`, `runner`, `tailnet`) umgehen diesen Guard vollstaendig. Deshalb ein DB-Trigger: er greift zentral, auch fuer `INSERT IGNORE`. ## Datenlage bei Einfuehrung (Prod, 2026-09-25) - 261.696 Objekte mit aktivem `memberA`, davon **95 mit mehreren** (92x zwei, 3x drei) = 98 ueberschuessige Links → 99,96 % konform - Aufschluesselung der Verstoesse: `person` 71, `extern` 9, `entry` 9, `group` 1, 5 verwaist (Link ohne `ObjectBase`-Zeile) - Ziele ausschliesslich `group` (158 Links) und `dlist` (20 Links) - Kein Objekt hat `memberA` auf **verschiedene Ziel-Typen** — die Mehrfach-Links liegen immer auf demselben Ziel-Typ - `memberS` (106 Objekte): 0 Duplikate, aber alle 106 haben **zusaetzlich** einen `memberA` → die Regel ist typ-spezifisch, nie "eine Mitgliedschaft insgesamt" ## Verifiziertes Verhalten (Wegwerf-`mariadb:11.7`, prod-identische Struktur `WITH SYSTEM VERSIONING` + `PARTITION BY SYSTEM_TIME`) 1. `CREATE TRIGGER` auf partitionierter **und** system-versionierter Tabelle funktioniert (MySQL verbietet das, MariaDB nicht). 2. `INSERT IGNORE` schluckt das `SIGNAL` **nicht** (Fehler 1644 kommt trotzdem) — Voraussetzung dafuer, dass die vielen `INSERT IGNORE` Stellen die Regel ueberhaupt spueren. 3. **Kein `BEFORE UPDATE` noetig.** Die internen Versionierungs-Inserts feuern diesen `BEFORE INSERT`-Trigger nicht: ein Objekt mit zwei aktiven `memberA`-Links liess sich nach Trigger-Einbau weiterhin `UPDATE`n. Haette die Versionierungs-Buchhaltung den Trigger gefeuert, haette die Pruefung den anderen Duplikat-Link gefunden und blockiert. 4. Altbestand bleibt **editier- und loeschbar**. Daraus folgt: die Migration ist nicht-brechend und benoetigt **kein** Daten-Pre-Cleanup. (Die 95 Verstoesse raeumt separat `GET /maintenance/personConsistency?fix=true`.) 5. `UIDTarget <> NEW.UIDTarget` ist **Pflicht**, nicht Kosmetik: der Trigger feuert *vor* der Duplikatspruefung, ein zweiter `INSERT IGNORE` **desselben** Links (heute ein stiller No-Op) wuerde sonst 1644 werfen. Ohne diese Bedingung brechen idempotente Re-Inserts an ~20 Stellen. 6. Pruefung laeuft ueber den Index (`PRIMARY`, `rows: 1`), kein Scan. 7. `SIGNAL ... SET MESSAGE_TEXT = CONCAT(...)` ist **nicht** erlaubt ("Undeclared variable: CONCAT") — die SET-Klausel akzeptiert nur Literale oder Variablen. Ausweg: `DECLARE msg VARCHAR(128)` + `SET msg = CONCAT(...)` + `SIGNAL ... = msg`. Nur so laesst sich die Objekt-UID in die Fehlermeldung aufnehmen. ## Reihenfolge-Anforderung an den Aufrufer Der alte Link muss **vor** dem neuen `INSERT` geschlossen sein, sonst blockiert der Trigger. Die lebenden Pfade halten das ein: `migratePerson.js` loescht `deltaOldPlus` (enthaelt immer das alte `memberA`-Ziel) vor dem `INSERT` des neuen Ziels. ## Folge fuer die Anwendung Ein Verstoss ist ab jetzt `errno 1644` / `SQLState 45000`. Die API-Schicht sollte das auf **409** (oder 400) mappen — sonst wird aus einem Datenproblem ein 500er. Rueckbau: `DROP TRIGGER IF EXISTS trg_links_single_membera_bi;`
Source:

(constant) id

Migration: avatar → array Converts Member.Data.avatar from a single file URL string to an array containing just the filename. If the stored URL already contains a `?` query string that part is kept; otherwise `?date=` is appended using the current wall-clock time so clients can bust their caches. Before: "avatar.jpg" or "https://…/UID/avatar/avatar.jpg" After: ["avatar.jpg?date=2026-03-29"] (filename only, array) Remove `export const disabled = true` to enable this migration.
Source:

(constant) id

Migration: Resize AIEmbeddings.Embedding column from VECTOR(768) to VECTOR(1536) Cohere embed-multilingual-v4.0 uses 1536 dimensions (vs. 768 from OpenAI text-embedding-3-small). MariaDB cannot ALTER a VECTOR column in-place, so we drop the old column and re-add it with the new size. All existing embeddings are cleared — they will be regenerated on next entity update. The vector-key index must be dropped before the column can be dropped.
Source:

(constant) id

Migration: ObjectBase.Data — fix NULLs and enforce NOT NULL DEFAULT '{}' Root cause of the ER_NET_PACKET_TOO_LARGE corruption incident (2026-04-12): When ObjectBase.Data was NULL the persons endpoint returned it as the literal string "null". The frontend echoed that string back in a subsequent PUT, where it was spread into the request body and then JSON.stringify()ed on every save, producing geometrically growing escaped backslash sequences. This migration: 1. Replaces all NULL and literal 'null' values with '{}' in the current rows. 2. Alters the column to NOT NULL DEFAULT '{}' so the DB rejects future NULLs. Note: system-versioned history rows are not writable; the ALTER TABLE will handle them implicitly by coercing any remaining NULLs in history to the column default during the table rebuild.
Source:

(constant) id

AP 30 — Rechte-Vererbung fuer Bestands-Shares materialisieren. Neue Shares ziehen ihren Rechte-Satz beim Anlegen/Verlinken nach (`./20260924-project-share-target-model` nur strukturell, die Vererbung selbst in `RouterProject/projectShare/access.js`). Der **Bestand** hat nur die Owner-Zeile: die Projekt-Rechte sind nirgends am Share materialisiert, und es gibt kein Rechte-Event, aus dem eine Projektion sie gewinnen koennte. Dieses Modul holt das nach — je Share: 1. den Filter-Satz des Projekts spiegeln (dieselbe Struktur wie bei Listen), 2. `Visible` neu materialisieren und die `/add|/remove/{shareType}/{level}/{uid}`- Events melden (macht `listRebuildAccess` selbst). Damit wird `share_grants` in der RAG-Projektion **ableitbar** statt gerechnet: die Kette Members (`Visible`) → Event → Projektion steht dann lueckenlos. Idempotent. Die Organisation kommt ueber die Link-Kette (`getOrganizationForShare`) — das Modul enthaelt keine UID.
Source:

(constant) id

Migration: Link existing runners to their owner groups and seed Visible admin. Runners now follow the same visibility model as projects: - `shared` runners get a `memberA` link to their org root group - every runner gets a `Visible admin` row for its creator (UIDuser) No schema change is needed — the `Links` and `Visible` tables already exist.
Source:

(constant) includeChangeability

Include changeability filter
Source:

(constant) includeVisibility

Include visibility filter
Source:

initPromise :Promise.<boolean>|null

Der laufende Initialisierungsversuch — alle Aufrufer teilen sich **einen**. Ohne das teilen sie sich nur den Zustand `isInitialized`, und der wird erst NACH `await client.connect()` gesetzt. Jeder Aufrufer, der in diesem Fenster startet, sieht `false`, erzeugt seinen eigenen Client und schreibt ihn in `pubClient`. Die Listener-Zeile liest `pubClient` danach **erneut** und trifft damit den ZULETZT erzeugten Client: beim Serverstart waren das 12 verbundene Clients (11 davon verwaist) und 11 `error`-Listener auf einem — genau die `MaxListenersExceededWarning: 11 error listeners added to [Commander]` (`Commander` ist die Client-Klasse von `@redis/client`).
Type:
  • Promise.<boolean> | null
Source:

(constant) initPublicBucket

Ensure the public bucket exists and is publicly readable. Uses publicMinioClient if available (independent endpoint), otherwise falls back to myMinioClient for backwards compatibility.
Source:

(constant) insertList

Insert a new list or dlist
Source:
Inserts `member` Links for delta groups, skipping person/extern/guest types (which handle their own link creation).
Source:

(constant) insertOrUpdateAchievement

Handles the insertion or update of an achievement for a member
Source:

(constant) invalidateCacheController

Source:

(constant) invalidateUserCache

Invalidate user cache for a specific user (call when user data changes)
Source:

(constant) invalidateUserCacheService

Invalidate user cache for one/multiple/all users.
Source:

ioInstance :SocketIOServer|null

Type:
Source:

(constant) isAdmin

Check if user is admin for current organization MIGRATION: Checks Keycloak orgRoles first, then falls back to database
Source:

(constant) isAdminOrga

Check if user is admin for an organization MIGRATION: Checks both Keycloak orgRoles (new) AND database admin list (legacy) Once bot sync is complete, database check can be removed
Source:

(constant) isBaseAdmin

Check if the base user (real user, not impersonated) has admin rights MIGRATION: Checks Keycloak orgRoles first, then falls back to database
Source:

isInitialized :boolean

Type:
  • boolean
Source:

(constant) isObjectInOrg

Does this object belong to the given organization? Replaces the former `ObjectBase.UIDBelongsTo = ` filter, which no longer holds once objects carry their self-reference / parent there (project, share). Both sides are compared as canonical UUID strings.
Source:

(constant) isUsableSharedRunner

Ist der Runner als Projekt-/öffentlicher Runner nutzbar (Soll: nicht personal, nicht revoked, in der Orga)?
Source:

(constant) isUserDataCached

Check if user data exists in cache
Source:

(constant) isValidUID

Checks if the given UID is a valid UUID string with a specific prefix. The UID must be a string that matches the following pattern: - Starts with "UUID-" - Follows the UUID version 1-5 format
Source:

(constant) isValidUid

Prüft, ob ein Wert eine UID in der hier gültigen Form ist.
Source:

(constant) jobQualified

Checks if a person is qualified for a job based on their achievements.
Source:

(constant) kvDel

Source:

(constant) kvExists

Source:

(constant) kvGet

Source:

(constant) kvSetEx

Key mit TTL setzen. @returns {Promise} true bei Erfolg.
Source:

lastMailAt

Zeitpunkt der letzten Fehler-Mail (ms).
Source:

(constant) linkShare

Ein **bestehendes** Repo an ein Projekt haengen (verlangt **changeable**). Das legt einen **Ableger** an: ein eigenes `ObjectBase`-Objekt mit eigener UID, das in `UIDBelongsTo` auf den **Basis-Share** (= der Root, die Index-Identitaet) zeigt und die projekt-eigenen Einstellungen traegt. Der Basis-Share bleibt unangetastet — derselbe Code wird damit **einmal** indexiert, auch wenn er in mehreren Projekten haengt ([Shares eines Projekts](https://members.app.commtool.org/-/001-Backend/Datenstruktur/dProjectShares)). **Harte Regel: ein Root hoechstens einmal je Projekt.** Haengt bereits ein Objekt desselben Roots am Projekt, ist der Aufruf idempotent (es ist genau dieses Objekt) oder ein `409 SHARE_ALREADY_IN_PROJECT`. Damit kann derselbe Root nicht als Basis **und** als Ableger im selben Projekt liegen. `linkType` wird nur noch **validiert** (Alt-Alias), nie geschrieben: der Modus ist eine Eigenschaft des Shares (§13.9 Punkt 3).
Source:

(constant) linkShare

POST /project/project/:projectUid/shares/:shareUid/link
Source:

(constant) listAchievementsPerson

Lists all achievements for a specific person
Source:

(constant) listCredentials

List credentials visible to the caller: - org-scoped credentials: org admins only - user-scoped credentials: the owning user sees his own; org admins see all
Source:

(constant) listCredentials

GET /project/credential
Source:

(constant) listEventGroupsController

List event groups controller with pagination support Handles GET /:UID
Source:

(constant) listEventsController

List events controller with pagination support Handles GET /
Source:

(constant) listFiles

List files in directory (GET /:UID)
Source:

(constant) listJobsController

List jobs for event with pagination support Handles GET /jobs/:UID
Source:

(constant) listLanguageFilesByAppController

List language files for a specific application. Handles GET /:app
Source:

(constant) listLanguageFilesController

List all available language files. Handles GET /
Source:

(constant) listProjects

GET /project/project
Source:

(constant) listRepoLanguageSlicesController

Dünne Überschicht aller Bot-Repos für die Session-Organisation. Handles GET /?lang=de
Source:

(constant) listRootGet

Controller for GET /list/
Source:

(constant) listRunners

List runners of the current org the user can see (visible | changeable | admin). Org admins and bots see all runners of the organization. Non-admins are filtered through the Visible table (creator/admin row + addVisibility group membership) — exactly the project `getListing` pattern.
Source:

(constant) listRunners

GET /api/runners
Source:

(constant) listShares

List all shares of a project (requires at least visible on the project). Shares are resolved through the project's memberA/member links — in both directions while the old rows still exist.
Source:

(constant) listShares

GET /project/project/:projectUid/shares
Source:

(constant) listTailnetRunners

List runners explicitly assigned to a tailnet network (Links.Type='tailnetRunner', UID=tailnet, UIDTarget=runner).
Source:

(constant) listTailnetRunners

GET /api/tailnets/:UID/runners
Source:

(constant) listTailnets

List tailnet networks of the current org the user can see (visible | changeable | admin). Org admins and bots see all networks. Optional `group_uid` filter (only networks of that owner group) — same as projects.
Source:

(constant) listTailnets

GET /api/tailnets
Source:

(constant) loadVisibleScopes

Laedt die Sichtbarkeits-Zeilen zu einer Menge von Objekten. Bewusst nur die uebergebenen Objekte: der Aufrufer weiss, welche Zeilen sein Lauf ueberhaupt anfassen kann, und alles andere waere teurer, nicht genauer. `cast: ['UUID']` ist hier **der Punkt der Normalisierung**: die Spalten `Visible.UID` und `Visible.UIDUser` sind `binary(16)` und kaemen sonst als Rohbuffer an. Jeder Vergleich muesste sie dann erneut umwandeln — genau das hat den Server blockiert (ein `asUuid` pro Paarvergleich, siehe publishVisibilityDiff). Einmal hier umgewandelt, sind die Zeilen ueberall im Weiteren direkt vergleichbar.
Source:

(constant) logError

Betriebsfehler: protokollieren, **nicht** mailen.
Source:

(constant) logFatal

Echter Fatal: protokollieren **und** mailen (gedrosselt, wenn konfiguriert). Gedacht fuer den Startpfad — wenn der Server nicht hochkommt, ist das die einzige Meldung, die jemand mitbekommt.
Source:

logStreamDb

Source:

logStreamError

Source:

logStreamLogin

Source:

logStreamRead

Source:

logStreamUpdateDb

Source:

(constant) loginLogger

Logs login events.
Source:

(constant) matchExcludersList

Matches objects against excluder lists and handles membership updates
Source:

(constant) matchObjectsLists

Matches objects against list filters and updates dynamic lists accordingly
Source:

(constant) memberAConsistency

Report and (optionally) repair duplicate and dangling `memberA` links.
Source:

(constant) mergeTemplateData

Merges existing template data with new data, preserving customizations. Default values support optional version-based enforcement: - The bot may supply a `defaultVersions` object alongside `defaults`, mapping each key to a monotonically increasing version number. - On re-registration a key is overwritten only when the bot's version is strictly greater than the stored version. - Admin-edited values are preserved as long as the bot does not bump the version for that key. - Templates that do not supply `defaultVersions` continue to work as before: existing values are always preserved (backwards-compatible). - `defaultsOriginal` is always overwritten with the bot's current defaults so the admin UI can offer a "reset to bot default" action at any time.
Source:

(constant) metadataFromRow

Extract the metadata object from a project row's `metadata_json` envelope (`JSON_OBJECT('value', JSON_EXTRACT(Data, '$.metadata'))`). With `{ cast: ['json'] }` the driver already parses the envelope into an object (`{ value: {...} }`), while legacy/test call paths may still deliver a JSON string. Both forms are normalized here; anything else yields `{}`.
Source:

(constant) migrate

Adds a Sequence column to TransactionLines to preserve booking line ordering (PosNr from old KPE system). Uses IF NOT EXISTS to stay idempotent.
Source:

(constant) migrate

Fuehrt die Datenmigration aus.
Source:

(constant) migrate

Adds TUID (human-readable UUID) virtual columns to both transaction tables, matching the same pattern used in ObjectBase, Member, Links, AIEmbeddings, and Visible. TUID is generated as: bytes[5-8]-bytes[3-4]-bytes[1-2]-bytes[9-10]-bytes[11-16] This mirrors the byte ordering of UUID v1 hex display, which is the format the CommTool @commtool/sql-query library (HEX2uuid/UUID2hex) expects. TransactionLines.UIDTransaction gets TUIDTransaction as a virtual FK display column.
Source:

(constant) migrate

Fuehrt den Owner-Backfill aus.
Source:

(constant) migrate

Source:

(constant) migrate

Source:

(constant) migrate

Source:

(constant) migrate

The replay endpoint (GET /api/kpe20/events) filters the eventLog by the organization, which previously required a full scan of millions of rows via JSON_VALUE(Data, '$.UIDorga'). A generated virtual column plus an index on (UIDorga, seq) makes org-scoped replay and high-watermark lookups fast.
Source:

(constant) migrate

Runner objects live in ObjectBase (topology, no versioned runtime state). `deployment`/`deploymentEndpoint` literals were dropped with the members runtime layer (see 20260907-runner-companion.js) — the runtime moved to the session (ide-server).
Source:

(constant) migrate

Source:

(constant) migrate

A share is linked to exactly one project via Links.Type='projectShare' with Links.UID = Project-UID and Links.UIDTarget = Share-UID. In addition Share.UIDBelongsTo = Project-UID is used as a fast association query. Both representations are written in the same transaction.
Source:

(constant) migrate

The cross-service contract (080-Workspaces/018-Cross-Service-Contracts.mdx) requires replay via an opaque, strictly ordered cursor. The existing eventLog PK is (Timestamp, EventKey), which is not a reliable monotonic cursor. A BIGINT AUTO_INCREMENT seq column provides the stable ordering needed by the GET /api/kpe20/events replay endpoint.
Source:

(constant) migrate

Drops and recreates Transactions + TransactionLines tables. The new Transactions table uses a `Data` JSON column as single source of truth. Previously separate columns (DocumentNumber, Date, Status, TransactionType, TotalAmount, DocumentSequenceNumber, FullTextIndex) are now PERSISTENT GENERATED COLUMNS derived from `Data`. TransactionLines stays unchanged.
Source:

(constant) migrate

Source:

(constant) migrate

Project objects are the Members source of truth for project-wide metadata. Repository- and directory-shares are share objects belonging to exactly one project. None of these target types gets its own visible-* filter type — shares derive all rights from their project (see workspace plan 025).
Source:

(constant) migrate

Tailnet networks are ObjectsBase objects (Type='tailnet'), one per network a team can create. Multiple networks per group are allowed — the owner group is tracked via Links.Type='memberA' (tailnet -> group), exactly like projects. Links.Type='tailnetRunner': UID = Tailnet-UID, UIDTarget = Runner-UID. A runner can be assigned to one or more networks; assigning/removing is an explicit control-plane operation (the Addon "Tailnet-Netze" group tab). `deployment`/`deploymentEndpoint` (ObjectBase) and `deploymentRunner` (Links) were dropped — they belonged to the members runtime layer (20260907-runner-companion).
Source:

(constant) migrate

Source:

(constant) migrate

Adds denormalized columns to Transactions so the transaction list can be fetched without JOINing on TransactionLines every time.
Source:

(constant) migrate

Source:

(constant) migrate

Erzwingt die Eindeutigkeit von `memberA`-Links auf DB-Ebene. Legt einen `BEFORE INSERT`-Trigger an. Nur `INSERT` — siehe Migrationkopf, Punkt 3: `UPDATE` braucht keine Pruefung, weil weder die legitimen Updates noch die internen Versionierungs-Inserts den Trigger faelschlich ausloesen. Idempotent: der Trigger wird verworfen und neu angelegt, damit eine spaetere Aenderung der Definition beim erneuten Lauf greift.
Source:

(constant) migrate

Source:

(constant) migrate

Source:

(constant) migrate

Fuehrt den Backfill aus.
Source:

(constant) migrate

Ergänzt `botRepo` in `Links.Type`. Ein „Bot-Repo" bündelt die Bots eines Repositories (z. B. alle Bots von `basic-bots`) und ist bewusst **nicht** organisationsgebunden: die UID wird im Repo selbst vergeben (`botRepo.json`) und existiert nur als Link-Endpunkt — genau wie die Bot-UIDs, die ebenfalls keine `ObjectBase`-Zeilen sind. `Links.Type='botRepo'`: UID = Repo-UID, UIDTarget = Bot-UID. Bewusst nur eine Migration auf `Links.Type`: `ObjectBase` bleibt unberührt, es wird **kein** neuer Objekt-Typ gebraucht. Eine `Links`-Zeile trägt keine Datenspalte, es wird also nichts „am Repo" gespeichert — die Beziehung ist der ganze Inhalt. Sollte später doch Repo-Metadaten (Name, Icon, …) nötig werden, ist der Weg eine Companion-Tabelle analog zu `RunnerData`. Bewusst **nicht** `appBot`/`app` genannt: `app`, `appDomain` und `appAsset` sind im App-Registry-Konzept (`PLAN-app-registry.md`) für org-gebundene, gehostete Frontends reserviert (Domain, Branding, PWA-Icons) — hier ist dagegen ein globales Bot-Repo gemeint. ## Warum die vorhandenen Werte gelesen werden Die Enum-Listen sind je Umgebung auseinandergelaufen und werden von der Migrationskette aufgebaut (`initTables.sql` ist ein alter Stand, jede Link-Typ-Migration ergänzt). Prod hat die 2026-09 ausgemusterte Runner-Runtime bereits hinter sich, Dev nicht: - Dev (`member`) führt zusätzlich `deploymentRunner`, `workspaceRunner` und `workspaceLease` — und zwar **in der History**. `Links` ist system-versioniert und nach Zeit partitioniert; `system_versioning_alter_history = 1` prüft das ALTER gegen diese Partitionen. Eine Liste ohne diese Werte schneidet dort ab und die Migration bricht mit „Data truncated for column 'Type'" ab (Zeile 295490). - Prod führt sie nicht und soll sie auch nicht bekommen: `20260827-tailnet-object-types` hat sie dort bewusst entfernt. Deshalb wird `botRepo` an die **jeweils vorhandene** Liste angehängt, statt eine kanonische Liste zu schreiben. Eine feste Liste wäre in beide Richtungen falsch: zu kurz für Dev (Abbruch), zu lang für Prod (rüstet ausgemusterte Typen wieder ein und macht die Entfernung aus `20260827` rückgängig). Zeichensatz und Collation kommen ebenfalls aus der Spalte, damit die Migration dort nichts umstellt.
Source:

(constant) migrate

Source:

(constant) migrateDB

Migrates the database by running all pending migration modules. Migrations are JS files in src/config/migrations/ and support both SQL schema changes and JSON data transformations. Applied migrations are tracked in the dbVersion table.
Source:

(constant) migrateFamilyAction

Handles `family` and `familyB` migration actions. Moves a person's family or familyFees link from the old family object to the new one. If the old family object has no remaining members the orphaned Member row is deleted; otherwise family fees are recalculated for it. Either way, fees are recalculated for the new family object.
Source:

(constant) migratePersonAction

Handles `person` and `extern` migration actions. Computes the symmetric difference between the old and new group memberships, then: - Rebuilds visibility for the groups gained by the move. - Re-evaluates list membership for the person in all new groups. - Re-checks list entries for the person. - Fires `/add/group/…` events for gained groups and `/remove/group/…` for lost ones.
Source:

(constant) minTimestamp

GET /minTimestamp/:UID — return the minimum allowed backdate timestamp (ms) for a group object, constrained by its latest history row.
Source:

(constant) minTimestamp

GET /minTimestamp/:group/:UID — return the minimum allowed backdate timestamp (ms) for adding a person/extern to a specific target group.
Source:

(constant) mirrorProjectFilters

Die Rechte-Filter des Projekts auf den Share spiegeln: hinzufuegen, was das Projekt hat; entfernen, was es nicht (mehr) hat. Der Share bekommt damit **denselben** Filter-Satz wie das Projekt und beim naechsten Rebuild dieselben `Visible`-Zeilen. Idempotent und rein strukturell (keine Rechte-Auswertung).
Source:

(constant) monitorDelayedUpdates

Processes the `delayedUpdateTimestamps` map and flushes any entries that have been quiet for longer than the debounce threshold (2.5 s). Should be invoked on a periodic interval (e.g. `setInterval`) by the server startup code. For each overdue entry it: 1. Finds all clients with a matching UID in their `updateAbo` Set. 2. Emits `{ update: true, UID, timestamp }` to those clients. 3. Removes the entry from `delayedUpdateTimestamps`. This is the trailing-edge part of the two-phase debounce implemented together with addUpdateList.
Source:

(constant) mysqlTimeToRfc3339

Convert a MariaDB timestamp string ('YYYY-MM-DD HH:MM:SS.ffffff', UTC) to the contract RFC3339 format with six fractional digits.
Source:

(constant) name

Human-readable description shown in progress output
Source:

(constant) nameReplace

Helper function to replace special characters with underscores
Source:

(constant) normalizeDomainEntry

Bringt einen Domain-Eintrag auf die Form `{ type, status }`. Nimmt **beide** Formen an, denn der Altbestand in Vault ist eine Zeichenkette (`{"kpe.de":"verified"}`). Die Zuordnung ist eindeutig, weil die alten Werte sich gegenseitig ausschließen: | Alt | `type` | `status` | Begründung | |---|---|---|---| | `internal` | internal | verified | Ein System-Präfix liegt im eigenen Namensraum — nachzuweisen gibt es nichts | | `external` | external | pending | Eine Kunden-Domain bleibt offen, bis der DNS-Eintrag zeigt | | `verified` | external | verified | Nur Kunden-Domains wurden je von Hand verifiziert — sie tragen einen Punkt |
Source:

(constant) normalizeDomainMap

Bringt eine ganze Domain-Map auf `{ domain: {type, status} }`.
Source:

(constant) normalizeDomainValue

Normalisiert einen Domain-Namen: Kleinschreibung, ohne führenden `*.`/`.` und ohne abschließenden Punkt. `*.Kpe.de.` → `kpe.de`.
Source:

(constant) normalizeUid

Bringt eine UID in die gültige Form. Akzeptiert bereits korrekte Werte, ein `Buffer(16)` (wie ihn `UIDV1()` liefert, via `HEX2uuid` umgesetzt) und die rohe 36-Zeichen-Form. Bewusst tolerant beim Lesen, streng beim Schreiben: Werte aus `session`, Vault oder einer älteren Zeile sind nicht immer schon normalisiert.
Source:

(constant) objectInOrgSql

The same rule as `getOrganizationForObject`, but as a SQL predicate so a listing can scope many rows in one query instead of resolving each object. Bind the organization **twice** (the predicate uses two placeholders) — both times as the value you would pass as `orgUID`.
Source:

(constant) optimizeDatabase

Optimizes database tables
Source:

(constant) optimizeTables

Utility function to optimize and analyze all tables in the database
Source:

(constant) paginateCollectionsUIDController

Pagination pre-handler for GET /:UID.
Source:

(constant) parseEnumValues

Liest die Werte einer `enum(...)`-Spaltendefinition aus. Die Werte dürfen Kommas und Klammern enthalten, deshalb wird zeichenweise gelesen statt an Kommas zu trennen. MySQL/MariaDB verdoppelt Anführungszeichen innerhalb eines Werts (`'a''b'`).
Source:
Example
parseEnumValues("enum('a','b')") // ['a', 'b']

(constant) parseTimestamp

Parses the timestamp from a tree action and produces the SQL `FOR SYSTEM_TIME AS OF` clause string.
Source:

(constant) parseTimestamp

Normalises a raw action timestamp into a numeric value and the corresponding `FOR SYSTEM_TIME AS OF …` SQL clause.
Source:

(constant) patchRunnerData

Update runner Data fields (tailnet, capabilities) — schreibt nur bei echten Änderungen (kein versioniertes ObjectBase-Wachstum durch identische Heartbeat-Meldungen).
Source:

(constant) personAdmin

Checks if the logged-in user has admin rights for a given person UID
Source:

(constant) personConsistency

Report and (optionally) repair person level drift for the current organisation. GET /maintenance/personConsistency → report only, no writes. GET /maintenance/personConsistency?fix=true → additionally align `Member.Data.stage`/`hierarchie` with `ObjectBase`. Surplus `memberA` links are handled by `memberAConsistency`.
Source:

(constant) personDuplicates

Finds potential duplicate person records based on phonetic similarity
Source:

(constant) personHistorie

Retrieves the historical group membership information for a person
Source:

(constant) personRebuildAccountingAccess

Rebuilds accounting visibility (Visible.Accounting) for a person based on their accountingVisible/accountingChangeable filter objects (rule-based access). Evaluates the filter rules and sets Visible.Accounting entries. Respects hierarchy: admin > changeable > visible — never overwrites a higher level. This is a separate step from personRebuildAccess and should only be called when accounting rules change (financialMaster toggle or accountingAccess/ accountingWriteAccess changes), NOT on every visibility rebuild.
Source:

(constant) postCollectionsController

Controller for POST /
Source:

(constant) postCountsController

Controller for POST /counts
Source:

(constant) postDlistEntryController

Handle POST /dlist/params/:UIDlist/:UIDperson — update entry params for a dynamic list
Source:

(constant) postDlistUID

Controller for POST /dlist/:UID
Source:

(constant) postEntry

Update extra parameters for a person's entry in a list
Source:

(constant) postListEntryController

Handle POST /list/params/:UIDlist/:UIDperson — update entry params for a static list
Source:

(constant) postListUID

Controller for POST /list/:UID
Source:

(constant) postShare

PUT /project/project/:projectUid/shares
Source:

(constant) postSnapshotCurrent

POST /projects/:projectUid/snapshot/current
Source:

(constant) preWarmUserCache

Pre-warm cache with commonly accessed users
Source:

(constant) processExclude

Processes exclude filter operations
Source:

(constant) processGgroupMemberships

Handles guest-group (ggroup) membership for the object being added. Creates guest records or cascades group guests as appropriate.
Source:

(constant) processInclude

Processes include filter operations
Source:

(constant) processIncludeFilter

Processes include filter and creates new entries based on filter criteria
Source:

(constant) processLastschrift

Processes SEPA mandate data for family fees
Source:

(constant) projectInOrg

Verify that a project exists within the current organization. The organization is derived over the owner group (`project → memberA → group → … → root group`), not read from `UIDBelongsTo` — that field now holds the project's own UID.
Source:

(constant) projectSelect

Full project SELECT used for reads. `source_updated_at` is derived from the temporal row start (ValidFrom) with microsecond precision.
Source:

(constant) projectShareRoots

Alle Shares eines Projekts mit ihrem Root — beide Link-Richtungen. Das ist die Grundlage der harten Root-Regel: **ein Root hoechstens einmal je Projekt**. Ohne sie haengen Basis und Ableger desselben Repos doppelt im Projekt.
Source:

(constant) projectToContract

Map an ObjectBase row to the contract Project object.
Source:

(constant) projectsOfShare

Die Projekte eines Shares — beide Link-Richtungen.
Source:

(constant) projectsOfShares

Die Projekte mehrerer Shares auf einmal — fuer die Anzeige der **Herkunft** eines Ablegers („kommt von Projekt X") ohne eine Abfrage je Zeile.
Source:

(constant) promoteRoot

Die Basis eines Roots auf einen Ableger umhaengen: der Nachfolger wird die neue Basis (Selbstreferenz), alle uebrigen Ableger zeigen auf ihn. Danach ist der alte Root frei — genau das braucht „Basis loeschen, aber ein Ableger soll sie ersetzen". Innerhalb einer Transaktion **muss** `connection` mitgegeben werden.
Source:

pubClient :redis.RedisClientType|null

Type:
  • redis.RedisClientType | null
Source:

(constant) publicObjectUrl

Build the direct public URL for an object in the public bucket. First checks S3publicBaseUrl for a full override, then tries dedicated public S3 connection vars (publicS3endPoint etc.), and finally falls back to the protected S3 endpoint as before.
Source:

(constant) publishChangeEvent

Publishes change events for person modifications. Notifies related entities (groups, organizations) about changes to a person.
Source:

(constant) publishEvent

Publishes an event to Redis with multi-tenant organization scoping and persists it to eventLog for replay.
Source:

(constant) publishGroupEvent

Publishes an event for a person joining or leaving an organization. Notifies the group and its parent groups about the person's status change.
Source:

(constant) publishGroupEvents

Publishes `/add/group/…` or `/remove/group/…` events for each group in the provided list.
Source:

(constant) publishMembershipEvents

Publishes membership-change events for all groups in `deltaPlus`.
Source:

(constant) publishToRedis

Publish a prepared payload to Redis (live channel). Never throws.
Source:

(constant) publishVisibilityDiff

Vergleicht zwei Staende und meldet die Differenz. Verglichen wird das Paar `(UID, UIDUser)` **inklusive** Level: eine Zeile, die von `visible` auf `changeable` wandert, ist kein `add` auf ein leeres Blatt, sondern ein `add` auf ein bereits gemeldetes — der Bot fuehrt den staerkeren Stand. Ein `remove` fuer ein Level, das die Zeile nie hatte, entsteht dadurch nicht. Reihenfolge: erst `remove`, dann `add` — ein Herabstufen (Loeschen und neu Anlegen in einem Lauf) kommt so in der richtigen Ordnung an. Laufzeit: **O(n+m)**. Die kanonischen Schluessel werden je Zeile genau einmal gebildet (scopeKey) und ueber zwei `Set` verglichen, statt jedes Paar erneut zu normalisieren.
Source:

(constant) putCredential

PUT /project/credential
Source:

(constant) putDlistOwner

Controller for PUT /dlist/:owner
Source:

(constant) putEntry

Add one or more persons as entries to a static list
Source:

(constant) putEntryController

Handle PUT /list/person/:UIDlist — add persons to a static list
Source:

(constant) putGroup

PUT /:UIDparent — create or update a group under the given parent.
Source:

(constant) putListOwner

Controller for PUT /list/:owner
Source:

(constant) putProject

PUT /project/project/:group
Source:

(constant) putRepoLanguageController

Schreibt eine Ebene. Ohne `:UIDroot` die geteilte Ebene, sonst die der angegebenen Organisation. Handles PUT /:repo/:lang und PUT /:repo/:UIDroot/:lang
Source:

(constant) putTailnet

PUT /api/tailnets/:group
Source:

(constant) putUser

Ensure identifyer link and self-visibility are in sync for one person.
Source:

(constant) putUserController

Source:

(constant) queryAllGroupsOf

Returns every group `UIDTarget` is currently a member of.
Source:

(constant) queryGainedGroups

Returns the groups that belong to `UIDnewTarget` but are **not** exclusively shared with `UIDoldTarget`, together with the derived delta arrays.
Source:

(constant) queryLostGroups

Returns the groups that belong to `UIDoldTarget` but **not** to `UIDnewTarget`, together with the derived delta arrays.
Source:

(constant) queueRunning :Record.<string, boolean>

Type:
  • Record.<string, boolean>
Source:

(constant) readAgeUpdateStats

Stats für eine Organisation lesen. Wird von members-back (`GET /person/ageUpdate/stats`) aufgerufen.
Source:

(constant) readLogger

Logs read/GET requests.
Source:

(constant) readProjectRunnerUid

Projekt-Runner aus `metadata.runnerUid` lesen (Wire-UID „UUID-…" oder null). Quelle: Project.Data.metadata.runnerUid (Projekteinstellung „öffentlicher Runner", Soll-Auflösung beim Session-Anlegen).
Source:

(constant) readRunnerMeta

Minimales Runner-Record für interne Validierung/Auflösung (kein Sichtbarkeits-Check — der Aufrufer prüft Orga/Auth selbst).
Source:

(constant) rebuildAccountingVisibility

Rebuilds accounting visibility for ALL function templates in the organization. Iterates over every function template and calls syncAccountingForFunction, which in turn re-evaluates Visible.Accounting for every job linked to that function. Sends progress events via WebSocket.
Source:

(constant) rebuildEventAccess

Rebuild event access completely Deletes all visibility filters and visibilities, then rebuilds them
Source:

(constant) rebuildEventVisibility

Rebuild event visibility from scratch
Source:

(constant) rebuildExternAccess

POST /rebuildAccess/:UID — Rebuild visibility and list access for an extern.
Source:

(constant) rebuildExternAccess

Rebuild visibility and list access for an extern and all its job objects. Delegates to the shared helper in personHelpers.
Source:

(async, constant) rebuildFeesGroup

Rebuilds the fees for all families that have a member in the specified group. This has to be called, if the fees of a group have changed, so that all families with members in this group will have their fees recalculated according to the new group fee rules.
Source:

(constant) rebuildListEntries

Rebuilds list entries
Source:

(constant) rebuildPersonAccess

POST /rebuildAccess/:UID — Rebuild visibility and list access for a person.
Source:

(constant) rebuildSearchIndex

Rebuild the SearchIndex table for a given object type Clears and rebuilds search index entries (email, phone, etc.) for all objects of the specified type in the current organization.
Source:

(constant) rebuildShareAccess

`Visible` eines Shares neu materialisieren und die Rechte-Events melden. Bewusst ueber die Queue (wie `rebuildListVisibility` bei Listen): der Rebuild laeuft asynchron, ein Fehler dort darf das Anlegen/Linken nicht zurueckrollen.
Source:

(constant) reconcileShare

Einen Share vollstaendig nachziehen: Filter spiegeln **und** Rechte materialisieren. Nach Anlegen, Verlinken und Entlinken aufrufen.
Source:

(constant) reconcileSharesOfProject

Alle Shares eines Projekts nachziehen — nach einer Aenderung an den Projekt-Rechten und beim Anlegen/Entfernen von Shares.
Source:

(constant) recreateAllJobsController

Recreate all jobs for organization Handles GET /recreate
Source:

(constant) recreateEventsLocations

Recreates event / location objects. ObjectBase holds system-versioned fields; Member holds display fields.
Source:

(constant) recreateFunctions

Recreates function template objects. ObjectBase only (UIDBelongsTo = org UID). Uses DELETE+INSERT.
Source:

(constant) recreateGgroups

Recreates ggroup (guest group) objects. All fields live in ObjectBase — no own Member row. Uses versioned UPDATE (not DELETE+INSERT) to preserve clean history.
Source:

(constant) recreateJobs

Recreates job objects. ObjectBase only (UIDBelongsTo = person UID). Uses DELETE+INSERT because jobs carry a computed `dindex` (qualification status) that must be replaced.
Source:

(constant) recreateJobsFunction

Recreates jobs based on a specified function template. This function retrieves all jobs associated with a given function template and recreates them based on the template using the recreateJobs function. it should be called, when a function template is updated without changed to the achievement rules.
Source:

(constant) recreateJobsGroup

Recreates all jobs within a specified group using templates. This function fetches all job objects associated with a given group, optionally at a specific point in time (using system versioning), and recreates them based on their templates using the recreateJobs function. this function should be called, when a group is updated.
Source:

(constant) recreateJobsOrga

Recreates all jobs for an organization based on templates. This function queries the database for all job objects belonging to the organization, optionally as of a specific timestamp, and then recreates them. It retrieves related data such as person, function, group, and member information needed for job recreation.
Source:

(constant) recreateObjects

Recreates all objects of the organization of the given type via the template
Source:

(constant) recreatePersonJobsController

Recreate jobs for a person Handles GET /recreate/:UIDperson
Source:

(constant) recreatePersonsExternGuests

Recreates person / extern / guest objects. Inherits stage, hierarchie and banner from the member group, then re-renders.
Source:

(constant) recreateWithMemberRow

Recreates group / list / dlist / email (and any other type that stores its data in Member.Data and display fields in Member). ObjectBase holds system-versioned fields; Member holds display fields.
Source:

redisUrl :string

Type:
  • string
Source:

(constant) reduceFiltered

Reduces filtered results to unique entries by UIDBelongsTo
Source:

(constant) reduceObjects

Reduces duplicate objects to unique entries based on UIDBelongsTo comparison
Source:

(constant) regenerateEmbeddings

Regenerate AI embeddings for all objects of a specific type Endpoint to regenerate embeddings for person, extern, guest, or job types. Processes objects in batches with single API call per batch for cost efficiency.
Source:

(constant) registerBotActionTemplates

Register bot action templates (POST /register)
Source:

(constant) registryAuth

Das Gate für den gesamten Router — `bot` und `employee`, kein Mandanten-Nutzer. Begründung und Abgrenzung: Dateikopf. Statischer Import ist hier in Ordnung: `addons.js` macht es genauso, und die Middleware wird erst beim ersten Request ausgeführt — zu diesem Zeitpunkt sind die Secrets konfiguriert.
Source:

(constant) removeDlistFilterAction

Handles removal of dlist filter actions: include, exclude, intersect. Removes all entries produced by the filter, deletes the filter's Links and ObjectBase row, then flags the target list for WebSocket update.
Source:

(constant) removeFamilyAction

Handles the `family` remove action. Deletes the `family` / `familyFees` link from the family object. If that was the last member the orphaned Member row is cleaned up; otherwise membership fees are recalculated for the affected family.
Source:

(constant) removeFilter

Removes a filter from a target and cleans up associated entries
Source:

(constant) removeListEntryAction

Handles the `list` remove action. Fired when a list entry is deleted. Cleans up any `member`, `member0`, and `dynamic` Links that dlists created for this entry, and notifies subscribers via event-bus and WebSocket. The entry itself has already been deleted by the time this action runs; only the downstream dlist bookkeeping remains.
Source:

(constant) removeMemberAction

Handles tree-structural remove actions for objects leaving a group hierarchy. Supported types: `job`, `guest`, `groupGuest`, `group`, `person`, `extern`, `achievement` (stub), `event`, `eventJob`. Steps: 1. Resolve current memberships of the removed object. 2. Delete `member` links for `job` and `guest`. 3. Job-specific: delete visibility filters and rebuild the holding person's access. 4. groupGuest: queue removal for all guest children; clean up memberG/memberGA links. 5. guest: delete the guest ObjectBase row. 6. group: cascade-delete member links; queue filter removals; re-check list entries. 7. person/guest/extern/job: re-check list entries via `checkEntries`. 8. event: rebuild object visibility. 9. Publish removal events and trigger WebSocket updates.
Source:

(constant) removeMemberFromFamily

Remove member from family (DELETE /:UIDmember) Removes a member from their current family and creates a new family for them. Supports rebate mode for fee calculations.
Source:

(constant) removePersonsFromEmail

Remove persons from email
Source:

(constant) removeTailnetRunner

Remove a runner from a tailnet network.
Source:

(constant) removeTailnetRunner

DELETE /api/tailnets/:UID/runners/:runnerUID
Source:

(constant) removeVisibilityFilterAction

Handles removal of visibility filter actions: visible, changeable. Removes the filter's `list` Link, deletes the filter object itself, then rebuilds the access table for the affected list/dlist/email and flags it for WebSocket update.
Source:

(constant) renewalMaintenance

Maintenance endpoint to check renewal of achievements
Source:

(constant) replayEvents

Replay events for an organization in strict cursor order.
Source:

(async, constant) requalify

Requalifies all jobs based on the given function template. This function fetches all jobs related to the specified function template and updates their qualification status. It also recreates the jobs with the updated qualification status. This function should be called, when a function template including its achievement rules is updated.
Source:

(constant) requalifyPersons

Requalifies all jobs based on function templates
Source:

requestQueue :Array.<{requestFn: function(), resolve: function(), reject: function()}>

Type:
  • Array.<{requestFn: function(), resolve: function(), reject: function()}>
Source:

(constant) requestUpdateLogger

Logs write/update requests.
Source:

(constant) requireRunnerAuth

Middleware: authenticate runner credential.
Source:

(constant) resolveGroupDelta

Queries the transitive group memberships (delta) for the given target group.
Source:

(constant) resolveSecondLevelGroups

Queries the second-level parent groups needed for visual display updates.
Source:

(constant) resolveVisibilityOrganization

Die Organisation fuer ein Event-Payload, wenn der Aufrufer keine mitgibt. Der Aufrufer weiss sie in aller Regel (`action.UIDroot`, `req.session.root`) und reicht sie durch — hier steht nur der Rueckfall. Ohne ihn traegt das Event die Null-Organisation, obwohl die Zeile am richtigen Objekt landet; genau dieser Fehler war schon einmal da (Commit `0738a87`). Der Import ist dynamisch, damit die Baum-Ebene nicht zyklisch auf die Router-Ebene zeigt (`organizationUtils` zieht `Router/orga/service.js`).
Source:

(constant) restartActionTemplate

Restart action template (POST /restart/:UID)
Source:

(constant) restorePerson

Restores a person from historical data
Source:

(constant) reverseGeocode

Reverse geocode coordinates to a place name
Source:

(constant) reverseGeocodeController

Reverse geocode: coordinates → place name
Source:

(constant) revertList

Revert all entries in a list to their state at a given timestamp
Source:

(constant) revertListController

Handle POST /list/revert/:UID/:timestamp — revert list entries to a previous state
Source:

(constant) revokeRunner

Soft-revoke: set Data.status=revoked, keep ObjectBase for audit. Die Companion-Auth (Member.lookup_key ↔ ObjectBase) lehnt weitere Requests ab.
Source:

(constant) revokeRunner

POST /api/runners/:UID/revoke
Source:

(constant) rfc3339ToMysql

Convert an RFC3339 timestamp (with optional timezone offset and microsecond fraction) into a UTC MariaDB timestamp literal for FOR SYSTEM_TIME AS OF. Returns null when the value is not parseable.
Source:

(constant) rootOfShare

Der Root (Basis-Share) eines Share-Objekts, plus die Angabe, ob es selbst die Basis ist. `null`, wenn die UID kein Share ist.
Source:

(constant) runMigrations

Discovers and runs all pending migration modules from this directory. Each migration file must export: - `id` {string} — stable unique identifier used to track applied state - `name` {string} — human-readable description shown in progress - `migrate` {async fn} — receives the migration API and performs the change Migrations support any logic: SQL schema changes, JSON data transformations, backfills, or any combination. Files are executed in alphabetical filename order.
Source:

(constant) runnerInOrg

Source:

(constant) sanitizeActions

Sanitize an actions payload from a function template. Malformed entries (non-strings) are dropped. Unknown *string* actions are preserved: the server only ever *grants* actions it knows (`hasActionPermission`), stored unknown actions are inert and stay available for forward compatibility.
Source:

(constant) saveAppsController

PUT /kpe20/orgaSettings/apps Saves the app registry for the current organisation. Request body: { [appId]: { domain, roles, title, description?, port? } }
Source:

(constant) saveDomainsController

PUT /kpe20/orgaSettings/domains Validates and saves the domain settings for the current organisation. Request body: { [domain: string]: "internal" | "external" }
Source:

(constant) scanHostKey

Scan the SSH host keys of a Git host via `ssh-keyscan`. The host key is the server identity of the Git host (used for `StrictHostKeyChecking` when the worker clones). It is NOT the credential key pair — the credential is the client identity. `ssh-keyscan` runs on the backend because browsers cannot execute it. The host is validated strictly (hostname + optional port) and passed as a plain argv element (no shell), so there is no command injection surface. Only ed25519 keys are collected — the modern, strongly recommended type.
Source:

(constant) scanHostKey

GET /project/credential/hostkey?host=...
Source:

(constant) searchShares

Search org-owned repository/directory shares the current user may see. Visibility is derived from the projects a share is linked to: a share is returned when at least one of its linked projects is visible to the user (admin users see all org shares). Because a share carries no organization itself, the result is additionally scoped to the caller's organization via the project chain.
Source:

(constant) searchShares

GET /project/project/shares/search
Source:

(constant) sendError

Send an error response using the contract envelope.
Source:

(constant) sendErrorFrom

Normalize a thrown error into a contract error response. Errors that already carry an ApiError shape (code/status) are honoured; everything else becomes 500.
Source:

(constant) sendMessageBuffered

Sends a message to a client, buffering update messages when the socket is temporarily disconnected. **Behaviour:** - If `message.update` is truthy, the message is treated as a list-update notification. Only the latest such notification per client is kept (`clientData.updateBuffer`). If the socket is connected it is sent immediately and the buffer is cleared; otherwise it waits. - Any other message payload is forwarded directly via `socket.emit` (Socket.IO itself buffers these internally when disconnected). - When called with `message = null` the function flushes any buffered update notification. This is triggered automatically after a successful `setRoot` event.
Source:

(constant) sendOk

Send a successful response using the contract envelope.
Source:

(constant) sendProgressStatus

Broadcasts a long-running operation's progress status to all clients of an organisation. This is an organisation-wide broadcast — every connected client whose `UIDroot` matches `root` receives `{ progressStatus: status }`. The frontend forwards the payload to any registered `cbProgressData` callbacks. Typical callers: import jobs, bulk operations, async queue workers.
Source:

(constant) sendTransaction

Sends a transaction-completion message to a single specific client. Unlike the organisation-wide broadcast functions, this targets exactly one socket by its `socketID` room. Emits a `transactionComplete` event with the provided data payload. Called after a bulk database transaction finishes, so the initiating client can refresh its state.
Source:

(constant) sendWebSocketUpdates

Sends WebSocket update notifications for all affected groups. Person and extern updates are skipped (handled by migratePerson storage).
Source:

(constant) setOrgaRoot

Set the organization root for the current session
Source:

(constant) setResponsibleController

Set responsible person Handles POST /responsible/:event
Source:

(constant) setupSocketHandlers

Registers all Socket.IO connection and event handlers. Called once at server startup with the Socket.IO `io` instance. Stores `io` in the module-level `ioInstance` so that other exported functions (e.g. `broadcastUpdate`) can reach connected sockets. **Connection lifecycle:** 1. Validates JWT-authenticated `socket.data.user` (set upstream by auth middleware). 2. Requires a `?id=` query parameter to derive a stable `socketID`. 3. Requires organisation context from `x-organization` header or token claims. 4. Creates an entry in clientDataStore keyed by `socketID`. 5. Joins the socket to a private room named `socketID` for targeted emits. 6. Registers per-socket event handlers (see below). 7. Removes the `clientDataStore` entry on disconnect. **Socket events handled per connection:** | Event | Payload | Effect | |-----------------|-------------------------------|--------| | `transaction` | `{ start: boolean }` | Marks bulk-transaction mode on `socket.data.transaction` | | `monitor` | `{ UID: string\|null }` | Adds list UID to `updateAbo` Set; `null` clears the Set | | `monitorObject` | `{ UID: string\|null }` | Adds object UID to `objectAbo` Set; `null` clears the Set | | `setRoot` | `{ UIDroot: string }` | Updates active organisation for the connection | | `disconnect` | reason string | Removes entry from `clientDataStore` | | `error` | Error | Logs the socket error |
Source:

(constant) shareEmail

Share email (delegate to list share function)
Source:

(constant) shareLinkToContract

Map a raw ObjectBase row to the contract Share object for a share that also carries a memberA/member link (used by snapshot reads over system time).
Source:

(constant) shareToContract

Map an ObjectBase row to the contract Share object. The share belongs to the org, so the contract `project_uid` is taken from the project context that resolved the share (via memberA/member link), never from UIDBelongsTo.
Source:

(constant) sharedFieldsChanged

Die geteilten Felder, die eine Schreiboperation WIRKLICH veraendert hat. Praesenz allein genuegt nicht: ein Aufrufer kann das ganze Objekt schicken, obwohl der geteilte Teil unveraendert ist. Nur bei einer echten Aenderung darf bei den Geschwistern abgeglichen — also auch entfernt — werden. Konten werden entschluesselt verglichen (`accountsEqual`): `IBANencrypted` traegt einen zufaelligen Salt, ein Vergleich der Rohdaten schluege deshalb immer fehl.
Source:

(constant) sharedFieldsTouched

Die geteilten Felder, die eine Schreiboperation tatsaechlich geliefert hat. Grundlage ist der PATCH (`req.body`), nicht die gemergten Daten: nur so ist „Feld war nicht Teil dieses Speicherns" von „Feld wurde geleert" zu trennen. Die gemergten Daten tragen den alten Wert immer weiter, ein Loeschen sieht dort aus wie „unveraendert".
Source:

(constant) sharedKeyOf

Schluessel, an dem ein geteilter Eintrag wiedererkannt wird. Ein leerer Rueckgabewert heisst „kein Schluessel" — solche Eintraege werden nur angehaengt, nie zugeordnet, damit zwei leere Eintraege nicht miteinander verschmelzen.
Source:

(constant) sharesOfProject

Die Shares eines Projekts — beide Link-Richtungen.
Source:

(constant) snapshotAsOf

GET snapshot?asOf= - historical snapshot.
Source:

(constant) snapshotCurrent

POST snapshot/current - authoritative DB time snapshot.
Source:

(constant) statsKey

Redis-Key für eine Organisation.
Source:

(constant) suggestFamiliesByLastName

Suggest families by last name (GET /suggest/:lastName) Provides family suggestions based on phonetic matching of last names. Uses double metaphone algorithm for fuzzy matching and scoring.
Source:

(constant) sweepDisconnectedClients

Verwirft Clients, die sich innerhalb der Schonfrist nicht neu verbunden haben. Ohne das wuerde jeder abgestuerzte Tab seinen Eintrag dauerhaft behalten.
Source:

(constant) syncBySourceController

Source:

(constant) syncShareFilters

Den Filter-Spiegel eines Shares an seinen aktuellen Projekt-Link angleichen. Ohne Projekt (z. B. nach dem Entlinken) fallen die gespiegelten Filter weg. Kein Rebuild — nur die Struktur. Innerhalb einer Transaktion **muss** `connection` mitgegeben werden, damit Share und Filter-Satz zusammen committen.
Source:

(constant) syncUsers

Sync identifyer links for selected persons.
Source:

(constant) syncUsersBySource

Sync identifyer links and add self-visibility for all persons in one orga.
Source:

(constant) syncUsersController

Source:

targetUID

`l.UIDTarget`, never `t.UID`: a dangling link has no `t` row, and the target UID is exactly what the removal has to match on.
Source:

(constant) toLegacyDomainValue

Gegenstück zu normalizeDomainEntry für den **Vault-Schreibpfad**. Solange `REGISTRY_READ_MODE` nicht auf `db` steht, schreibt `saveOrgDomains` weiter nach Vault — und dort lesen `shared-auth` (`organizationDomains.js`) und die übrigen Konsumenten eine **Zeichenkette**: sie vergleichen mit `state === 'internal'` bzw. `state === 'verified'`. Ein Objekt dort würde sie brechen. Die Rückübersetzung ist verlustfrei, weil die drei Altwerte die drei sinnvollen Kombinationen genau abdecken.
Source:

(constant) toProject

Convert a raw project row (with metadata_json envelope) to the app object shape: UID/Title/Display/Data (+ source_updated_at). Same convention as list/dlist/location/event objects.
Source:

(constant) toRfc3339Micro

Format a DB timestamp (Date, string or number) as RFC3339 with microsecond precision (the contract's API time format).
Source:

(constant) toRunner

Source:

(constant) toShare

Map a share row to the app Share object (UID / Type / project_uid / metadata / linkType). `project_uid` comes from the project context; the organization is no longer readable from the share itself.
Source:

(constant) toTailnet

Source:

(constant) triggerMaintenance

Triggers the organisations tree queue
Source:

(constant) typesIn

Build a SQL IN (...) list of quoted literals from a type set.
Source:

(constant) unlinkShare

Remove a link between a share and a project (requires **changeable**). Fires the matching level event; the share object itself is never removed here.
Source:

(constant) unlinkShare

DELETE /project/project/:projectUid/shares/:shareUid/link
Source:

(async, constant) updateAchievements

Consolidates all achievement UIDs for a person into their Data object. This function fetches all achievements linked to a specific person, encodes their UIDs in base64 format, and stores this consolidated array in the person's Data object. This approach enables faster filtering and querying of persons based on their achievements without needing to perform complex joins each time. The function only updates the person's record if the achievements data has actually changed, minimizing unnecessary database operations.
Source:

(constant) updateAction

Update an existing action
Source:

(constant) updateActionTemplate

Update action template (PUT / and POST /) Handles single template update for the current organization only. For multi-org bot registration and creation, use POST /register endpoint instead.
Source:

(constant) updateConfig

Notifies all clients of an organisation that the app configuration has changed. This is an organisation-wide broadcast — every connected client whose `UIDroot` matches `root` receives `{ updateConfig: , app }`. The frontend re-fetches config for the specified app.
Source:

(constant) updateEmail

Update email data
Source:

(constant) updateEventController

Update event controller Handles POST /:UID
Source:

(constant) updateEventList

Update a list for an event
Source:

(constant) updateEventListController

Controller for updating an event list
Source:

(constant) updateEventTemplate

Update an existing event template
Source:

(constant) updateEventTemplateController

Controller for updating an existing event template (POST)
Source:

(constant) updateExistingExtern

Update an existing extern record, or migrate a person record to type 'extern'. Delegates shared update logic to personHelpers. Note: `req` is forwarded because updatePersonData / handleGroupMembershipMigration internally require session information from it.
Source:

(constant) updateExistingPerson

Update an existing person record, or migrate an extern record to type 'person'. Note: `req` is still forwarded because the shared personHelpers functions that handle DB updates (`updatePersonData`, `handleGroupMembershipMigration`) require session information from it internally.
Source:

(constant) updateExtern

POST /:UID — Partial update of extern data. By default only accepts 'extern' type. With query parameter `?strict`, also accepts 'person' type.
Source:

(constant) updateFamily

Update family data (POST /:UID) Updates family information including address, contact details, accounts, and fee address. Handles both family-level updates and member-specific updates.
Source:

(constant) updateGroup

POST /:UID — partial update of an existing group.
Source:

(constant) updateGroupData

Updates an existing group's display data, sister-group link, banner, and fees. Unlike createOrUpdateGroup, this merges the request body over existing data rather than replacing it, and rejects changes to immutable fields.
Source:

(constant) updateGroupMembership

POST /:group/:UID — Update group membership for an extern.
Source:

(constant) updateGroupMembership

Updates group membership for a person
Source:

(constant) updateGroupMembershipShared

Shared function to update group membership for person or extern Response: `result` carries the new state of the object in the same shape the websocket clients receive (`{ person, parent }`), so a caller can apply it directly instead of re-fetching or waiting for the socket echo. It used to be `null`, which forced clients to reload and left them with a stale view until the echo arrived.
Source:

(constant) updateJobController

Update job template Handles POST /:UID
Source:

(constant) updateList

Update existing list/dlist
Source:

(constant) updateMemberDisplay

Updates the display fields in the Member table (no system versioning).
Source:

(constant) updateObjectBaseVersioned

Updates system-versioned ObjectBase columns with proper backDate handling. Finds the earliest safe timestamp for the backDate and wraps the UPDATE in a transaction so MariaDB records the change against the existing history row.
Source:

(constant) updatePerson

Updates a person's data in the database (partial update endpoint) This endpoint (POST /:UID) performs partial data updates by merging the request body with existing data. It only updates the Member table, not ObjectBase fields. Used by both person and extern endpoints via delegation. By default accepts both 'person' and 'extern' types. With query parameter `?strict`, only 'person' type is accepted.
Source:

(constant) updatePersonData

Updates person data in both ObjectBase and Member tables (full object update) This function is used during create/update operations (PUT /:group) where a complete object with all rendered fields is provided. It updates both database tables, handles event publishing, family address updates, and WebSocket notifications. Difference from updatePersonPartial: - Updates BOTH ObjectBase and Member tables (vs. Member only) - Expects a fully rendered object with Title, Display, SortBase, etc. (vs. partial data) - Used for PUT operations during create/update flows (vs. POST for partial updates) - Uses publishChangeEvent for group hierarchy (vs. direct publishEvent)
Source:

(constant) updatePersonIdentifyer

Update a person's UIDuser and rebuild identifyer link.
Source:

(constant) updatePersonIdentifyerController

Source:

(constant) updatePersonPartial

Updates person/extern data with partial merge (used by POST /:UID endpoint) This function performs partial data updates by merging the provided data with existing Member data. It only updates the Member table, not ObjectBase fields. Used by both person and extern POST endpoints for partial updates without changing group membership. Difference from updatePersonData: - Updates ONLY Member table (vs. both ObjectBase and Member) - Performs partial merge with existing data (vs. full object replacement) - Uses direct publishEvent (vs. publishChangeEvent through group hierarchy) - No group membership handling (vs. full create/update flow)
Source:

(constant) updatePersonStatus

Update person status in email
Source:

(constant) updateProject

Update project metadata (requires admin on the project).
Source:

(constant) updateProject

POST /project/project/:UID
Source:

(constant) updateQueueStatus

Broadcasts the current job-queue status to all clients of an organisation. This is an organisation-wide broadcast — every connected client whose `UIDroot` matches `root` receives the message, regardless of individual subscriptions. The status is also cached in `clientData.queueStatus` for reference. The frontend receives `{ root, queueStatus }` and calls any registered `setQueueStatus` callbacks across all active subscriptions.
Source:

(constant) updateShare

Update share metadata (requires admin on the project or `Visible.admin` on the share, i.e. the owner).
Source:

(constant) updateShare

POST /project/project/:projectUid/shares/:shareUid
Source:

(constant) updateTailnet

Source:

(constant) updateTailnet

POST /api/tailnets/:UID
Source:

(constant) updateTemplate

Notifies all clients of an organisation that their UI template has changed. This is an organisation-wide broadcast — every connected client whose `UIDroot` matches `root` receives `{ root, updateTemplate: }`. The frontend reacts by re-fetching the template configuration.
Source:

(constant) updateTemplateEvent

Like updateTemplate but for the event application specifically. Emits `{ root, updateTemplateEvent: }` to all matching clients.
Source:

(constant) updateUserSettings

Notifies all sockets of a specific user that their own settings have changed. Only targets sockets belonging to the given Keycloak userUID, so other users in the same organisation are not affected.
Source:

(constant) uploadAppIconController

POST /kpe20/orgaSettings/apps/:appId/icon Upload an icon image for a specific app to the public bucket. Stores the resulting public URL in Vault under apps[appId].icon.
Source:

(constant) uploadAvatarFiles

Upload avatar images (POST /avatar/:UID)
Source:

(constant) uploadBannerFiles

Upload banner images (POST /banner/:UID)
Source:

(constant) uploadEditorFiles

Upload editor files (POST /editor/:expire/:UID)
Source:

(constant) uploadImagePdfFiles

Upload image and PDF files (POST /imagePdf/:UID)
Source:

(constant) uploadLanguageFileController

Upload a language file. Handles POST /:api
Source:

(constant) uploadLanguageOrChangelog

Upload language or changelog files (POST /:type(language|changelog)/:api)
Source:

(constant) uploadPrivateFiles

Upload private files (POST /:UID)
Source:

(constant) uploadPrivateRailFiles

Upload private rail files (POST /rail/:UID)
Source:

(constant) uploadPublicFiles

Upload public files with expiration (POST /public/:expire/:UID)
Source:

(constant) uploadPublicRailFiles

Upload public rail files for apps (POST /rail/:app/)
Source:

(constant) upsertPortalPendingController

Source:

(constant) upsertRuntime

Topologie-Heartbeat in die Companion-Zeile (Member.Data) schreiben — nie in ObjectBase (kein History-Wachstum). Der Runner bleibt Topologie-Teil von members; Job-/Session-Runtime liegt beim Zusteller (ide-server).
Source:

(constant) upsertSearchIndex

Replace all SearchIndex entries for a given object + index type. Deletes existing rows then inserts the new values. Safe to call with an empty values array (just removes stale entries).
Source:

(constant) usertPortalPending

Create or refresh a portal pending link and token payload.
Source:

(constant) validateBodyUUID

Validator for request body UIDs Some endpoints receive UIDs in the request body
Source:
Example
api.put('/', validateBodyUUID(['UID', 'UIDparent'], false), controller.create);

(constant) validateDomainEntry

Prüft einen einzelnen Domain-Eintrag gegen die Regeln seiner Art. Gibt eine Meldung für **Menschen** zurück, keinen Code: sie landet direkt in der Fehlerliste der Oberfläche.
Source:

(constant) validateMultipleUIDs

Convenience middleware for validating multiple common UUID parameters Useful for endpoints that accept multiple UIDs
Source:
Example
api.put('/:member/:group/:function', validateMultipleUIDs, controller.create);

(constant) validateQueryUUID

Validator for query parameters (not route params) Some endpoints receive UIDs in query strings
Source:
Example
api.get('/search', validateQueryUUID(['user', 'loginUser']), controller.search);

(constant) validateRegisterInput

Validates input for register endpoint
Source:

(constant) validateSingleUID

Convenience middleware for validating a single UID parameter Most common use case for DELETE, GET, POST endpoints
Source:
Example
api.delete('/:UID', validateSingleUID, controller.delete);

(constant) validateUUID

Validates UUID parameters in the request
Source:
Examples
// Validate single parameter
api.delete('/:UID', validateUUID(['UID']), controller.delete);
// Validate multiple parameters
api.put('/:member/:group', validateUUID(['member', 'group']), controller.update);

(constant) validateUUIDParam

Express param middleware for automatic validation Apply this to automatically validate any route parameter
Source:
Example
// Automatically validate all :UID parameters in this router
api.param('UID', validateUUIDParam('UID'));

// Now all routes with :UID are automatically protected
api.delete('/:UID', controller.delete);
api.get('/:UID', controller.get);

(constant) validateUser

Validate user access for an organization and populate cache
Source:

(constant) validateUserForOrganization

Validate user access to organization with caching
Source:

(constant) visibilityFilter

Visibility filter function
Source:

(constant) visibilityList

Visibility list filter
Source:

(constant) writeEventLog

Persist an event to eventLog. When `connection` is provided (inside a transaction) the write joins the same transaction as the business change, so no permanent "data change without event" can occur. The primary key is (Timestamp, EventKey) at microsecond precision; a repeat publish within the same microsecond refreshes the payload instead of losing it.
Source:

(constant) wsFakeUser

Pushes a fake-login (impersonation) state update to all sockets of a user. When an admin impersonates another user the session's `fakeLogin` flag changes. This broadcasts `{ baseUser, user, fakeLogin }` to every socket belonging to that user so the frontend can update the displayed identity without a page reload.
Source:

Methods

accountKey()

Schluessel, an dem ein Konto wiedererkannt wird: die IBAN. `IBANshow` ist beim verschluesselten Konto maskiert (XXXXXX), taugt aber als Rueckfall, wenn gar keine IBAN vorliegt. Ein leerer Rueckgabewert heisst „kein Schluessel" — solche Konten werden nie zugeordnet, damit zwei leere Eintraege nicht verschmelzen. Entschluesselt wird nur eine KOPIE, ausschliesslich fuer den Schluessel: der Eintrag selbst bleibt in der Form, in der er vorliegt. Sonst wanderte die IBAN im Klartext in die Ablage (siehe `familyAccountsOf` und `adjustMemberData`).
Source:

(async) accountsReadOnly(req) → {Promise.<boolean>}

Checks if the current user has read-only access to group accounts. Returns true if accounts should be protected from writes for this user.
Parameters:
Name Type Description
req ExpressRequestAuthorized
Source:
Returns:
Type
Promise.<boolean>

(async) addAction(action)

Handles various actions related to adding objects to a tree structure, such as filters, memberships, visibility, and other hierarchical updates. This function processes different types of actions and performs corresponding database operations and updates.
Parameters:
Name Type Description
action treeAction The action object containing details about the operation to be performed.
Source:
Throws:
Throws an error if any database operation or action processing fails.
Type
Error

(async) addAction()

Source:

(async) adjustMemberData(member, object, organization, touchedopt) → {Promise.<(Object|undefined)>}

Adjusts member data with family-shared information (address, email, phone, accounts)
Parameters:
Name Type Attributes Description
member FamilyMemberObject The family member to update
object FamilyMemberObject The source object containing family data
organization string Organization UID for event publishing
touched Array.<string> <optional>
Shared fields the caller supplied. When set, those fields are reconciled against the source: shared entries the source no longer carries are REMOVED. When omitted, the sync stays purely additive (nothing is ever removed) — that keeps full-database callers harmless.
Source:
Returns:
Updated member data or undefined
Type
Promise.<(Object|undefined)>

(async) alterEnum(query, table, values)

Führt ein `ALTER TABLE … MODIFY COLUMN Type enum(…)` auf einer system-versioned Tabelle aus. Setzt und entfernt das Session-Flag selbst, damit kein Aufrufer es vergessen kann.
Parameters:
Name Type Description
query function
table string
values Array.<string>
Source:

app2serverURL(baseDir) → {object}

Combine OpenAPI documents by resolving $ref references
Parameters:
Name Type Description
baseDir string Base directory for resolving references
Source:
Returns:
- Combined OpenAPI document
Type
object

appBaseDomain() → {string}

Basis-Domain für interne Hosts, zur **Laufzeit** gelesen. Nicht als Modulkonstante: in den Dev-Umgebungen steht `APP_BASE_DOMAIN` auf `dev.commtool.org`, und ob die Variable beim Import schon gesetzt ist, hängt davon ab, wer die Datei zuerst lädt. Ein einmal eingefrorener Wert würde dort Hosts für die Produktions-Basis erzeugen — die Auflösung fände nichts.
Source:
Returns:
Type
string

appendMissing(current, wanted) → {Array.<string>|null}

Hängt fehlende Literale an ein `enum` an — in der Reihenfolge, in der sie übergeben werden. Vorhandene Werte behalten ihre Position, damit bestehende Zeilen ihren Index nicht verlieren.
Parameters:
Name Type Description
current Array.<string>
wanted Array.<string>
Source:
Returns:
neue Liste, oder `null` wenn nichts fehlt
Type
Array.<string> | null

appendOutOfHierarchyLevels()

Assigns extra levels for out-of-hierarchy nodes when explicitly requested.
Parameters:
Type Description
Source:

applyLifeCycle(bucket) → {Promise.<void>}

Apply the lifecycle rules and never let a rejection escape. A failing `setBucketLifecycle` must not hang startup: `initBucket` resolves only via `applyLifeCycle`, so an unhandled rejection there would leave the promise pending forever and `initS3` would silently stop (the outer try/catch cannot catch a hang). The bucket stays usable, only the automatic expiry of `public//...` files would not be in place - worth a loud log line.
Parameters:
Name Type Description
bucket string
Source:
Returns:
Type
Promise.<void>

asUuid(value) → {string}

UID als Schluessel — **ohne** `Buffer.equals`. Zwei Gruende, beide schon einmal teuer: 1. `listRebuildAccess` setzt `UID` aus seinem Parameter zusammen, nicht aus der Abfrage: dort steht mal ein Buffer (Aufrufer `UUID2hex`), mal ein String (Queue-Action). Ein `.equals` auf dem String wirft — und weil der Aufruf im `try` der Rebuild-Funktion steht, verschwaende der Wurf die **ganze** Meldung (genau der Fehler war schon da: der Personen-Rebuild meldete nichts, weil `Visible.UIDUser` fehlte). 2. `binary(16)` in MariaDB traegt die ersten acht Bytes eines `UUID-…` in geswappter Reihenfolge: `dacaa7a1-94b7-11f1-…` liegt als `11f194b7dacaa7a1…` in der Zeile. `toString('hex')` ergaebe also einen Hex-String, der **nicht** die UID ist — im Event-Key stuende eine UUID, die es nicht gibt, und die Projektion haengte ihre Grants an ein Phantom-Objekt. Deshalb `HEX2uuid` (dasselbe Paar wie in `sql-query`). Verglichen wird die kanonische Form `UUID-…`, nicht der Rohbuffer.
Parameters:
Name Type Description
value unknown
Source:
Returns:
`UUID-…`, oder der Rohwert, wenn er nicht deutbar ist
Type
string

assertNoInvariantRisk(source, decision)

Guards the one assumption the repair leans on: as soon as a link to an EXISTING target is removed, exactly one such link has to be kept. Without that the object would silently end up with zero `memberA` links.
Parameters:
Name Type Description
source any
decision any
Source:

(async) assertUsableProjectRunner(runnerUid, orgHex)

Validiert einen Projekt-Runner (metadata.runnerUid): muss ein `shared`-/ `team`-Runner derselben Orga sein (nicht `personal`, nicht `revoked`). Leerer Wert (null/'') ist erlaubt und entfernt die Einstellung.
Parameters:
Name Type Description
runnerUid unknown — Wire-UID („UUID-…") oder leer
orgHex string
Source:

(async) authorizeRef(req, ref) → {Promise.<{uid: string, name: string}>}

Split a credentialsRef ({UID}/{name}) and authorize: - user credential: only the owning user (or org admin) - org credential: only org admins
Parameters:
Name Type Description
req ExpressRequestAuthorized
ref string
Source:
Returns:
Type
Promise.<{uid: string, name: string}>

avatarUrlGen()

URL generator for avatar file uploads
Source:

bannerUrlGen()

URL generator for banner file uploads
Source:

bufferToEmbedding(buffer) → {Float32Array}

Convert Buffer from database to Float32Array
Parameters:
Name Type Description
buffer Buffer Binary buffer from DB
Source:
Returns:
- Embedding vector
Type
Float32Array

bufferToUUID(buf) → {string}

MariaDB binary(16) mixed-endian buffer → standard uuid string.
Parameters:
Name Type Description
buf Buffer
Source:
Returns:
Type
string

buildCompactNodeLabel(node, fallback) → {string}

Builds a compact node label for tree rendering.
Parameters:
Name Type Description
node any
fallback string
Source:
Returns:
Type
string

buildCursor(seq) → {string}

Build a cursor from a numeric seq.
Parameters:
Name Type Description
seq number
Source:
Returns:
Type
string

buildDataFields(req, groupBannerTableopt) → {string}

Build extra SELECT column fragment from `Data` / `ExtraData` / `dataFilter` / `groupBanner` query parameters.
Parameters:
Name Type Attributes Default Description
req ExpressRequestAuthorized
groupBannerTable string <optional>
'pmember' Table alias that holds banner data
Source:
Returns:
Type
string

buildNodeAdjacency()

Builds adjacency maps for fast traversal. - memberA is directed: parent -> child - memberS is undirected: sibling <-> sibling
Parameters:
Type Description
Source:

(async) buildSnapshot(uidHex, orgHex, mysqlTime) → {Promise.<Object>}

Build the snapshot for a resolved UTC MySQL timestamp.
Parameters:
Name Type Description
uidHex string
orgHex string
mysqlTime string 'YYYY-MM-DD HH:MM:SS.ffffff' UTC
Source:
Returns:
Type
Promise.<Object>

calculateContentHash(text) → {Buffer}

Calculate content hash for change detection
Parameters:
Name Type Description
text string Text to hash
Source:
Returns:
- SHA256 hash
Type
Buffer

changelogUrlGen()

URL generator for changelog file uploads
Source:

(async) checkEntries(ObjectUID, UIDOrga) → {Promise.<void>}

Checks all entries for the given objects against their filters and performs necessary cleanup. This function processes multiple objects, retrieves their filters, and checks each entry to ensure they still match the current filter criteria, removing entries that no longer qualify.
Parameters:
Name Type Description
ObjectUID Buffer | Array.<Buffer> Single object UID or array of object UIDs to check
UIDOrga string The organization UUID for multi-tenant scoping (must be string)
Source:
Throws:
Will log an error if any operation fails during execution.
Returns:
Type
Promise.<void>

(async) checkEntry(entry, UIDOrga)

Checks a single entry against its filters and performs necessary add/remove operations. This function evaluates whether an entry should be included or excluded from a list based on the current filter state and publishes appropriate events for membership changes.
Parameters:
Name Type Description
entry any Entry object with filter information and membership data
UIDOrga string The unique identifier of the organization (required)
Source:
Throws:
Will log an error if any operation fails during execution.

(async) checkPersonListMember(UID, UIDOrga) → {Promise.<void>}

Asynchronously checks if a person is a member of specific lists/dynamic lists dlist) and performs related operations. This is clled, when an objet has been updated or created, to check if any dynamic list has to be updated This function retrieves all groups (sources) that the object identified by the given UID is a member of, matches the object against those lists, by checking all object filters attached to the sources/groups, if they pass the filters and performs necessary updates to the entries of the dynamic lists attached to these filters In a second step it checks, if therre are entries which do not match the filters anymore and removes them from the dlist
Parameters:
Name Type Description
UID string | Buffer The unique identifier of the object to check membership for.
UIDOrga string The unique identifier of the organization.
Source:
Throws:
Will log an error if any operation fails during execution.
Returns:
Resolves when the operations are completed.
Type
Promise.<void>

(async) cleanEventLog(timestampopt) → {Promise.<void>}

- Deletes events from the `eventLog` table where the `Timestamp` is older than the specified timestamp. - If `timestamp` is `null`, the default value is calculated as the UNIX timestamp of the first day of the previous month. - After deletion, the `eventLog` table is optimized to reclaim storage and improve performance. - The database transaction is executed with a query timeout of 100 seconds.
Parameters:
Name Type Attributes Default Description
timestamp number | null <optional>
null The UNIX timestamp (in seconds) to use as the cutoff for deletion. Defaults to the first day of the previous month if not provided.
Source:
Throws:
Logs any errors encountered during the operation.
Type
Error
Returns:
Resolves when the cleanup operation is complete.
Type
Promise.<void>

(async) clearMirroredFilters()

Alle gespiegelten Filter-Links eines Shares entfernen (kein Projekt mehr).
Source:

clearOrgReleaseOverride(appKey, orgId) → {Promise.<boolean>}

Nimmt eine Organisation aus dem Canary. Ab hier folgt sie wieder dem Zeiger — das ist der Rollback, und er braucht keinen Rückbau eines Deployments.
Parameters:
Name Type Description
appKey string
orgId string
Source:
Returns:
true, wenn wirklich ein Eintrag entfernt wurde
Type
Promise.<boolean>

compareDOWN(filterA, filterB) → {number}

Comparator function for sorting filters in descending order during filter removal. Sorts by filter type priority: include > exclude > intersect (reverse order)
Parameters:
Name Type Description
filterA Object First filter object with Type property
filterB Object Second filter object with Type property
Source:
Returns:
-1 if filterA < filterB, 0 if equal, 1 if filterA > filterB
Type
number

compareUP(filterA, filterB) → {number}

Comparator function for sorting filters in ascending order during filter rebuilding. Sorts by filter type priority: include > exclude > intersect
Parameters:
Name Type Description
filterA Object First filter object with Type property
filterB Object Second filter object with Type property
Source:
Returns:
-1 if filterA < filterB, 0 if equal, 1 if filterA > filterB
Type
number

(async) compressTable(tableName, entityKeys, chunkSize, dryRun, connection, onProgress) → {Promise.<{squeezed: number, inserted: number, originalTotal: number, newTotal: number}>}

Compress a single system-versioned table.
Parameters:
Name Type Description
tableName string
entityKeys Array.<string>
chunkSize number
dryRun boolean
connection
onProgress
Source:
Returns:
Type
Promise.<{squeezed: number, inserted: number, originalTotal: number, newTotal: number}>

computeNodeLevels()

Computes rank levels for nodes by traversing memberS bands and memberA jumps.
Parameters:
Type Description
Source:

configLifeCycle(bucket) → {Promise.<void>}

Lifecycle rules for a bucket - the ONLY place these rules are maintained. `setBucketLifecycle` REPLACES the complete lifecycle configuration of the bucket: rules added manually in the Backblaze/MinIO console (or by another service) are gone with the next start of this backend. So change rules here, never in the console. Scope: only `public//...` keys are covered, matching `publicUrlGen` (`public///.`). `public/0` deliberately has NO rule (= never expires). Object artefacts (`/...`) and app assets (`locations/...`, `events/...`, `admin/...`, `config/...`, `db/...`) are intentionally NOT covered and therefore kept forever.
Parameters:
Name Type Description
bucket string
Source:
Returns:
Type
Promise.<void>

(async) connectRedis() → {Promise.<boolean>}

Einmaliger Verbindungsaufbau. Nur über initializeRedis aufrufen.
Source:
Returns:
true bei Erfolg, false solange die Secrets fehlen
Type
Promise.<boolean>

cosineSimilarity(a, b) → {number}

Calculate cosine similarity between two embeddings
Parameters:
Name Type Description
a Float32Array First embedding
b Float32Array Second embedding
Source:
Returns:
- Similarity score (0-1)
Type
number

createNodeHierarchyLookup(nodeMap)

Creates a hierarchy lookup function for nodes.
Parameters:
Name Type Description
nodeMap Map.<string, any>
Source:
Returns:

credentialsRootFor()

KV2 credentials root for one organisation.
Source:

decrypt(encryptedData, passphrase) → {string}

Decrypts an AES-128 encrypted Base64 string using a passphrase.
Parameters:
Name Type Description
encryptedData string The encrypted string (Salt and encrypted text in Base64, separated by colons). Supports both old format (salt:iv:encrypted) and new format (salt:encrypted).
passphrase string The passphrase used to derive the decryption key and IV.
Source:
Returns:
- The decrypted Base64 string.
Type
string

(async) deleteAppByUid(uid, appIdopt)

Löscht eine App samt ihrer Links. `appDomain` wird beim Löschen mitgenommen, obwohl der Bestand seit der Umstellung keine solchen Links mehr anlegt: ein früherer Import hat sie erzeugt, und ein Löschpfad, der sie stehen ließe, hinterließe Karteileichen.
Parameters:
Name Type Attributes Description
uid string
appId string <optional>
nur für den Log
Source:

(async) deleteDir()

Helper function to delete directories recursively
Source:

(async) deleteFunctionTemplate(req, res) → {Promise.<void>}

Deletes a function template if there are no jobs linked to it. This function checks if any jobs are associated with the specified function template. If jobs are found, deletion is denied and a message is returned listing the members with jobs. If no jobs are linked, the function template and all related achievement links are deleted. The template update function is called after successful deletion.
Parameters:
Name Type Description
req Object Express request object, expects `params.UID` for the template UID and `session.root` for the root user UID.
res Object Express response object used to send JSON responses.
Source:
Returns:
Sends a JSON response indicating success or failure.
Type
Promise.<void>

(async) deleteVaultSecret(path) → {Promise.<boolean>}

Permanently delete a KV2 secret (all versions) via the metadata API. `@commtool/vault-secrets` has no delete function, so we issue the DELETE directly. The KV2 metadata endpoint (`{mount}/metadata/{path}`) removes the secret including version history; the `data` endpoint alone would only soft- delete the latest version.
Parameters:
Name Type Description
path string KV2 data path, e.g. `orgas/data/{orgId}/credentials/{ref}`
Source:
Returns:
true when the secret was deleted
Type
Promise.<boolean>

deliverToClient(socketID, clientData, event, payload)

Stellt eine Nachricht zu — oder puffert sie, wenn der Client nicht empfangsbereit ist. Nicht empfangsbereit heisst: - getrennt (`connected === false`), oder - gerade neu verbunden, aber noch nicht neu registriert (`resynced === false`). Der zweite Fall ist fuer die Reihenfolge noetig: ohne ihn koennte eine Nachricht, die unmittelbar nach dem Verbinden eintrifft, VOR den nachgelieferten aelteren Nachrichten ankommen. Betroffen ist nur das kurze Fenster bis `syncSubscriptions()` im Client gelaufen ist. Aufgerufen wird der Helfer nur von den Pfaden, die der Client auch wirklich konsumiert (`addUpdateEntry`, `addUpdateList`). Die uebrigen Broadcasts (Queue-Status, Template, Config, …) verhalten sich unveraendert.
Parameters:
Name Type Description
socketID string
clientData object
event string
payload object
Source:

deriveKeyAndIv(passphrase) → {Object}

Derives a key and IV from a passphrase.
Parameters:
Name Type Description
passphrase string The passphrase to derive key and IV from.
Source:
Returns:
- The derived key, IV, and salt in base64 format.
Type
Object

detectOutOfHierarchyNodes()

Detects nodes that violate the expected memberA hierarchy step (+1).
Parameters:
Type Description
Source:

detectVisibleNodes()

Detects visible nodes from computed levels and hierarchy flags.
Parameters:
Type Description
Source:

(async) duplicateGitUrlWarnings(rootUid, gitUrl, orgUuid) → {Promise.<Array.<{code: string, share_uid: string, repositoryKey: (string|null)}>>}

Nicht blockierender Hinweis: ein **anderer** Root derselben Organisation traegt dieselbe Git-URL. Das ist ein Hinweis fuer die Oberflaeche („meintest du ‚bestehendes hinzufuegen'?") — **keine** Regel: dieselbe URL kann legitim zweimal existieren (Fork, zweiter Klon), und die Identitaet ist die UID, nie die URL.
Parameters:
Name Type Description
rootUid string | Buffer
gitUrl unknown
orgUuid string
Source:
Returns:
Type
Promise.<Array.<{code: string, share_uid: string, repositoryKey: (string|null)}>>

embeddingToBuffer(embedding) → {Buffer}

Convert Float32Array to Buffer for database storage
Parameters:
Name Type Description
embedding Float32Array Embedding vector
Source:
Returns:
- Binary buffer
Type
Buffer

encodeKrokiGraph(diagramSource) → {string}

Encodes Graphviz text for Kroki using deflate + base64url.
Parameters:
Name Type Description
diagramSource string
Source:
Returns:
Type
string

encrypt(base64String, passphrase) → {string}

Encrypts a Base64-encoded string with AES-128 using a passphrase.
Parameters:
Name Type Description
base64String string The Base64-encoded string to encrypt.
passphrase string The passphrase used to derive the encryption key and IV.
Source:
Returns:
- The encrypted string in Base64 format.
Type
string

(async) ensureVersionTable()

Ensures the dbVersion tracking table exists. Safe to call on both fresh and existing databases.
Source:

escapeHtml(value)

Parameters:
Name Type Description
value string
Source:

(async) exclude(entry, UIDOrga)

Creates an exclusion link for an entry and publishes remove events to notify about the exclusion. This function is called when an entry should be excluded from a list due to filter matching.
Parameters:
Name Type Description
entry any Entry object containing UIDEntry, UIDList, UIDBelongsTo
UIDOrga string The unique identifier of the organization (required)
Source:
Throws:
Will log an error if any operation fails during execution.

expandMemberSBand(roots)

Expands one memberS-connected band and computes local ranks from roots.
Parameters:
Name Type Description
roots Map.<string, number>
Source:

extractAchievements(filter) → {Array.<string>}

Extracts all achievement qualifiers (as strings) from a potentially nested filter object or array. The function traverses the filter structure recursively, collecting all string values found at any depth. The filter can be a string, an object with a single key whose value is another filter or array of filters, or an array of such filters.
Parameters:
Name Type Description
filter Object | Array | string The filter structure to extract achievement qualifiers from.
Source:
Returns:
An array of extracted achievement qualifier strings.
Type
Array.<string>

fail(req, res, status, message) → {void}

Parameters:
Name Type Description
req ExpressRequestAuthorized
res ExpressResponse
status number
message string
Source:
Returns:
Type
void

familyAccountsOf(object) → {Array.<Object>}

Die geteilten Konten der Quelle — in der Form, in der sie vorliegen. Bewusst NICHT entschluesselt: was hier durchgereicht wird, wird beim Geschwister gespeichert. Ein verschluesseltes Konto bleibt deshalb verschluesselt. Fuer den Abgleich braucht es die IBAN nur als Schluessel, und den bildet `accountKey`. Bei person/extern traegt `accounts` auch die eigenen Konten; geteilt sind nur family/familyFees. Bei einem Familienobjekt ist der Satz selbst der geteilte.
Parameters:
Name Type Description
object FamilyMemberObject
Source:
Returns:
Type
Array.<Object>

familyEntriesOf(object, field) → {Array.<Object>}

Die geteilten Eintraege EINES Feldes in der Quelle. Bei person/extern traegt das Feld auch die eigenen Eintraege des Mitglieds — hier zaehlen nur die geteilten. Bei einer Familie ist das Feld (sofern gesetzt) selbst der geteilte Satz; historisch als Einzelobjekt oder Skalar.
Parameters:
Name Type Description
object FamilyMemberObject
field string
Source:
Returns:
Type
Array.<Object>
Every active `memberA` link whose source holds more than one of them, plus every link whose target no longer exists (`TargetExists = 0` → dangling). ## Why this is written in two phases The obvious single-pass form ```sql LEFT JOIN ObjectBase t ON (t.UID = l.UIDTarget AND t.ValidUntil > NOW()) WHERE … AND (dup OR t.UID IS NULL) ``` does not come back on production-sized data: `Links` holds ~470k active links, and a `LEFT JOIN` is evaluated for every one of them before the `WHERE` narrows anything, so `ObjectBase` is probed ~470k times. The candidate set is only ~2k rows, so the candidate links are selected FIRST (the derived table below) and enriched afterwards — that drops the runtime from minutes to a few hundred milliseconds. The source is LEFT JOINed: the links of a deleted object are still in the table and must not silently disappear from the report.
Source:
Returns:
Type
Promise.<Array.<any>>

fetchPersonRows(rootHex) → {Promise.<Array.<any>>}

Every person/extern of the organisation with both level representations and one row per `memberA` group link (LEFT JOIN, so persons without a group link are kept).
Parameters:
Name Type Description
rootHex Buffer binary UID of the organisation root
Source:
Returns:
Type
Promise.<Array.<any>>

(async) fetchUserFromMembersAPI(userUID, orgaUID, authToken) → {Object}

Fetch user data from members API to populate cache
Parameters:
Name Type Description
userUID string User UUID
orgaUID string Organization UUID
authToken string Auth token for API call
Source:
Returns:
- User data or null
Type
Object

filterImage()

Helper function to filter image file types
Source:

filterImagePdf()

Helper function to filter image and PDF file types
Source:

filterJSON()

Helper function to filter JSON file types
Source:

filterVisibleEdges()

Filters edges to only those that should be rendered.
Parameters:
Type Description
Source:

findSimilarEntities(referenceUID, options) → {Promise.<Array>}

Find entities similar to a reference entity
Parameters:
Name Type Description
referenceUID Buffer | string UID of the reference entity (Buffer or hex string)
options Object Search options (same as searchSimilarEntities)
Source:
Returns:
- Array of similar entities
Type
Promise.<Array>

flushPendingMessages()

Leert den Puffer in Einfuegereihenfolge (FIFO).
Source:

generateEmbedding(text, options) → {Promise.<Float32Array>}

Generate single embedding from text
Parameters:
Name Type Description
text string Text to embed
options Object Generation options (see generateEmbeddings)
Source:
Returns:
- Embedding vector
Type
Promise.<Float32Array>

generateEmbeddings(texts, options) → {Promise.<Array.<Float32Array>>}

Generate embeddings from text using configured backend
Parameters:
Name Type Description
texts string | Array.<string> Text(s) to embed
options Object Generation options
Properties
Name Type Attributes Default Description
sanitize boolean <optional>
true Sanitize sensitive PII before embedding
sanitizeOptions Object <optional>
Options passed to sanitizeTextForEmbedding
Source:
Returns:
- Array of embedding vectors
Type
Promise.<Array.<Float32Array>>

(async) generateEmbeddingsCohere()

Generate embeddings using Cohere
Source:

(async) generateEmbeddingsOllama()

Generate embeddings using Ollama
Source:

(async) generateEmbeddingsOpenAI()

Generate embeddings using OpenAI
Source:

(async) generateEmbeddingsTEI()

Generate embeddings using TEI (HuggingFace Text Embeddings Inference)
Source:

(async) getAchievement(req, res) → {Promise.<void>}

Retrieves an achievement by UID, checking user permissions. If timestamp is provided, retrieves the achievement as it was at that time. Returns achievement details including template data and authorization status.
Parameters:
Name Type Description
req Object Express request object
Properties
Name Type Description
params Object Request parameters
Properties
Name Type Description
UID string UID of the achievement to retrieve
query Object Query parameters
Properties
Name Type Attributes Description
timestamp string <optional>
Optional timestamp for point-in-time queries
session Object Session information
Properties
Name Type Description
user string Current user's UID
res Object Express response object
Source:
Returns:
- Sends JSON response with achievement data or error message
Type
Promise.<void>

getAllCorsOrigins() → {Promise.<Array.<string>>}

CORS-Origins: **alles außer** den internen Domains. Die Negation ist Absicht. Ein `=== 'external'` stand hier einmal, und weil im Bestand `verified` lag (`{"kpe.de":"verified"}`), traf es **nichts** — die Liste war leer, obwohl vier Kunden-Domains existierten. Mit getrenntem `type`/`status` wäre `=== 'external'` zwar wieder richtig, aber die Negation bleibt die robustere Aussage: eine neue Domänenart soll nicht stillschweigend aus CORS herausfallen. Die App-Hosts stehen bewusst **nicht** darin: sie liegen unterhalb einer dieser Domains (`admin.app.kpe.de` ⊂ `kpe.de`), und `createCorsOriginChecker` prüft mit Punktgrenze auf die Basis-Domain. Sie einzeln aufzuzählen wäre doppelt gemoppelt — und bei jeder neuen App zu ändern.
Source:
Returns:
Type
Promise.<Array.<string>>

getAllDomainMappings() → {Promise.<Array.<{domain: string, org: string, orgId: string, app: string, type: string}>>}

Die Routing-Tabelle: für jede App der Host, unter dem sie läuft. Form wie bei `shared-auth` (`loadOrganizationDomains`): `domain` ist der **fertige Host**, nicht der Rohtwert aus dem App-Eintrag. Genau daran hängt die Erkennung „welche Organisation bedient dieser Host" — würde hier `sjm` statt `sjm.admin.app.commtool.org` stehen, fände die Erkennung nichts.
Source:
Returns:
Type
Promise.<Array.<{domain: string, org: string, orgId: string, app: string, type: string}>>

(async) getAllFilters(UID) → {Promise.<Array>}

Retrieves all filters (include, exclude, intersect) associated with a specific dynamic list.
Parameters:
Name Type Description
UID string The unique identifier of the dynamic list
Source:
Returns:
Array of filter objects with UID, Type, Data, Title, Display, UIDBelongsTo, and SourceType
Type
Promise.<Array>

getAllOrgDomains() → {Promise.<Record.<string, Record.<string, {type: string, status: string}>>>}

Alle Domains aller Organisationen (für den Konflikt-Check).
Source:
Returns:
Type
Promise.<Record.<string, Record.<string, {type: string, status: string}>>>

getAllOrgDomains() → {Promise.<Record.<string, Record.<string, string>>>}

Load domain maps for every organisation from Vault. Wird vom `registryService` **nur** im Rückfall gebraucht: bei `REGISTRY_READ_MODE=vault` und im `dual`-Modus, wenn die Datenbank leer ist. Ohne diese Funktion liefe der Rückfall ins Leere (`undefined` aufrufen) — und zwar genau dann, wenn man ihn braucht, nämlich beim Zurückschalten.
Source:
Returns:
Type
Promise.<Record.<string, Record.<string, string>>>

getAppCatalog() → {Promise.<Record.<string, object>>}

Der App-Katalog: die Vorlage, aus der eine neue Organisation ihre Apps bekommt. Bewusst ein Durchgriff auf Vault und **keine** DB-Variante. Der Katalog hängt an keinem Mandanten (`orgas/data/default/apps`), und der Import lässt den `default`-Ordner ausdrücklich aus, damit kein Objekt ohne `UIDBelongsTo` entsteht. Ein `readsDb()`-Zweig würde hier nur so tun, als gäbe es Zeilen.
Source:
Returns:
Type
Promise.<Record.<string, object>>

getAppCatalog() → {Promise.<Record.<string, AppEntry>>}

Der App-Katalog — welche Apps es überhaupt gibt. Er liegt unter einem **reservierten** Pfad, `orgas/data/default/apps`, und ist keine Organisation: keine UID, keine Domains, keine Rollen-Sichtbarkeit — nur die Metadaten, die eine neue Organisation anbieten können soll (`title`, `description`, `icon`, `category`, `roles`). Eine neue Organisation kopiert daraus **einmal**; einen Overlay gibt es bewusst nicht. Ein Vorlagenstand, der sich unter den Mandanten weiterbewegt, macht die Frage „woher stammt dieser Eintrag" unbeantwortbar — und ein Katalog, der beim Lesen gemischt wird, sähe für zwei Aufrufer verschieden aus, je nachdem, wer ihn zuerst gelesen hat. Es gibt hier keine DB-Variante: der Import lässt `default` ausdrücklich aus (`migrateVaultToRegistry.js` überspringt Nicht-UUID-Ordner), damit kein verwaister Mandant ohne `UIDBelongsTo` entsteht.
Source:
Returns:
Type
Promise.<Record.<string, AppEntry>>

getAppManifest(orgId, appId) → {Promise.<(object|null)>}

PWA-Manifest einer App (Branding aus dem Registry statt Vault-PWA-Cache).
Parameters:
Name Type Description
orgId string
appId string
Source:
Returns:
Type
Promise.<(object|null)>

getApps(orgId) → {Promise.<Record.<string, AppEntry>>}

Load the app registry for one organisation.
Parameters:
Name Type Description
orgId string
Source:
Returns:
Type
Promise.<Record.<string, AppEntry>>

getClient()

Liefert den geteilten Redis-Client. Bewusst lazy: `getRedisClient()` wirft, falls `configureAuth()` noch nicht gelaufen ist — das darf beim Modul-Import nicht passieren, sondern erst beim tatsächlichen Request (nach Serverstart).
Source:
Returns:

getDomains(orgId) → {Promise.<Record.<string, string>>}

Load domain settings for one organisation. This is the **Vault side** of the registry: `registryService` uses it as its fallback while `REGISTRY_READ_MODE` is not yet `db`. The validation rules and the cross-organisation conflict check used to live here as well — they moved to `registryTypes.js` / `registryService.js`, because checking a value is not the same job as fetching it: they must run against the store that is being written to, not against the one this module happens to read.
Parameters:
Name Type Description
orgId string
Source:
Returns:
Type
Promise.<Record.<string, string>>

getEmbeddingServerInfo() → {Promise.<Object>}

Get embedding server info
Source:
Returns:
Type
Promise.<Object>

(async) getEnumValues(query, table, column) → {Promise.<(Array.<string>|null)>}

Liest die Enum-Literale einer Spalte aus `information_schema`.
Parameters:
Name Type Description
query function
table string
column string
Source:
Returns:
Literale, oder `null` wenn keine enum-Spalte
Type
Promise.<(Array.<string>|null)>

getFinancialMasterFlag(functionData, jobDataopt) → {Object}

Extracts the financialMaster flag from a job or function template. Priority: job-level `accounting.financialMaster` > function template `financialMaster`
Parameters:
Name Type Attributes Description
functionData Object Data from the function template (ObjectBase.Data)
jobData Object <optional>
Data from the job (ObjectBase.Data), may contain accounting block
Source:
Returns:
Type
Object

(async) getFunctionTemplates(req, res) → {Promise.<void>}

Retrieves all function template names and UIDs for the organization.
Parameters:
Name Type Description
req Object Express request object, expects `session.root` for the root user UID.
res Object Express response object used to send JSON responses.
Source:
Returns:
Sends a JSON response with the function templates list.
Type
Promise.<void>

getHash(row, entityKeySet, allColumns) → {string}

Compute a hash of the non-key, non-temporal columns for a row. Two rows with the same hash can be collapsed (the earlier history row removed).
Parameters:
Name Type Description
row Object
entityKeySet Set.<string>
allColumns Array.<{Field: string, isVirtual: boolean}>
Source:
Returns:
Type
string

getHierarchyBorderColor(hierarchie, hierarchyColors) → {string}

Returns border color for a group hierarchy from config/palette.
Parameters:
Name Type Description
hierarchie number | string | null | undefined
hierarchyColors Array.<any> | Object | null
Source:
Returns:
Type
string

getHierarchyColorConfig(config) → {Array.<any>|Object|null}

Resolves hierarchy colors from merged config.
Parameters:
Name Type Description
config any
Source:
Returns:
Type
Array.<any> | Object | null

(async) getJobsByFunctionTemplate(req, res) → {Promise.<void>}

Retrieves jobs associated with a specific function template.
Parameters:
Name Type Description
req Object Express request object, expects `params.UID` for the template UID and optional query parameters.
res Object Express response object used to send JSON responses.
Source:
Returns:
Sends a JSON response with the jobs data.
Type
Promise.<void>

getMailSettings(orgId) → {Promise.<(object|null)>}

Load mail/SMTP settings for one organisation. The password is masked before being returned.
Parameters:
Name Type Description
orgId string
Source:
Returns:
Type
Promise.<(object|null)>

getMemberAStep(parentHex, childHex) → {number|null}

Returns memberA rank increment from parent to child. Invalid hierarchy transitions return null and are omitted.
Parameters:
Name Type Description
parentHex string
childHex string
Source:
Returns:
Type
number | null

getNonVirtualColumns(columns) → {Array.<{Field: string, isVirtual: boolean}>}

Determine which columns are VIRTUAL / GENERATED (excluded from INSERT).
Parameters:
Name Type Description
columns Array.<{Field: string, Extra: string}> Result of SHOW COLUMNS
Source:
Returns:
Type
Array.<{Field: string, isVirtual: boolean}>

(async) getObjectFilters(ObjectUID) → {Promise.<(Array.<any>|undefined)>}

Retrieves all filters and related data for objects that need to be checked for dynamic list membership. This function queries the database to get filter information for objects and their associated lists.
Parameters:
Name Type Description
ObjectUID Buffer | Array.<Buffer> Single object UID or array of object UIDs to get filters for
Source:
Returns:
Array of filter objects with complete filter and object information
Type
Promise.<(Array.<any>|undefined)>

getOrgApp(orgId, appId) → {Promise.<(object|null)>}

Eine einzelne App einer Organisation.
Parameters:
Name Type Description
orgId string
appId string
Source:
Returns:
Type
Promise.<(object|null)>

getOrgApps(orgId) → {Promise.<Record.<string, object>>}

Alle Apps einer Organisation.
Parameters:
Name Type Description
orgId string UID in `UUID-`-Form
Source:
Returns:
`{ [appId]: AppEntry }`
Type
Promise.<Record.<string, object>>

getOrgDomains(orgId) → {Promise.<Record.<string, {type: string, status: string}>>}

Alle Domains einer Organisation. Rückgabe ist `{ [domain]: { type, status } }` — **eine** Form für Aufrufer und Oberfläche. Der Altbestand (in Vault wie in der Datenbank) trägt statt dessen eine Zeichenkette wie `"verified"`; übersetzt wird hier einmal, nicht bei jedem Konsumenten.
Parameters:
Name Type Description
orgId string
Source:
Returns:
Type
Promise.<Record.<string, {type: string, status: string}>>

(async) getOrgSection(orgId, section) → {Promise.<(object|null)>}

Load a named section for one organisation from Vault. Returns `null` on missing key or error.
Parameters:
Name Type Description
orgId string
section string e.g. 'domains', 'apps', 'mail'
Source:
Returns:
Type
Promise.<(object|null)>

getRequiredDbRoles() → {Array.<string>}

Get the required database roles based on NODE_ENV Production: db-user, db-admin Development: db-dev, db-admin Demonstration: db-demo, db-admin
Source:
Returns:
Array of valid roles for current environment
Type
Array.<string>

getStageColorConfig(config) → {Array.<any>|Object|null}

Resolves stage colors from merged config.
Parameters:
Name Type Description
config any
Source:
Returns:
Type
Array.<any> | Object | null

getStageDotColor(stage, stageColors) → {string}

Parameters:
Name Type Description
stage number | string | null | undefined
stageColors Array.<any> | Object | null
Source:
Returns:
Type
string

groupBySource(rows) → {Map.<string, any>}

Groups the flat link rows per source object. Keyed by the UUID string — two `Buffer`s with equal content would be different Map keys and split one object with several links into several single-link objects.
Parameters:
Name Type Description
rows Array.<any>
Source:
Returns:
Type
Map.<string, any>

(async) groupEntriesFilter(myObjectFilters) → {Promise.<(Record.<string, any>|undefined)>}

Groups filter data by entry UID and organizes filters into include/exclude/intersect categories. This function processes raw filter data from the database and structures it for efficient filtering operations, creating an object keyed by entry UIDs with complete filter information.
Parameters:
Name Type Description
myObjectFilters Array.<any> Array of raw filter objects from the database query
Source:
Throws:
Will log an error if any operation fails during execution.
Returns:
Object keyed by entry UIDs containing organized filter data
Type
Promise.<(Record.<string, any>|undefined)>

groupNames(session) → {Array.<string>}

Keycloak-Gruppen normalisieren: liefert `/employees` und `employees` identisch. (Keycloak stellt Group-Pfade je nach Mapper mit oder ohne führenden Slash aus.)
Parameters:
Name Type Description
session Object
Source:
Returns:
Type
Array.<string>
Manages the sister-group link for a group. If belongsTo changes, removes old memberS link, inserts new one, and syncs members.
Parameters:
Name Type Description
req ExpressRequestAuthorized
UID Buffer Group UID (hex Buffer)
Source:
Returns:
The new sister-group object, or null if unchanged/removed
Type
Promise.<(object|null)>

(async) hasColumn()

`Member.credential_id` (20260926) war typ-gebunden benannt: eine Spalte, die genau ein Objekttyp mit wenigen Zeilen benutzt. Diese Migration ersetzt sie durch einen **generischen Lookup-Slot**. ## Konvention (neu, hier festgehalten) `Member.lookup_key` ist der **eine opake externe Schlüssel** eines Objekts: ein Wert, der von außen kommt (Client, Registrierung, Import) und über den das Objekt gesucht wird — NICHT die Objekt-UID. - **Ein Slot pro Objekt, global eindeutig.** Die Bedeutung ergibt sich aus `ObjectBase.Type`, nicht aus dem Spaltennamen. Kein Typ-spezifisches Feld, keine zweite Spalte für den nächsten Typ. - **Die Werte sind präfixiert** (`rc_…` für Runner-Credentials). Deshalb genügt ein globaler UNIQUE statt `(Type, key)` — Letzteres bräuchte `Type` in `Member` (Denormalisierung) und bringt für einen Zufallswert nichts. - **Kein anderer Zweck.** `Member.Data` trägt den heißen Zustand (Heartbeat, Capacity); `lookup_key` trägt nur den Suchschlüssel. Beides zu vermischen macht den Unique-Konflikt zur Zufallsfehlerquelle an unerwarteten Stellen. Die Rolle ist damit `SortName`/`FullTextIndex`/`PhonetikIndex`/`Geo` gleichgestellt: eine ausgezogene Spalte, die Lookup oder Sort dient — die Member-Konvention (080-Workspaces/040-Ist-Zustand: „heißer Zustand im Data-JSON, ausgezogene Spalten nur für Lookup/Sort"). ## Ablauf 1. `lookup_key` an `Member` anlegen (varchar(128): ein generischer Slot sollte nicht auf die Länge seines ersten Nutzers dimensioniert sein). 2. UNIQUE `member_lookup_key_uq` anlegen. 3. Bestehende `credential_id`-Werte übernehmen, ihren Index und die Spalte entfernen. Idempotent: eine frische DB (initTables.sql kennt bereits `lookup_key`, kein `credential_id`) überspringt alles; eine laufende DB landet im selben Zustand. Hinweis: `20260926` legt `credential_id` weiterhin an — auf einem frischen Boot entsteht sie leer und wird hier wieder entfernt, weil die Migration bereits appliziert ist und nicht mehr geändert werden darf.
Source:

(async) hasColumn()

`RunnerData` war eine eigene Companion-Tabelle für den heißen Runner-Zustand (20260907-runner-companion) — dabei ist `Member` im Schema längst die **generische Companion-Tabelle** nach dem Member-Muster: gleiche UID wie das `ObjectBase`-Objekt, nicht system-versioniert, `Data`-JSON trägt den heißen Zustand, nur der gesuchte Lookup liegt als Spalte daneben. Gruppen, Events, Locations, Familien und E-Mails liegen dort schon — Runner brauchen keine zweite Tabelle. Diese Migration zieht den Runner-Zustand nach `Member`: - `credential_id` (UNIQUE) → neue Lookup-Spalte an `Member` (Runner-Auth; inverser Lookup „Credential-ID → Runner") - `public_key` → entfällt als Spalte. Der Key steht bereits in `ObjectBase.Data.publicKey` (von `createRunner` gesetzt) und ist damit die eine Quelle. Für Bestands-Runner, die vor 20260907 entstanden sind, wird er hier einmalig nachgezogen — sonst könnten sie sich nach dem Drop nicht mehr authentifizieren. - `Data` (heartbeat/capacity/lastSeenAt) → `Member.Data` des Runner-Objekts Danach wird `RunnerData` gedroppt. Idempotent: ein frischer Boot (Member hat die Spalte schon aus `initTables.sql`, `RunnerData` existiert nicht) und eine laufende dev-DB (Spalte fehlt, `RunnerData` ist da) landen im selben Zustand. Hinweis: `20260907-runner-companion` legt `RunnerData` weiterhin an — auf einem frischen Boot entsteht sie leer und wird hier wieder entfernt. Die Migration bleibt unangetastet, weil sie auf laufenden DBs bereits appliziert ist.
Source:

(async) hasTable()

AP 1 (050-Migrationsplan): Die Mitglieder-Runtime-/Deployment-Ebene wird aus members entfernt — Runners bleiben reine Topologie-Objekte (ObjectBase Type='runner') mit einer Member-Muster-Companion-Zeile (`RunnerData`) für heißen, nicht versionierten Zustand: - credential_id/public_key → gezogene Lookup-Spalten (Runner-Auth) - heartbeat/capacity → Data-JSON (Topologie-Heartbeat) Bestehende Daten werden aus `runner_credentials`/`runner_runtime` übernommen. Die 1:n-/Queue-/Transfer-Tabellen werden gedroppt; `workspace`/`deployment`- Objekte + deren Links/Visible-Zeilen werden entfernt. KEINE ObjectBase/Links-Enum-MODIFY in dieser Migration: ObjectBase ist system- versioniert, History-Partitionen enthalten alte Zeilen der entfernten Literale (workspace/deployment/…) — ein MODIFY liefe in „Data truncated". Frische DBs entstehen ohnehin ohne die Literale (die erzeugenden Migrationen sind aus der Kette entfernt, vgl. 20260813-runner-object-types/20260827-tailnet-object-types); bestehende dev-DBs behalten einen harmlosen Enum-Superset. Gilt für laufende dev-DBs (dbVersion) UND frische Boots (alphabetisch nach 20260827-tailnet-object-types).
Source:

hashSensitiveValue(value, type) → {string}

Create deterministic hash for sensitive string data Same input always produces same hash (preserves uniqueness in embeddings)
Parameters:
Name Type Description
value string Value to hash
type string Type of value (email, phone, etc.)
Source:
Returns:
- Hashed placeholder
Type
string

(async) initializeRedis() → {Promise.<boolean>}

Initialize the Redis connection after secrets are loaded. Nebenläufigkeitsvertrag: parallele Aufrufe starten **einen** Versuch und bekommen dasselbe Ergebnis. Ein Versuch, der `false` liefert (Secrets noch nicht geladen) oder wirft, wird **nicht** festgeschrieben — der nächste Aufruf versucht es erneut. Genau darauf ist der Startpfad angewiesen: `server.js` ruft früh (noch ohne Secrets) auf und bekommt `false`, die erste Welle `publishEvent` initialisiert danach parallel.
Source:
Returns:
Returns true if initialized successfully, false otherwise
Type
Promise.<boolean>

(async) insertAchievement(object, achievementUID, templateUID, session, memberUID, connection) → {Promise.<void>}

import { parseTimestampToSeconds } from '../../utils/parseTimestamp.js' Inserts a new achievement into the database.
Parameters:
Name Type Description
object Object Achievement object to insert
achievementUID string | Buffer UUID (hex string or Buffer) of the achievement
templateUID string | Buffer UUID (hex string or Buffer) of the template
session Object User session data
memberUID string | Buffer UUID (hex string or Buffer) of the member
connection Object Database connection for transaction
Source:
Returns:
Type
Promise.<void>

(async) insertFunction() → {Promise.<void>}

Inserts or updates a function template in the database, manages related links and triggers updates. - Renders a function object from a template and request body. - Cleans up and compresses access filters to avoid unnecessary filter creation. - Inserts or updates the function in the ObjectBase table. - Handles achievement links and triggers requalification or visibility adjustments if needed. - If the function template changes, rebuilds all jobs based on this template and updates their data.
Parameters:
Type Description
Source:
Returns:
Type
Promise.<void>

(async) insertOrUpdateAchievement(req, res) → {Promise.<void>}

Handles the insertion or update of an achievement for a member. This function processes achievement data from the request, checks user authorization, validates the member and template, and either creates a new achievement or updates an existing one. It also handles achievement renewal logic and queues necessary updates.
Parameters:
Name Type Description
req Object The request object
Properties
Name Type Description
params Object URL parameters
Properties
Name Type Description
member string UUID of the member
template string UUID of the achievement template
body Object Request body
Properties
Name Type Attributes Description
UID string Achievement UUID
date number <optional>
Date of the achievement (timestamp)
userAdded string <optional>
User who added the achievement
session Object User session data
Properties
Name Type Description
user string Current user's UUID
root string Root UUID
res Object The response object
Source:
Throws:
- Logs errors with errorLoggerUpdate
Type
Error
Returns:
- Sends JSON response with success status and result
Type
Promise.<void>

(async) insertOrUpdateJob(req, res) → {Promise.<void>}

Inserts or updates a job in the system. This function handles the creation of a job for a member in a specific group with a specified function. It performs several authorization checks and validations before proceeding with the insertion.
Parameters:
Name Type Description
req Object The HTTP request object
Properties
Name Type Description
query Object Query parameters
Properties
Name Type Attributes Description
timestamp number <optional>
Optional timestamp for the job
params Object URL parameters
Properties
Name Type Description
group string UUID of the group
member string UUID of the member
function string UUID of the function
body Object Request body
Properties
Name Type Description
UID string UUID of the job to be created
session Object Session information
Properties
Name Type Description
user string Current user's UUID
root string Root UUID
res Object The HTTP response object
Source:
Throws:
- Logs errors through errorLoggerUpdate
Type
Error
Returns:
- Sends a JSON response with success status and result or error message
Type
Promise.<void>

(async) invalidateRegistryCache(orgId)

Sagt den Consumern, dass sich das Registry dieser Organisation geändert hat. Best-effort: ein fehlendes Redis darf das Speichern nicht scheitern lassen.
Parameters:
Name Type Description
orgId string
Source:

isEmbeddingServerHealthy() → {Promise.<boolean>}

Check if embedding server is healthy
Source:
Returns:
Type
Promise.<boolean>

isEnabled()

Feature flags for the staged rollout of the Project/Share feature set. Flags default to ENABLED so the API is usable right after the schema migration; set them to 'false'/'0' to keep Project functions disabled until rollout is complete (see 080-Workspaces/025-Members-Backend-Implementation-Plan.mdx). - PROJECT_OBJECTS_ENABLED gates Project/Share CRUD routers - NORMALIZED_VISIBLE_SCOPES gates the normalized visible/changeable/admin rebuild for generic target scopes (projects and accounting target types) - PROJECT_EVENTS_ENABLED gates lifecycle + rights-delta event publishing - RUNNER_OBJECTS_ENABLED gates Runner/Deployment control-plane routers
Source:

isFamilyEntry()

Ein geteilter Eintrag ist 'family' (Adresse/E-Mail/Telefon) bzw. 'familyFees' (Konto).
Source:

isFixRequested(value) → {boolean}

Parameters:
Name Type Description
value unknown
Source:
Returns:
Type
boolean

isFixRequested(value) → {boolean}

Parameters:
Name Type Description
value unknown
Source:
Returns:
Type
boolean

isReadOnly(metadata)

Is this share write-locked? (`metadata.mode` = readOnly / reference)
Parameters:
Name Type Description
metadata Object
Source:

isRootGroupSql(alias) → {string}

SQL fragment: is `${alias}` a top-level group (an organization)? Two equivalent markers exist in the data, and both are accepted: - `Data.root = true` (the flag set by the org setup), and - a `memberSys` self-link (`UID = UIDTarget = `), which marks the top level of the group tree. Test fixtures use the `memberSys` self-link; checking only `Data.root` would miss organizations that carry just that marker.
Parameters:
Name Type Description
alias string the ObjectBase alias
Source:
Returns:
Type
string

isValidHost()

Validate a Git host name (hostname / host:port).
Source:

isValidHostKey()

Validate a known_hosts line: " ".
Source:

isValidLogInterval(interval) → {boolean}

Validates log interval format
Parameters:
Name Type Description
interval string Interval string to validate (e.g., '1d', '1h')
Source:
Returns:
Type
boolean

isValidLogSize(size) → {boolean}

Validates log size format
Parameters:
Name Type Description
size string Size string to validate (e.g., '20M', '1G')
Source:
Returns:
Type
boolean

isValidName()

Validate a credential name (path-safe, used in the Vault path).
Source:

keyComponents()

Helper function to generate key components for file paths
Source:

languageUrlGen()

URL generator for language file uploads
Source:

levelOf(metadata) → {'read'|'write'}

Wire `linkType` derived from the share mode — the former write/read link level is now a property of the share.
Parameters:
Name Type Description
metadata Object
Source:
Returns:
Type
'read' | 'write'

(async) linkExcludeIntersect(UIDFilter, filtered, target, connection) → {Promise.<void>}

Creates database links for excluded/intersected objects
Parameters:
Name Type Description
UIDFilter Buffer Filter UID
filtered Array.<any> Filtered objects to exclude/intersect
target Buffer Target list UID
connection any Database connection
Source:
Returns:
Type
Promise.<void>

(async) linkIncludes(sourceType, UIDFilter, filtered, target, execConnection) → {Promise.<void>}

Creates database links for included objects
Parameters:
Name Type Description
sourceType string Source type ('group' or 'list')
UIDFilter Buffer Filter UID
filtered Array.<any> Filtered objects to link
target Buffer Target list UID
execConnection any Database connection
Source:
Returns:
Type
Promise.<void>

linkReport(link) → {any}

Link shape for the report. The UID is rendered with `HEX2uuid`, which yields the canonical `UUID-…` form the API uses everywhere. The generated SQL column `TUIDTarget` must NOT be used for this: it renders the same bytes WITHOUT the `UUID-` prefix, so report and API would disagree on the format.
Parameters:
Name Type Description
link any
Source:
Returns:
Type
any

(async) listAchievementsPerson(req, res) → {Promise.<void>}

Fetches achievements associated with a person, joining with template data. Can return achievements as of a specific point in time. Can filter to return only unique (latest) achievements.
Parameters:
Name Type Description
req Object Express request object.
Properties
Name Type Description
query Object Request query parameters.
Properties
Name Type Attributes Description
timestamp number <optional>
Optional timestamp for point-in-time query.
unique boolean <optional>
If true, returns only the latest version of each achievement.
params Object Request path parameters.
Properties
Name Type Description
UID string UID of the person whose achievements to list.
session Object User session object.
Properties
Name Type Description
user string UID of the current user.
res Object Express response object.
Source:
Throws:
- Logs any errors encountered during database operations.
Type
Error
Returns:
- Returns a JSON response with success status and result array.
Type
Promise.<void>

listAppReleases(appKey) → {Promise.<Array.<object>>}

Alle Releases einer App, Zeiger zuerst.
Parameters:
Name Type Description
appKey string
Source:
Returns:
Type
Promise.<Array.<object>>

listShares()

Parameters:
Type Description
Source:

(async) listVaultKeys(path) → {Promise.<Array.<string>>}

List credential names directly under a Vault directory. Returns [] when the path does not exist (no credentials yet).
Parameters:
Name Type Description
path string
Source:
Returns:
Type
Promise.<Array.<string>>

(async) loadAllConfigs()

Vollstaendiger Config-Durchlauf: liest alle Orga-YAMLs (admin + app-spezifisch) und baut `configs`/`mergedConfigs` von Grund auf neu auf. ACHTUNG: Setzt unterwegs `configs[app] = {}` zurueck und ist deshalb *nicht* nebenlaeufig ausfuehrbar. Immer ueber `readAllConfigs()` bzw. `ensureConfigsLoaded()` aufrufen — niemals direkt.
Source:

mailConfig() → {Object|null}

Liest die Mail-Konfiguration — oder `null`, wenn sie unvollstaendig ist. Der alte Guard lautete `if(process.env.mailHost && process.env.mailPort && process.env.mailUser && process.env.mailPassword, process.env.errorMail)`. Das ist ein **Komma-Operator**: der linke Ausdruck wird ausgewertet und verworfen, geprueft wird nur `errorMail`. Eine halb gesetzte Konfiguration lief damit in `createTransport` und warf erst beim Senden.
Source:
Returns:
Type
Object | null

mapRelease(row)

Zeile → Release-Objekt. `Backends` kommt über den JSON-Cast bereits als Objekt; `null` bleibt `null` und bedeutet „keine Backend-URLs im Release".
Parameters:
Name Type Description
row object
Source:

mergeCustomizer()

Lodash merge customizer - do not merge arrays
Source:

(async) migrateAchievementDates() → {Promise.<void>}

Migrates achievements from 05.01.2023 to 01.01.1900 Uses delete and re-insert to handle system versioned table
Source:
Returns:
Type
Promise.<void>

(async) migrateAction(action) → {Promise.<void>}

Handles migration actions for moving objects between different groups or targets. Delegates to type-specific submodules.
Parameters:
Name Type Description
action treeAction The migration action object containing source and target information
Source:
Throws:
Throws an error if migration is attempted for unsupported object types
Type
Error
Returns:
Type
Promise.<void>

(async) migrateAction()

Source:

minioput()

Put in MinIO — public bucket über den publicClient, sonst der interne
Source:

minioput()

Put a Buffer into MinIO — uses publicMinioClient for PUBLIC_BUCKET, myMinioClient otherwise
Source:

modeFromLinkType(linkType) → {string|null}

Resolve an incoming `linkType` into a share mode. `memberA`/`write` mean editable, `member`/`read` mean read only — that is the faithful translation of the old link level into the new share property.
Parameters:
Name Type Description
linkType unknown
Source:
Returns:
the mode, or null for an unknown value
Type
string | null

nameReplace(str) → {string}

Replace special characters in a string with underscores Used to create valid property names from parameter names
Parameters:
Name Type Description
str string
Source:
Returns:
Type
string

newAvatar(api)

Parameters:
Name Type Description
api Object
Source:

newAvatar(api)

Parameters:
Name Type Description
api Object
Source:

(async) newUid() → {Promise.<Buffer>}

Erzeugt eine UID **in der Datenbank** (`UIDV1()` = echte, sortierbare v1). Bewusst nicht in JavaScript: `randomUUID()` wäre eine v4, und ihr Hex-String passt in keines der SQL-UUID-Formate (§ registryTypes).
Source:
Returns:
16 Byte
Type
Promise.<Buffer>

normalizeDomainMapByOrg(map) → {Record.<string, Record.<string, {type: string, status: string}>>}

Wie `normalizeDomainMap`, nur eine Ebene tiefer: `{ orgId: { domain: entry } }`. Der Konflikt-Check vergleicht über **alle** Organisationen und muss dafür dieselbe Form sehen wie eine einzelne Organisation.
Parameters:
Name Type Description
map unknown
Source:
Returns:
Type
Record.<string, Record.<string, {type: string, status: string}>>

normalizeGitUrl(url) → {string}

Normalisiert eine Git-URL fuer den **Hinweis**-Vergleich (nie fuer eine Identitaet — die ist die UID-Kette). Protokoll, `git@host:`-Praefix, `.git`-Suffix, Trailing-Slash und Gross-/Kleinschreibung fallen weg.
Parameters:
Name Type Description
url unknown
Source:
Returns:
leer, wenn keine URL brauchbar ist
Type
string

normalizeMode(mode) → {string}

Canonical `metadata.mode`. Tolerates case/whitespace and the legacy `reference` spelling, which stays a **block** (fail-closed).
Parameters:
Name Type Description
mode unknown
Source:
Returns:
Type
string

normalizeValue(value, type) → {string}

Normalize sensitive values before hashing for consistency Same value in different formats produces same hash
Parameters:
Name Type Description
value string Raw value to normalize
type string Type of value (email, phone, iban, etc.)
Source:
Returns:
- Normalized value
Type
string

num(value) → {number|null}

SQL returns `JSON_VALUE` results as strings; levels are compared numerically.
Parameters:
Name Type Description
value unknown
Source:
Returns:
Type
number | null

num(value) → {number|null}

SQL returns numeric columns as strings; levels are compared numerically.
Parameters:
Name Type Description
value unknown
Source:
Returns:
Type
number | null

openAPIMiddleware(baseDir)

Middleware to serve combined OpenAPI documentation
Parameters:
Name Type Description
baseDir string Base directory for resolving references
Source:

parseCursor(cursor) → {number}

Parse an opaque cursor into its numeric seq.
Parameters:
Name Type Description
cursor string
Source:
Returns:
Type
number

parseTimestampToSeconds(val) → {number|null}

Parse an incoming query timestamp parameter. Accepts a number or string (in milliseconds) and returns seconds (number) or null. Returns null for undefined, null, NaN, or empty string.
Parameters:
Name Type Description
val string | number | undefined | null
Source:
Returns:
Type
number | null

parseTimestampToSecondsOrDefault(val, fallback) → {number}

Parse an incoming timestamp value (milliseconds) and return a seconds value or fallback number.
Parameters:
Name Type Description
val string | number | undefined | null
fallback number fallback seconds value when val is not present
Source:
Returns:
Type
number

privateUrlGen()

URL generator for private file uploads. `prefix` is an optional sub-folder (e.g. 'avatar', 'documents', 'editor'). Clients that cannot send multipart fields - such as CKEditor's SimpleUploadAdapter, which only posts the file - omit it; the artefact then lives directly under the object folder, i.e. `/`. That keeps it an asset of the object itself and makes it show up in `GET /files/{UID}`.
Source:

(async) processGroupEntry(ObjectFilter, of)

Processes a single filter entry and groups it under the appropriate entry key in the ObjectFilter. This function organizes filter data by entry UID, creating or updating filter collections for include, exclude, and intersect filters, along with membership information.
Parameters:
Name Type Description
ObjectFilter Record.<string, any> The object to store grouped filter data, keyed by entry UID
of any Filter object containing entry data, filter information, and list details
Source:
Throws:
Will log an error if any operation fails during execution.

(async) processIncludeFilter(include, myObjects) → {Promise.<void>}

Processes the inclusion filter and updates the database with the filtered objects. This function handles the creation of new entries, linking entries to filters, and processing exclude and intersect filters for newly created entries.
Parameters:
Name Type Description
include Object The inclusion filter object containing filter data and source type.
myObjects Array.<Object> Array of objects to be filtered and processed.
Source:
Throws:
Logs and throws an error if any issue occurs during processing.
Type
Error
Returns:
Resolves when the processing is complete.
Type
Promise.<void>
Example
const include = {
  Data: {  filter criteria here },
  SourceType: 'group',
  listUID: 'someUID',
  UID: 'filterUID'
};
const myObjects = [/ array of objects as retrieved by getObjects/];
await processIncludeFilter(include, myObjects);

processTraversalLayer() → {Array.<Buffer>}

Applies one traversal layer and computes the next frontier.
Parameters:
Type Description
Source:
Returns:
Type
Array.<Buffer>

projectOnto(shape, value) → {unknown}

Legt `value` auf die Felder von `shape` um. Ohne diesen Schritt wäre der Bericht **immer** rot, und zwar aus einem Grund, der kein Fehler ist: die Registry hängt dem App-Objekt die `appId` an (sie ist der Map-Schlüssel und liegt deshalb in `Data`), Vault kennt das Feld nicht. Ein `JSON.stringify`-Vergleich sähe darin eine Abweichung und meldete jede App als „~ abweichend" — ein Bericht, der nie grün wird, wird nicht gelesen. Verglichen wird deshalb genau das, was Vault **behauptet**: ein Feld, das in Vault fehlt, kann in der DB hinzukommen. Ein Feld, das Vault hat und die DB verloren hat, bleibt eine Abweichung.
Parameters:
Name Type Description
shape unknown die Vault-Seite (bestimmt die Feldmenge)
value unknown die DB-Seite
Source:
Returns:
Type
unknown

projectShares()

Register project share filter routes on a project router. Projects reuse the complete list/dlist/email share mechanism (`/api/kpe20/project/share/...`): filters are stored as ObjectBase entries of Type visible/changeable, linked to the project via a Links.Type='list' link, and materialized through the same visibility pipeline.
Parameters:
Type Description
Source:

publicUrlGen()

URL generator for public file uploads
Source:

publishLevels(verb, rows, organization) → {void}

Fasst Zeilen zu einem Event je `(ObjectType, Level, Object)` zusammen.
Parameters:
Name Type Description
verb 'add' | 'remove'
rows Array.<VisibleScope>
organization string | Buffer | null
Source:
Returns:
Type
void

q()

Waehlt `connection.query` (Transaktion) oder den Pool.
Source:

(async) queryGroupLinksForFrontier(userUID, frontier)

Loads one traversal layer for the current frontier.
Parameters:
Name Type Description
userUID Buffer
frontier Array.<Buffer>
Source:

(async) queueAdd(root, user, type, UID, UIDBelongsTo, oldTarget, newTarget, timestampopt) → {Promise.<void>}

Adds a single action to the tree queue and triggers queue processing.
Parameters:
Name Type Attributes Default Description
root Buffer | string The UID of the root organization (Buffer or hex string)
user Buffer | string The UID of the user requesting the action
type string The type of action to be performed
UID Buffer | string The UID of the object being acted upon
UIDBelongsTo Buffer | string The UID of the parent object
oldTarget Buffer | string | null The UID of the old target object (for migrations/removals)
newTarget Buffer | string | null The UID of the new target object (for additions/migrations)
timestamp number | null <optional>
null Optional timestamp for the action
Source:
Returns:
Type
Promise.<void>

(async) queueAddArray(req) → {Promise.<void>}

Adds multiple actions to the tree queue in batch and triggers queue processing.
Parameters:
Name Type Description
req Object Express request object with session data
Properties
Name Type Description
session Object Session object
Properties
Name Type Description
root string The root organization UUID
user string The user UUID
Source:
Returns:
Type
Promise.<void>

quoteGraphviz(value) → {string}

Builds a Graphviz-compatible, quoted label.
Parameters:
Name Type Description
value string
Source:
Returns:
Type
string

rateLimitedRequest(requestFn) → {Promise.<any>}

Rate limiter that ensures we don't exceed LocationIQ free tier limits
Parameters:
Name Type Description
requestFn function The async function to execute
Source:
Returns:
Type
Promise.<any>

(async) readCode() → {Promise.<({code: string, tenant: string, createdBy: string, status: string, mode: string, groupUID: (string|null), tailnetUID: (string|null)}|null)>}

Source:
Returns:
Type
Promise.<({code: string, tenant: string, createdBy: string, status: string, mode: string, groupUID: (string|null), tailnetUID: (string|null)}|null)>

readLang(req) → {string}

Sprachcode aus Query oder Pfad, mit Default.
Parameters:
Name Type Description
req ExpressRequestAuthorized
Source:
Returns:
Type
string

readMode() → {'vault'|'dual'|'db'}

Source:
Returns:
Type
'vault' | 'dual' | 'db'

(async) readProjectRows(uidHex)

Read current project rows.
Parameters:
Name Type Description
uidHex string
Source:

(async) readRunnerCompanion(uidHex) → {Promise.<({last_seen_at: (string|null), capacity: object, heartbeat: object, lookup_key: (string|null)}|null)>}

Companion-Zeile eines Runners — heißer, nicht versionierter Zustand nach dem Member-Muster, in der generischen `Member`-Tabelle: `lookup_key` als Lookup-Slot, heartbeat/capacity/lastSeenAt im `Data`-JSON.
Parameters:
Name Type Description
uidHex string
Source:
Returns:
Type
Promise.<({last_seen_at: (string|null), capacity: object, heartbeat: object, lookup_key: (string|null)}|null)>
Parameters:
Name Type Description
runnerHex string
Source:

(async) readRunnerRow(uidHex)

Parameters:
Name Type Description
uidHex string
Source:

(async) readShare(shareHex, projectHex)

Read a share row that is linked to the given project. Returns the share with its link type, or null when the share does not exist or has no link to this project. Both link directions are accepted during the migration.
Parameters:
Name Type Description
shareHex string
projectHex string
Source:
Parameters:
Name Type Description
tailnetHex string
Source:

(async) readTailnetRow(uidHex)

Parameters:
Name Type Description
uidHex string
Source:

(async) readVaultSecret(path) → {Promise.<(Object|null)>}

Read one credential secret. Returns null when missing OR when the private key was blanked (a soft/blanked delete leaves an empty private_key behind — such entries are zombies and must not surface in the API).
Parameters:
Name Type Description
path string
Source:
Returns:
Type
Promise.<(Object|null)>

readsDb()

Liest aus der DB? (`dual` und `db` lesen beide zuerst die DB)
Source:

(async) rebuildFees(UIDfamily, organization) → {Promise.<boolean>}

Rebuilds the fee structure for a given family by UID. This function fetches all family members, recalculates their fee indices, updates the fee address if necessary, and persists any changes to the database. It also publishes relevant events if the fee structure has changed. This has to be called if a family cahnged, e.g. a new member was added or removed,
Parameters:
Name Type Description
UIDfamily Buffer The UID of the family whose fees are to be rebuilt.
organization string The organization UID for multi-tenant context.
Source:
Throws:
Will log and handle errors internally if any database or processing error occurs.
Returns:
Returns true if the operation was successful, false otherwise.
Type
Promise.<boolean>

(async) rebuildFiltersDlist(rebuildFilters, UIDOrga) → {Promise.<Object>}

Rebuilds dynamic list filters and publishes appropriate events for membership changes. This function removes and re-adds filters within a transaction, then compares the before/after state to publish add/remove events for affected list members.
Parameters:
Name Type Description
rebuildFilters Array Array of filter objects to rebuild, each containing UIDFilter, UIDList, and Type
UIDOrga string | Buffer The unique identifier of the organization (required)
Source:
Throws:
Will log an error if any operation fails during execution.
Returns:
Result object containing beAdded and removed arrays
Type
Promise.<Object>

rebuildFullTree(identifyer, options) → {Promise.<{deleted: Array, added: Array}>}

High-level rebuild that ensures groups are rebuilt first (sorted by hierarchie ASC), so that group-to-group member links are correct before rebuilding persons/jobs/externs whose member links depend on the group tree.
Parameters:
Name Type Description
identifyer string Object type ('person','group','extern','event','job') or a UUID string
options
Source:
Returns:
Type
Promise.<{deleted: Array, added: Array}>

rebuildMembershipTree(UIDs, options) → {Promise.<{deleted: Array.<{UID: Buffer, UIDTarget: Buffer, DisplayMain: string, Display: string}>, added: Array.<{UID: Buffer, UIDTarget: Buffer, DisplayMain: string, Display: string, success: boolean}>}>}

Rebuilds the membership tree for a set of UIDs. Uses a virtual transaction to compute the desired link state without committing, then diffs against the current state and applies only the necessary inserts/deletes. This avoids touching existing rows in the system-versioned Links table (updates would create unnecessary history entries).
Parameters:
Name Type Description
UIDs Array.<Buffer> hex Buffer UIDs of the objects to rebuild
options
Source:
Returns:
Type
Promise.<{deleted: Array.<{UID: Buffer, UIDTarget: Buffer, DisplayMain: string, Display: string}>, added: Array.<{UID: Buffer, UIDTarget: Buffer, DisplayMain: string, Display: string, success: boolean}>}>

reconcileAccounts(data, desired, remove)

Gleicht die geteilten Konten auf einem Mitglied ab — dieselbe Regel wie `reconcileSharedField`, nur mit der entschluesselten IBAN als Schluessel. Eigene Konten bleiben unberuehrt. Mit `remove` fallen die geteilten Konten weg, die es in der Quelle nicht mehr gibt — das ist der Fall „geloescht" bzw. „auf privat umgestuft", der laut UI fuer die ganze Familie gilt. Ein geteiltes Konto wird insbesondere NICHT still auf einen anderen Typ herabgestuft. Uebernommen wird jeweils der Eintrag so, wie er vorliegt — Klartext-IBANs werden weder eingefuehrt noch entfernt.
Parameters:
Name Type Description
data Object Member.Data des Mitglieds (wird veraendert)
desired Array.<Object>
remove boolean
Source:

reconcileSharedField(data, field, desired, remove)

Gleicht EIN geteiltes Feld auf einem Mitglied ab. `desired` sind die geteilten Eintraege der Quelle — sie sind der gewuenschte geteilte Satz. Fehlende werden ergaenzt, geaenderte aktualisiert. Mit `remove` werden zusaetzlich die geteilten Eintraege entfernt, die es in der Quelle nicht mehr gibt: das ist der Fall „geloescht" bzw. „herabgestuft", der laut UI fuer die ganze Familie gilt. Eintraege mit eigenem Typ bleiben immer unberuehrt — ein geteilter Eintrag wird insbesondere NICHT still herabgestuft.
Parameters:
Name Type Description
data Object Member.Data des Mitglieds (wird veraendert)
field string
desired Array.<Object>
remove boolean
Source:

(async) recreateBanner(UID, banner, bannerRules, req)

Recursively propagates a banner update to child groups, jobs, and persons.
Parameters:
Name Type Description
UID Buffer Group UID
banner string Banner URL/path
bannerRules object Banner inheritance rules
req ExpressRequestAuthorized
Source:

(async) recreateJobs(req, jobs, timestamp, requalifyopt)

This function iterates through a list of jobs and updates their corresponding entries in the ObjectBase database table. It processes job qualification status, renders objects from templates, and updates various fields including Title, qualification index, hierarchie, stage, gender
Parameters:
Name Type Attributes Default Description
req Object The request object containing session information.
jobs Array Array of job objects to be recreated.
timestamp number The timestamp to use for updating objects.
requalify boolean <optional>
false Whether to requalify the jobs.
Source:
Throws:
Logs error if job recreation fails.
Type
Error

(async) recreateJobsPerson(req, res, requalifyopt) → {Promise.<void>}

Retrieves job data for a person at a specific point in time (if timestamp provided), then recreates the jobs using the recreateJobs function. When requalify is true, it recalculates job qualification status based on achievements if requalify is true (default). then recreates the jobs using the recreateJobs function.
Parameters:
Name Type Attributes Default Description
req Object Express request object
Properties
Name Type Description
params Object Request parameters
Properties
Name Type Description
UIDperson string UID of the person
query Object Request query parameters
Properties
Name Type Attributes Description
timestamp number <optional>
Optional timestamp for point-in-time query
res Object Express response object
requalify boolean <optional>
true Whether to recalculate job qualification status based on achievements
Source:
Throws:
- Logs error to error logger if query fails
Type
Error
Returns:
- Sends JSON response indicating success or handles error
Type
Promise.<void>

(async) recreateJobsPerson(req, UIDperson, requalifyopt) → {Promise.<Object>}

Recreates jobs for a specific person based on their UID. This function fetches job data from the database for a person, potentially as of a specific timestamp, and then recreates these jobs. It can also requalify the jobs as part of the process.
Parameters:
Name Type Attributes Default Description
req Object The request object containing query parameters.
UIDperson string | Buffer The UID (hex string or Buffer) of the person whose jobs need to be recreated.
requalify boolean <optional>
true Whether to requalify the jobs during recreation.
Source:
Throws:
- Any errors that occur during the job recreation process are logged.
Type
Error
Returns:
- A promise that resolves when the jobs have been recreated.
Type
Promise.<Object>

reduceResult(result) → {Array.<object>}

Deduplicate a raw query result set: - Skip entries with linkType `member0` - Merge Data objects for duplicate UIDBelongsTo values - Omit entries entirely if a `member0` counterpart exists
Parameters:
Name Type Description
result Array.<object> Raw query result rows
Source:
Returns:
Deduplicated result
Type
Array.<object>

(async) removeAction(action) → {Promise.<void>}

Handles various removal actions in the tree structure. Delegates to type-specific submodules. Note on dispatch order: the filter-type guards (include/exclude/intersect and visible/changeable) use plain `if` blocks and are not mutually exclusive with the final `else` branch of the listMember/list/family chain. This matches the original logic exactly.
Parameters:
Name Type Description
action treeAction
Source:
Returns:
Type
Promise.<void>

(async) removeAction()

Source:

(async) removeFilter(req) → {Promise.<Object>}

Remove a specific filter by UID
Parameters:
Name Type Description
req ExpressRequestAuthorized Express request object
Source:
Returns:
Result object with success status
Type
Promise.<Object>
Removes one `memberA` link. Deletes only the current version; the history row survives the system versioning and stays inspectable. `ValidUntil > NOW()` is repeated on purpose: in a system-versioned table it is the "is current" test, so a link that another process removed in between is a no-op.
Parameters:
Name Type Description
sourceUID Buffer binary UID of the link owner
targetUID Buffer binary UID of the target to remove
Source:

(async) removeObjects(myDEObjects, exclude, listUID) → {Promise.<(Array.<any>|undefined)>}

Removes objects based on exclude filter criteria
Parameters:
Name Type Description
myDEObjects Array.<any> Array of objects to potentially remove
exclude any Exclude filter object
listUID any List identifier
Source:
Returns:
- Array of removed objects
Type
Promise.<(Array.<any>|undefined)>

requestId()

Parameters:
Type Description
Source:

(async) requireAccessible(req, uidHex, orgHex)

Authorize that the project is currently accessible to the caller (snapshots are service operations gated by the current event-driven rights).
Parameters:
Name Type Description
req ExpressRequestAuthorized
uidHex string
orgHex string
Source:

(async) requireProjectAdmin(req, uidHex)

Authorize: the user may administrate the project (Visible.Type='admin' or org admin).
Parameters:
Name Type Description
req ExpressRequestAuthorized
uidHex string
Source:

(async) requireProjectChangeable(req, projectHex) → {Promise.<void>}

Verify the project exists in the organization and the user may **change** it (Visible `changeable` or `admin`). Changeable is enough to create or link shares — the creator becomes the owner of the new share.
Parameters:
Name Type Description
req ExpressRequestAuthorized
projectHex string
Source:
Returns:
Type
Promise.<void>

(async) requireProjectVisible(req, projectHex) → {Promise.<void>}

Verify the project is at least visible to the user (share read is derived from the project right).
Parameters:
Name Type Description
req ExpressRequestAuthorized
projectHex string
Source:
Returns:
Type
Promise.<void>

(async) requireShareAdmin(req, projectHex, shareHex) → {Promise.<void>}

Verify the user may administer this share: project `admin` (inherited) or `Visible.admin` on the share itself (the owner).
Parameters:
Name Type Description
req ExpressRequestAuthorized
projectHex string
shareHex string
Source:
Returns:
Type
Promise.<void>

resolveDomain(host) → {Promise.<({orgId: string, appId: (string|null), appUid: string}|null)>}

Host → Organisation + App. Gesucht wird über das Feld `domain` der App, nicht über ein Domain-Objekt: eine frühere Fassung legte für jeden App-Host ein eigenes `appDomain`-Objekt an und verlinkte es. Das machte den Domain-Bestand einer Organisation ununterscheidbar von ihrer Routing-Tabelle — dieselbe Liste trug plötzlich Mandanten-Domains (Cookie-Umfang, CORS) und App-Hosts. Der Host steht dort, wo der Admin ihn einträgt: im App-Eintrag. Der Vergleich läuft über appHostFor, also über **dieselbe** Regel, nach der der Host aufgebaut wird. Ein reiner String-Vergleich mit dem `domain`-Feld wäre falsch: bei einem internen Präfix (`sjm`) steht dort nicht der Host, sondern nur `sjm`. Kosten: ein Durchlauf über die App-Objekte (gemessen 29 in dieser Datenbank). Ein Index wäre erst bei einem Vielfachen davon nötig.
Parameters:
Name Type Description
host string
Source:
Returns:
Type
Promise.<({orgId: string, appId: (string|null), appUid: string}|null)>

(async) resolveProjectGroup(groupHex, orgHex) → {Promise.<({UID: string, Title: string, Display: string, Data: Object}|null)>}

Resolve the project group (owner group) for a project. Follows the list/dlist pattern: the requested group is loaded, falling back to the root group of the organization if it does not exist or is not a group/event object.
Parameters:
Name Type Description
groupHex string requested group UID (hex) or organization UID
orgHex string organization UID (hex)
Source:
Returns:
Type
Promise.<({UID: string, Title: string, Display: string, Data: Object}|null)>

(async) resolveProjectShare(projectHex, shareHex) → {Promise.<(string|null)>}

Das Share-Objekt, das **dieses** Projekt fuer einen Root benutzt. Ein Aufrufer darf den Root nennen (den die Suche vor dem Ableger-Modell zeigte) oder das Projekt-Objekt selbst (Basis/Ableger) — beides muss denselben Treffer geben. Die harte Regel „ein Root hoechstens einmal je Projekt" macht die Auflösung eindeutig, deshalb ist sie kein Raten.
Parameters:
Name Type Description
projectHex string
shareHex string
Source:
Returns:
die UID des Projekt-Objekts
Type
Promise.<(string|null)>

resolveRelease(appKey, orgIdopt)

Löst die Auslieferung auf: Canary zuerst, sonst der Zeiger, sonst nichts. Die Reihenfolge ist der Kern des Modells — sie macht Canary **additiv**. Wer keinen Override hat, folgt `Current`; es gibt keinen Zustand, in dem eine Organisation versehentlich kein Release mehr hat, nur weil Canary eingeführt wurde.
Parameters:
Name Type Attributes Description
appKey string
orgId string <optional>
UID in `UUID-`-Form (41 Zeichen)
Source:
Returns:

resolveReleaseEnv(appKey, orgId) → {Promise.<({env: (object|null), version: string, source: ReleaseSource}|null)>}

Der `window.env`-Aufsatz eines Releases — die Schlüssel aus `AppRelease.Backends`, **unverändert**. Bewusst ohne Übersetzungstabelle: die Backends liegen bereits unter dem Namen, unter dem das Frontend sie liest (`api`, `apiPortal`, …). Eine Umbenennung an dieser Stelle würde nur eine zweite Stelle schaffen, an der ein neuer Backend-Name nachgetragen werden müsste — und eine, die niemand beim Anlegen eines Releases sieht. `env: null` ist eine **gültige** Antwort und heißt „kein Release-Aufsatz": der Consumer behält dann seine Deployment-Werte. `null` als ganzer Rückgabewert dagegen heißt „die App hat überhaupt kein Release" — der Unterschied zwischen „kein Canary" und „falsche App", und der Grund für den 404 in der Route.
Parameters:
Name Type Description
appKey string
orgId string
Source:
Returns:
Type
Promise.<({env: (object|null), version: string, source: ReleaseSource}|null)>

(async) resolveRunnerGroup(groupHex, orgHex)

Resolve the owner group of a runner. `groupHex` may be a group/event UID or an org UID (root group). Falls back to the org root group when the given group is not a group/event object — exactly like project `resolveProjectGroup`.
Parameters:
Name Type Description
groupHex string
orgHex string
Source:

(async) resolveTailnetGroup(groupHex, orgHex)

Resolve the owner group of a tailnet. `groupHex` may be a group/event UID or an org UID (root group). Falls back to the org root group when the given group is not a group/event object — exactly like project `resolveProjectGroup`.
Parameters:
Name Type Description
groupHex string
orgHex string
Source:

resolveTreeUIDs(identifyer) → {Promise.<{UIDs: Array.<Buffer>, isType: boolean}>}

Resolves the UIDs to rebuild based on the identifier. If the identifier is a known object type, fetches all UIDs of that type ordered by hierarchy. If it's a UUID, converts it to hex. Returns an empty array if invalid.
Parameters:
Name Type Description
identifyer string Object type ('person','group','extern','event','job') or a UUID string
Source:
Returns:
Type
Promise.<{UIDs: Array.<Buffer>, isType: boolean}>

resumeAfterReconnect(socketID)

Nach einem Reconnect: verpasste Nachrichten ausliefern und auf Direktzustellung umschalten. Wird beim ersten `monitor`/`monitorObject` aufgerufen — also genau dann, wenn der Client seine Abos neu registriert. Eine frische Verbindung ist bereits `resynced` und ist hier ein No-Op.
Parameters:
Name Type Description
socketID string
Source:

same(a, b) → {boolean}

Parameters:
Name Type Description
a unknown
b unknown
Source:
Returns:
Type
boolean

sanitizeGraphvizColor(color) → {string|null}

Validates a Graphviz color value.
Parameters:
Name Type Description
color any
Source:
Returns:
Type
string | null

sanitizeTextForEmbedding(text, options) → {string}

Sanitize text by replacing sensitive information with hashed placeholders Preserves semantic structure while protecting PII
Parameters:
Name Type Description
text string Text to sanitize
options Object Sanitization options
Properties
Name Type Attributes Default Description
sanitizeEmail boolean <optional>
true Hash email addresses
sanitizePhone boolean <optional>
true Hash phone numbers
sanitizeIban boolean <optional>
true Hash IBAN numbers
sanitizeAddress boolean <optional>
true Hash street addresses
sanitizeCreditCard boolean <optional>
true Hash credit card numbers
sanitizeSSN boolean <optional>
true Hash SSN/tax IDs
Source:
Returns:
- Sanitized text with hashed placeholders
Type
string

saveAppRelease()

Legt ein Release an oder schreibt es fort (Schlüssel `AppKey`+`Version`). `current: true` macht den Zeiger in **einer** Transaktion um: erst alle anderen Zeilen der App auf 0, dann diese auf 1. Sonst könnte bei einem Fehler dazwischen kein oder — schlimmer — _jeder_ Zeiger gesetzt sein, und die Auflösung oben (`Current = 1 LIMIT 1`) würde zufällig wählen.
Parameters:
Type Description
Source:

saveApps(orgId, apps)

Persist the app registry for one organisation.
Parameters:
Name Type Description
orgId string
apps Record.<string, AppEntry>
Source:

saveDomains(orgId, domains)

Persist domain settings for one organisation.
Parameters:
Name Type Description
orgId string
domains Record.<string, string>
Source:

saveMailSettings(orgId, settings)

Persist mail/SMTP settings for one organisation. If the password is the mask sentinel, the existing password is preserved.
Parameters:
Name Type Description
orgId string
settings object
Source:

saveOrgApps(orgId, apps)

Ersetzt den App-Bestand einer Organisation (die Map kommt als Ganzes). Bestehende Apps behalten ihre UID — siehe Dateikopf. Der Host einer App steht als Feld `domain` **im App-Objekt selbst**; es gibt bewusst kein Domain-Objekt und keinen Link dafür. Eine frühere Fassung legte für jeden App-Host automatisch ein `appDomain`-Objekt an und verlinkte es — dadurch enthielt die Domain-Liste einer Organisation anschließend jeden App-Host, und App-Hosts (Routing) und Mandanten-Domains (CORS, Cookie-Umfang, Basis-Domain) waren nicht mehr unterscheidbar. `resolveDomain()` liest das Feld deshalb direkt; bei 4–14 Apps je Organisation braucht es dafür keinen Index.
Parameters:
Name Type Description
orgId string
apps Record.<string, object>
Source:

saveOrgDomains(orgId, domains)

Ersetzt den Domain-Bestand einer Organisation. Angenommen wird `{ [domain]: { type, status } }` **und** die Altform (`"internal"`/`"external"`/`"verified"`) — eine Fassung, die nur die neue Form verstünde, würde den vorhandenen Bestand beim ersten Speichern leeren. Bestehende Domains behalten ihre UID: an ihnen hängen die Basis-Domain- Erkennung (`shared-auth` prüft Kunden-Domains gegen die verifizierten) und der Cookie-Umfang. Löschen und Neuanlegen würde diesen Anker bei jedem Speichern austauschen.
Parameters:
Name Type Description
orgId string
domains Record.<string, unknown>
Source:

(async) saveOrgSection(orgId, section, data)

Persist a named section for one organisation in Vault.
Parameters:
Name Type Description
orgId string
section string
data object
Source:

saveSecretsToVault(secretPath, data) → {Promise.<void>}

Write (or update) a secret in Vault KV v2. Merges the new data on top of any existing secret (patch semantics via POST).
Parameters:
Name Type Description
secretPath string Vault KV v2 path including the "data" segment, e.g. "orgas/data/UUID-xxxx/domains"
data Record.<string, unknown> Key/value data to store
Source:
Returns:
Type
Promise.<void>

scalarEntry()

Altwert-Skalar -> Eintrag, falls ein Feld noch als einfacher Wert gespeichert ist.
Source:

scopeKey(row) → {string}

Der Schluessel einer Zeile fuer den Vergleich: `(UID, UIDUser, Level)` in kanonischer Form. Bewusst **einmal pro Zeile** berechnet. Vorher stand `asUuid` im innersten Praedikat des Diffs, damit rechnete **jedes** `(a, b)`-Paar beide Seiten neu aus — Regex und `HEX2uuid` inklusive. Das war O(n*m) mit teurer Konstante: auf der Dev-Datenbank (`Visible`: 1.085.068 Zeilen) hat ein **einziger** Aufruf den Server stundenlang auf 100 % CPU gehalten und die Event-Loop blockiert. `JSON.stringify` statt einer Verkettung mit Trennzeichen, damit der Schluessel auch fuer nicht deutbare Rohwerte kollisionsfrei bleibt — der Vergleich muss exakt derselbe bleiben wie vorher.
Parameters:
Name Type Description
row VisibleScope
Source:
Returns:
Type
string

searchSimilarEntities(searchText, options) → {Promise.<Array>}

Search for similar entities using vector similarity
Parameters:
Name Type Description
searchText string Text to search for
options Object Search options
Properties
Name Type Attributes Default Description
entityType string <optional>
Filter by entity type
organizationUID Buffer | string <optional>
Filter by organization (Buffer or hex string)
limit number <optional>
10 Maximum number of results
threshold number <optional>
0.7 Minimum similarity threshold (0-1)
distanceMetric string <optional>
'cosine' Distance metric: 'cosine' or 'euclidean'
sanitize boolean <optional>
true Sanitize sensitive PII in search text
sanitizeOptions Object <optional>
Options passed to sanitizeTextForEmbedding
Source:
Returns:
- Array of matching entities with similarity scores
Type
Promise.<Array>

sendErrorMail(cfg, label, errors) → {void}

Verschickt eine Fehler-Mail — fire-and-forget. Ein Fehler im Mailer darf die Fehlerbehandlung nicht aufhalten oder gar werfen, deshalb ist alles umschlossen und der Versand wird nicht abgewartet.
Parameters:
Name Type Description
cfg Object
label string `FATAL` (nur hierfuer wird gemailt)
errors Array.<unknown>
Source:
Returns:
Type
void

serializeErrors(errors) → {string}

Macht Fehler mailbar. `JSON.stringify(new Error('x'))` ergibt `{}` — `message` und `stack` sind nicht-enumerable und fielen damit aus dem Mailtext heraus. Die Fehler-Mail enthielt deshalb nur `[{}]` und war als Meldung wertlos.
Parameters:
Name Type Description
errors Array.<unknown>
Source:
Returns:
Type
string

setCurrentRelease(appKey, version)

Setzt den Zeiger auf eine vorhandene Version. Ein Deploy ist damit ein Config-Update und ein Rollback das Zurücksetzen desselben Zeigers — es startet nichts neu.
Parameters:
Name Type Description
appKey string
version string
Source:

setOrgReleaseOverride(appKey, orgId, version)

Stellt eine Organisation auf ein bestimmtes Release (Canary).
Parameters:
Name Type Description
appKey string
orgId string UID in `UUID-`-Form
version string
Source:

setPublicReadPolicy()

Set an anonymous read policy on a bucket (MinIO / S3). Uses publicMinioClient if available, otherwise falls back to myMinioClient.
Source:

shareToSnapshot(row, projectUid)

Parse a snapshot share row into the contract share shape. The share belongs to the org, so project_uid comes from the snapshot context, not UIDBelongsTo.
Parameters:
Name Type Description
row any
projectUid string
Source:

(async) slugTaken(slug, orgHex, excludeHexopt)

Slug uniqueness within the org (two teams must not collide on the same headscale user / MagicDNS subdomain).
Parameters:
Name Type Attributes Description
slug string
orgHex string
excludeHex string <optional>
Source:

(async) softDeleteVaultSecret(path) → {Promise.<boolean>}

Soft-delete the latest version of a KV2 secret via the data API. Some tokens only get `delete` on the data endpoint (not the metadata one). A soft delete makes the current version unreadable (read returns 404) — good enough for a credential to disappear from the API, though version history remains in Vault.
Parameters:
Name Type Description
path string KV2 data path
Source:
Returns:
true when the soft delete succeeded
Type
Promise.<boolean>

squeeze(rows, entityKeySet, allColumns) → {Array.<Object>}

Squeeze consecutive duplicate history rows for a single entity. Keeps the first occurrence, then only rows whose hash differs from the previous, plus the current (latest) row.
Parameters:
Name Type Description
rows Array.<Object> All history rows for one entity, sorted by ValidFrom
entityKeySet Set.<string>
allColumns Array.<{Field: string, isVirtual: boolean}>
Source:
Returns:
Type
Array.<Object>

syncAccountingForFunction(functionUID) → {Promise.<void>}

Synchronizes Visible.Accounting for ALL jobs linked to a function template. Called when a function template's financialMaster flag or accounting rules change.
Parameters:
Name Type Description
functionUID Buffer | string UID of the function template
Source:
Returns:
Type
Promise.<void>

syncAccountingVisibility(jobUID, optsopt) → {Promise.<void>}

Synchronizes `Visible.Accounting` for a single job. - If financialMaster=true: sets Accounting='admin' on the job's group AND recursively on all sub-groups of that group using a recursive CTE. - If financialMaster=false: removes Accounting rows for this person+group. Does NOT remove if the person has another job with financialMaster in same group.
Parameters:
Name Type Attributes Description
jobUID Buffer | string UID of the job (hex buffer or UUID string)
opts Object <optional>
Options
Properties
Name Type Attributes Description
delete boolean <optional>
If true, the job is being deleted
personUID string <optional>
Person UID (required when opts.delete is true)
groupUID string <optional>
Group UID (required when opts.delete is true)
Source:
Returns:
Type
Promise.<void>

(async) tailnetInOrg(uidHex, orgHex)

Parameters:
Name Type Description
uidHex string
orgHex string
Source:

(async) tailnetInOrg(uidHex, orgHex)

Parameters:
Name Type Description
uidHex Buffer
orgHex Buffer
Source:

testSanitization()

Test sanitization with sample data (for debugging)
Source:

timeOf(value) → {number}

`ValidFrom` is a `timestamp(6)`; the driver hands it over as a `Date`. The comparison has to use the microseconds, not the rendered date.
Parameters:
Name Type Description
value unknown
Source:
Returns:
Type
number

toCredential(ref, orgId, data)

Map a Vault secret payload + ref to the wire object (never the private key).
Parameters:
Name Type Description
ref string {UID}/{name}
orgId string organization UID (to derive scope)
data Object Vault payload
Source:

toListingInput(req)

Parameters:
Name Type Description
req ExpressRequestAuthorized
Source:

toOpenSshPublicKey(derPub) → {string}

Encode an ed25519 public key in DER (SPKI) form as the OpenSSH wire format used by Git hosts ("ssh-ed25519 AAAA..."): string "ssh-ed25519" string raw 32-byte public key The SPKI DER for ed25519 is exactly 44 bytes: 12 byte header + 32 byte key.
Parameters:
Name Type Description
derPub Buffer
Source:
Returns:
Type
string

toReport(person) → {any}

Parameters:
Name Type Description
person any
Source:
Returns:
Type
any

toStringUuid(uuid) → {string}

Helper function to ensure UUIDs are converted to strings
Parameters:
Name Type Description
uuid string | Buffer UUID that might be Buffer or string
Source:
Returns:
- UUID as string
Type
string

(async) traverseGroupGraphRecursive()

Recursively traverses group links level-by-level. Keeps route logic readable while preserving the existing batched SQL behavior.
Parameters:
Type Description
Source:

(async) triggerQueue(rootGroup) → {Promise.<void>}

Triggers the processing of the tree queue for a specific root organization. Processes all queued actions in order and updates the queue status.
Parameters:
Name Type Description
rootGroup Buffer | string The UID of the root organization group (Buffer or hex string)
Source:
Returns:
Type
Promise.<void>

(async) triggerQueues() → {Promise.<void>}

Initializes action handlers and triggers queue processing for all organizations. This function imports the action modules and starts queue processing for all root organizations.
Source:
Returns:
Type
Promise.<void>

(async) unExclude(entry, UIDOrga)

Removes the exclusion link for an entry and publishes add events to notify about the re-inclusion. This function is called when an entry that was previously excluded from a list should now be included.
Parameters:
Name Type Description
entry any Entry object containing UIDEntry, UIDList, UIDBelongsTo
UIDOrga string The unique identifier of the organization (required)
Source:
Throws:
Will log an error if any operation fails during execution.

(async) updateAchievement(object, achievementUID, templateUID, session, connection) → {Promise.<void>}

Updates an existing achievement in the database.
Parameters:
Name Type Description
object Object Achievement object with updated data
achievementUID string | Buffer UUID (hex string or Buffer) of the achievement
templateUID string | Buffer UUID (hex string or Buffer) of the template
session Object User session data
connection Object Database connection for transaction
Source:
Returns:
Type
Promise.<void>

updateEntityEmbedding(entityUID, data, entityType, organizationUID, optionsopt) → {Promise.<void>}

Updates or creates AI embeddings for any entity type asynchronously
Parameters:
Name Type Attributes Description
entityUID Buffer Entity UID as buffer
data Object | string Entity data object or pre-prepared text
entityType string Entity type ('person', 'extern', 'group', etc.)
organizationUID Buffer Organization UID as buffer
options Object <optional>
Optional configuration
Properties
Name Type Attributes Default Description
sanitize boolean <optional>
false Sanitize PII for person/extern data
textBuilder function <optional>
Custom function to build embedding text from data
Source:
Returns:
Type
Promise.<void>

(async) updateJob(req, res) → {Promise.<void>}

Updates a job after validating user permissions. The function performs these steps: 1. Converts the job UID parameter to hexadecimal format 2. Checks if the user has admin permissions for the job 3. Validates the job UID exists 4. Retrieves the existing job data from the database 5. Merges the existing job data with the provided updated data 6. Updates the job record in the database 7. Adds the job to an update list for processing
Parameters:
Name Type Description
req Object Express request object
Properties
Name Type Description
params Object Request parameters
Properties
Name Type Description
UID string Unique identifier of the job to update
body Object Data to update the job with
res Object Express response object
Source:
Throws:
- Logs error through errorLoggerUpdate if operation fails
Type
Error
Returns:
- Sends JSON response with operation success status
Type
Promise.<void>

uploadAppIcon(orgId, appId, fileStream, mimeType) → {Promise.<string>}

Upload an app icon: 1. Stores the original in the public bucket (URL saved in Vault apps[appId].icon). 2. Uses sharp to generate all standard PWA sizes and writes them to the data bucket at `{orgId}/manifests/{appId}/{iconName}` — the exact paths the static server looks up, so no redirect is needed after this.
Parameters:
Name Type Description
orgId string
appId string
fileStream
mimeType string
Source:
Returns:
The public icon URL
Type
Promise.<string>

uploadOrgAppIcon(orgId, appId, fileStream, mimeType) → {Promise.<string>}

Lädt ein App-Icon hoch (Original + PWA-Varianten) und legt ein `appAsset` an. Die S3-Pfade sind **dieselben** wie im Vault-basierten `service.js` — der Static-Server findet sie also unverändert, ohne dass dort etwas umgestellt werden muss.
Parameters:
Name Type Description
orgId string
appId string
fileStream
mimeType string
Source:
Returns:
öffentliche Icon-URL
Type
Promise.<string>

validateDomains(newDomains, currentOrgId)

Prüft einen vorgeschlagenen Domain-Bestand. Gehört hierher und nicht in den Vault-Adapter: geprüft wird gegen **den Bestand, in den geschrieben wird**. Als die Prüfung noch aus Vault las, hat sie den eigenen, inzwischen in der Datenbank liegenden Bestand nicht gesehen — eine Domain ließ sich damit zweimal vergeben.
Parameters:
Name Type Description
newDomains Record.<string, unknown>
currentOrgId string
Source:
Returns:

validateEmailArray() → {Object}

Validate an array of email entries, rejecting any that contain display-name formatting like "Name ". Only bare email addresses are accepted.
Parameters:
Type Description
Source:
Returns:
Type
Object

validateLoggerConfig()

Validates logger configuration
Source:
Throws:
If configuration is invalid
Type
Error

validateRef()

Validate that `:ref` looks like "{UID}/{name}" (the service re-validates).
Source:

vaultPathFor()

KV2 secret path for one credential (ref = {UID}/{name}).
Source:

vectorToString(embedding) → {string}

Convert Float32Array to MariaDB VECTOR text format like "[0.1,0.2,...]"
Parameters:
Name Type Description
embedding Float32Array Embedding vector
Source:
Returns:
- Vector text representation for VEC_FromText()
Type
string

wrapLabel(value, maxLineLength) → {string}

Wraps text into short lines to keep Graphviz labels compact.
Parameters:
Name Type Default Description
value string
maxLineLength number 16
Source:
Returns:
Type
string

writesVault()

Schreibt zusätzlich nach Vault? (`vault` schreibt nur dorthin)
Source:

Type Definitions

AccountItem

Type:
  • Object
Properties:
Name Type Attributes Description
type string Account type (e.g., 'family', 'familyFees', 'personal')
IBAN string <optional>
Bank account IBAN
Source:

AddressItem

Type:
  • Object
Properties:
Name Type Attributes Description
type string Address type (e.g., 'family', 'personal', 'secondary')
road string <optional>
Street name
houseNumber string <optional>
House number
postcode string <optional>
Postal code
countryCode string <optional>
Country code
Source:

AppEntry

Type:
  • Object
Properties:
Name Type Attributes Description
domain string The app's URL or hostname
roles Array.<string> Keycloak roles that grant access
title string Human-readable app name
description string <optional>
port number <optional>
Source:

ClientData

Per-connection state stored in clientDataStore.
Type:
  • Object
Properties:
Name Type Attributes Description
updateBuffer Object | null Pending list-update message to flush on reconnect
updateAbo Set.<Buffer> Set of hex-encoded list UIDs this client monitors (via `monitor` events)
objectAbo Set.<Buffer> Set of hex-encoded object UIDs this client monitors (via `monitorObject` events)
messageBuffer Array General message buffer (reserved for future use)
UIDuser string userUID of the connected user
UIDroot string Organisation UID active for this connection
orgSource string How orgUID was determined: 'header' | 'session' | 'user-default' | 'dynamic'
connectedAt number Unix ms timestamp of initial connect
queueStatus any <optional>
Last known queue status (cached for reference)
Source:

CollectionsListingInput

Type:
  • Object
Properties:
Name Type Description
session any
query Record.<string, any>
body any
params Record.<string, any>
Source:

ControllerFunction()

Source:

DataFieldSpec

Type:
  • Object
Properties:
Name Type Attributes Description
path string JSON path expression
alias string Column alias name
query boolean <optional>
Use JSON_QUERY instead of JSON_VALUE
Source:

DatabaseObject

Type:
  • Object
Properties:
Name Type Attributes Description
UID Buffer The unique identifier as a Buffer
UIDBelongsTo Buffer The parent object identifier as a Buffer
Type string The object type
Title string <optional>
Optional title for the object
Source:

DatabaseQueryOptions

Type:
  • Object
Properties:
Name Type Attributes Description
log boolean <optional>
Whether to log the query
cast Array.<string> <optional>
Fields to cast to JSON
batch boolean <optional>
Whether this is a batch operation
group function <optional>
Grouping function for results
Source:

EmailItem

Type:
  • Object
Properties:
Name Type Attributes Description
type string Email type (e.g., 'family', 'personal', 'secondary')
email string <optional>
Email address
Source:

EntryObject

Type:
  • Object
Properties:
Name Type Description
UID Buffer Entry unique identifier
UIDBelongsTo Buffer Parent object identifier
UIDList Buffer List identifier
UIDEntry Buffer Entry identifier
Type string Object type
Data Object Entry data
Source:

EventLogConnection

A database connection capable of executing statements (either the transaction connection wrapper from @commtool/sql-query or the default pool).
Type:
  • Object
Properties:
Name Type Description
query function
Source:

ExpressRequest

Type:
  • Object
Properties:
Name Type Attributes Description
params any <optional>
Route parameters
query any <optional>
Query string parameters
body any <optional>
Request body
method string <optional>
HTTP method
url string <optional>
Request URL
headers any <optional>
Request headers
user any <optional>
Authenticated user object
session SessionData <optional>
Session data
Source:

ExpressRequestAuthorized

Type:
  • Object
Properties:
Name Type Attributes Description
params any <optional>
Route parameters
query any <optional>
Query string parameters
body any <optional>
Request body
method string <optional>
HTTP method
url string <optional>
Request URL
headers any <optional>
Request headers
user Object <optional>
Authenticated user object
session Object Session data (guaranteed to exist for authorized requests)
Properties
Name Type Attributes Description
root string The root organization UUID
user string The database member UUID
baseUser string <optional>
The base user UUID
loginOrga string <optional>
The login organization UUID from token
authUser any <optional>
Authenticated user from bearer token
sysUser string <optional>
System user UID (often used as organization/system admin)
save function Save session data
destroy function Destroy session
Source:

ExpressResponse

Type:
  • Object
Properties:
Name Type Description
status function Set status code
json function Send JSON response
send function Send response
set function Set header
end function End response
Source:

FamilyMemberObject

Type:
  • Object
Properties:
Name Type Attributes Description
UID Buffer Member unique identifier
Type 'person' | 'extern' | 'family' Object type (required)
Data Object Member data object (required)
Properties
Name Type Attributes Description
address Array.<AddressItem> <optional>
Address array
email Array.<EmailItem> <optional>
Email array
phone Array.<PhoneItem> <optional>
Phone array
accounts Array.<AccountItem> <optional>
Account array
Touched Array.<string> <optional>
Names of the shared fields the caller actually supplied (from the write patch). Only those are reconciled with removal — see `adjustMemberData`. Omit for full-database sources (then nothing is removed).
Source:

FilterAction

Type:
  • 'visible' | 'changeable' | 'include' | 'exclude' | 'intersect'
Source:

FilterData

Type:
  • Object
Properties:
Name Type Attributes Description
UID string Filter unique identifier
Type string Filter type (include, exclude, intersect)
Data any Filter configuration
SourceType string <optional>
Source type (group, list, etc.)
listUID string <optional>
Associated list UID
Source:

FilterObject

Type:
  • Object
Properties:
Name Type Description
UID Buffer The filter unique identifier
Type string Filter type ('include', 'exclude', 'intersect')
Data Object Filter configuration data
Source:

FilterOptions

Type:
  • Object
Properties:
Name Type Attributes Default Description
virtual boolean <optional>
false Whether this is a virtual operation (no permanent changes)
connection any <optional>
null Database connection for transactions
Source:

LinkDecision

Type:
  • Object
Properties:
Name Type Description
keep Array.<any> the links that survive (at most one, none on a skip)
remove Array.<any> the links to delete
skipReason string | null set when a human has to decide
Source:

LoggerOptions

Type:
  • Object
Properties:
Name Type Attributes Description
maxSize string <optional>
Maximum size per log file (e.g., '20M')
interval string <optional>
Time interval for rotation (e.g., '1d', '1h')
path string <optional>
Directory path for logs
maxFiles number <optional>
Number of files to retain
Source:

MemberData

Type:
  • Object
Properties:
Name Type Attributes Description
UID Buffer | string Member unique identifier
UIDBelongsTo Buffer | string Parent object identifier
Type string Object type
Data any Member data
Title string <optional>
Optional title
new boolean <optional>
Whether this is a new entry
Source:

OrganizationData

Type:
  • Object
Properties:
Name Type Attributes Description
UID string Organization unique identifier
name string Organization name
data any <optional>
Additional organization data
Source:

PersonListItem

Type:
  • Object
Properties:
Name Type Attributes Description
UID string Object UID (UUID string)
Type PersonType Object type
UIDBelongsTo string Parent person UID
Title string | null Title / role label
Display string Member display name
SortName string Sort key
UIDgroup string | null Primary group UID
pGroup string | null Primary group display label
hierarchie number | null Hierarchy level
stage number | null Stage / level
gender string | null Gender
dindex number | null Display index
visibility 'visible' | 'changeable' <optional>
Visibility type
Source:

PersonType

Type:
  • 'person' | 'guest' | 'extern' | 'family' | 'job' | 'entry' | 'eventJob'
Source:

PhoneItem

Type:
  • Object
Properties:
Name Type Attributes Description
type string Phone type (e.g., 'family', 'personal', 'secondary')
number string <optional>
Phone number
Source:

PublishEventOptions

Type:
  • Object
Properties:
Name Type Attributes Default Description
organization string The organization UUID for multi-tenant scoping
data Array.<any> | any The event data payload
backDate number <optional>
Unix timestamp for backdated events
eventLog boolean <optional>
true Whether to also persist the event to eventLog
Source:

ReleaseSource

Type:
  • 'override' | 'current'
Source:

ServiceResult

Type:
  • Object
Properties:
Name Type Attributes Description
success boolean
result any <optional>
message string <optional>
status number <optional>
HTTP status to respond with (default 200)
Source:

ServiceResult

Type:
  • Object
Properties:
Name Type Attributes Description
success boolean Whether the operation was successful
result any <optional>
Result data if successful
error any <optional>
Error message if unsuccessful
UIDaction string <optional>
Action UID for some operations
Source:

SessionData

Type:
  • Object
Properties:
Name Type Attributes Description
root string <optional>
The root organization UUID
user string <optional>
The database member UUID
baseUser string <optional>
The base user UUID
loginOrga string <optional>
The login organization UUID from token
sysUser string <optional>
System user UID (often used as organization/system admin)
authUser any <optional>
Authenticated user from bearer token (groups, orgRoles, etc.)
save function Save session data
destroy function Destroy session
regenerate function Regenerate session ID
reload function Reload session data
Source:

ShareType

Type:
  • 'repositoryShare' | 'directoryShare'
Source:

SocketIOServer

Socket.IO server instance used to register connection handlers and emit to rooms.
Type:
  • Object
Source:

SocketIOSocket

Represents a single connected Socket.IO client.
Type:
  • Object
Properties:
Name Type Description
request Object Underlying HTTP upgrade request (contains session, headers)
data Object Per-socket mutable storage set by connection handler
Properties
Name Type Description
connectID string Base64-encoded socketID used as key in clientDataStore
user string userUID of the authenticated user
userInfo Object Full decoded token payload
root string Current organisation UID (may be updated via setRoot)
rootHex Buffer Hex-encoded root for fast comparisons
transaction boolean Whether a bulk-transaction is in progress
id string Internal Socket.IO connection ID
connected boolean Whether the socket is currently connected
emit function Emit an event to this client
join function Join a Socket.IO room
disconnect function Forcefully close the connection
handshake Object Handshake information (headers, query, auth)
Source:

VisibleScope

Eine Sichtbarkeits-Zeile mit dem Typ des Objekts, an dem sie haengt. `UID` und `UIDUser` sind **kanonische Strings** (`UUID-…`), keine Rohbuffer: die Normalisierung passiert einmal an der Grenze, in loadVisibleScopes (`cast: ['UUID']`). Wer die Zeilen von Hand baut (die Rebuild-Pfade in `rebuildList.js`), muss dieselbe Form liefern — `asUuid` toleriert Buffer weiterhin, damit ein einzelner Aufrufer das nicht erzwingt.
Type:
  • Object
Properties:
Name Type Description
UID string das Objekt, an dem das Recht haengt
Type string das Level: `visible` | `changeable` | `admin`
UIDUser string die Person, die das Recht hat
ObjectType string `ObjectBase.Type` von `UID`
Source:

treeAction

The action object containing details about the operation to be performed.
Type:
  • Object
Source: