Domänenmodell – Übersicht
Status: Entwurf · Spec-Kandidat: ja
Modellprinzip
- Metadaten relational (
DDM_ENTITY_TYPE,DDM_ENTITY_TYPE_ATTRIBUTE,DDM_RELATION_TYPE,DDM_ENUM_SET,DDM_ENUM_VALUE) - Flexible Attribute in JSONB (
DDM_ENTITY.attributes) - Echte Referenzen und Beziehungen relational (
DDM_ENTITY_RELATIONals typisierte Kantentabelle) - Soft Delete über
deleted_at-Timestamps - Volltextsuche über
tsvector(DDM_ENTITY.search_vector) - Erweiterbarkeit für Reporting (typisierte Views je
DDM_ENTITY_TYPE.key) und Enterprise-Ausbau
Damit bleibt SQL die führende Speicherebene; Flexibilität entsteht durch Metadaten, nicht durch dynamisches Schema.
Tabellen im Überblick
| Tabelle | Zweck |
|---|---|
DDM_ENTITY_TYPE | Definition fachlicher Typen (z. B. customer, service) |
DDM_ENTITY_TYPE_ATTRIBUTE | Attributdefinitionen je Entitätstyp |
DDM_ENTITY | Konkrete Stammdatensätze mit JSONB-Attributen |
DDM_RELATION_TYPE | Definition fachlicher Beziehungen mit Lösch-Policy |
DDM_ENTITY_RELATION | Konkrete Beziehungen zwischen Entitäten |
DDM_ENUM_SET / DDM_ENUM_VALUE | Wiederverwendbare Codelisten |
DDM_ENTITY_VERSION | Versions-Snapshots von Entitäten |
AA_AUDIT_LOG | Append-only-Änderungsprotokoll |
AA_APP_USER / AA_SERVICE_ACCOUNT | Identitäten (OIDC-gemappt bzw. M2M) |
AA_PRINCIPAL_GROUP / AA_PRINCIPAL_GROUP_MEMBER | Gruppierung von Identitäten |
AA_ROLE / AA_PERMISSION / AA_ROLE_PERMISSION | RBAC: Rollen + Permission-Zuweisung |
AA_PRINCIPAL_ROLE | Rollenzuweisung an Principal (mit Scope) |
AA_ACL_ENTRY | Feingranulare Allow/Deny-Regeln |
DDM_RELATION_TYPE_ATTRIBUTE | Attributdefinitionen je Beziehungstyp |
AA_TENANT | Mandant — Sichtbarkeits-/Isolationsgrenze |
AA_OUTBOX_EVENT | Transactional Outbox für Events / Webhooks |
ER-Diagramm
erDiagram ENTITY_TYPE ||--o{ ENTITY_TYPE_ATTRIBUTE : defines ENTITY_TYPE ||--o{ ENTITY : classifies ENTITY_TYPE ||--o{ RELATION_TYPE : source_type ENTITY_TYPE ||--o{ RELATION_TYPE : target_type
ENUM_SET ||--o{ ENUM_VALUE : contains ENUM_SET ||--o{ ENTITY_TYPE_ATTRIBUTE : used_by
RELATION_TYPE ||--o{ ENTITY_TYPE_ATTRIBUTE : backs_reference_attribute RELATION_TYPE ||--o{ ENTITY_RELATION : classifies
ENTITY ||--o{ ENTITY_RELATION : source ENTITY ||--o{ ENTITY_RELATION : target ENTITY ||--o{ ENTITY_VERSION : snapshots ENTITY ||--o{ AUDIT_LOG : affects
ENTITY_TYPE { uuid id PK text key UK text name boolean is_active integer version }
ENTITY_TYPE_ATTRIBUTE { uuid id PK uuid entity_type_id FK text key text label string data_type boolean required boolean searchable boolean filterable uuid enum_set_id FK uuid relation_type_id FK }
ENUM_SET { uuid id PK text key UK text name }
ENUM_VALUE { uuid id PK uuid enum_set_id FK text key text label integer sort_order }
RELATION_TYPE { uuid id PK text key UK uuid from_entity_type_id FK uuid to_entity_type_id FK string delete_policy }
ENTITY { uuid id PK uuid entity_type_id FK text code text name string status jsonb attributes tsvector search_vector integer version timestamptz deleted_at }
ENTITY_RELATION { uuid id PK uuid relation_type_id FK uuid from_entity_id FK uuid to_entity_id FK timestamptz valid_from timestamptz valid_to timestamptz deleted_at }
ENTITY_VERSION { uuid id PK uuid entity_id FK integer version_no jsonb snapshot }
AUDIT_LOG { bigint id PK text entity_name uuid entity_id string action timestamptz changed_at uuid actor_principal_id jsonb old_data jsonb new_data }RBAC + ACL (Identität und Rechte)
erDiagram APP_USER ||--o{ PRINCIPAL_GROUP_MEMBER : member_of SERVICE_ACCOUNT ||--o{ PRINCIPAL_GROUP_MEMBER : member_of PRINCIPAL_GROUP ||--o{ PRINCIPAL_GROUP_MEMBER : has_members PRINCIPAL_GROUP ||--o{ PRINCIPAL_ROLE : assigned
APP_USER ||--o{ PRINCIPAL_ROLE : assigned SERVICE_ACCOUNT ||--o{ PRINCIPAL_ROLE : assigned
ROLE ||--o{ PRINCIPAL_ROLE : grants ROLE ||--o{ ROLE_PERMISSION : has PERMISSION ||--o{ ROLE_PERMISSION : in
APP_USER ||--o{ ACL_ENTRY : overrides SERVICE_ACCOUNT ||--o{ ACL_ENTRY : overrides PRINCIPAL_GROUP ||--o{ ACL_ENTRY : overrides
ENTITY_TYPE ||--o{ ROLE_PERMISSION : scoped_by ENTITY ||--o{ ROLE_PERMISSION : scoped_by RELATION_TYPE ||--o{ ROLE_PERMISSION : scoped_by ENTITY_TYPE ||--o{ ACL_ENTRY : scoped_by ENTITY ||--o{ ACL_ENTRY : scoped_by RELATION_TYPE ||--o{ ACL_ENTRY : scoped_by
APP_USER { uuid id PK text external_id text issuer text email boolean is_active timestamptz deleted_at } SERVICE_ACCOUNT { uuid id PK text key UK text name boolean is_active } PRINCIPAL_GROUP { uuid id PK text key UK } PRINCIPAL_GROUP_MEMBER { uuid id PK uuid principal_group_id FK string member_principal_type uuid member_principal_id } ROLE { uuid id PK text key UK boolean is_system } PERMISSION { uuid id PK text key UK string action string scope boolean is_system } ROLE_PERMISSION { uuid id PK uuid role_id FK uuid permission_id FK string effect uuid scope_entity_type_id FK uuid scope_entity_id FK uuid scope_relation_type_id FK } PRINCIPAL_ROLE { uuid id PK string principal_type uuid principal_id uuid role_id FK string scope timestamptz valid_from timestamptz valid_to } ACL_ENTRY { uuid id PK string principal_type uuid principal_id string action string effect string scope text attribute_key timestamptz valid_from timestamptz valid_to }