Datenbank-Architektur¶
TCM365 verwendet PostgreSQL 15 als primäre Datenbank mit TypeORM 0.3 als ORM-Schicht. Das Datenbankdesign umfasst 35 Entities, Single Table Inheritance für Multi-Vendor-Support, Row-Level Security für Tenant-Isolation und Per-Tenant-Schemas für Data-Plane-Trennung.
Technology Stack¶
| Technologie | Version | Zweck |
|---|---|---|
| PostgreSQL | 15 | Relationale Datenbank-Engine |
| TypeORM | 0.3 | Object-Relational Mapping |
| uuid-ossp | Built-in | UUID-Generierung für Primärschlüssel |
| Row-Level Security | Built-in | Tenant-Level-Datenisolation |
Entity-Ueberblick¶
TCM365 definiert 35 TypeORM Entities in sechs funktionalen Kategorien. Alle Entities erweitern eine gemeinsame BaseEntity, die UUID-Primärschlüssel und Zeitstempel bereitstellt.
BaseEntity-Pattern¶
Jede Entity erbt von der gemeinsamen BaseEntity:
// backend-js/src/common/entities/base.entity.ts
import { PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
export abstract class BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
}
UUID-Primärschlüssel
TCM365 verwendet UUID v4 Primärschlüssel statt Auto-Increment-Integers. Dies verhindert ID-Enumerationsangriffe, unterstützt verteilte ID-Generierung und vermeidet Konflikte in Multi-Tenant-Schemas.
Entity-Katalog¶
Kern-Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
User |
users |
Anwendungsbenutzer mit lokaler/Azure AD Auth, RBAC-Rollen und Berechtigungen |
Group |
groups |
Benutzergruppen-Management mit rollenbasierten Mitgliedschaften |
InternalTenant |
internal_tenants |
Organisatorische Gruppierungen (Org-Level-Isolationsgrenze) |
Legacy Cleanup (v2.4.0)
Die m365_tenants-Tabelle wurde in v2.4.0 vollständig entfernt. Alle Foreign Keys wurden auf vendor_tenants migriert. Das frühere "Dual FK"-Pattern (sowohl m365_tenant_id als auch vendor_tenant_id) existiert nicht mehr.
Vendor Tenant-Hierarchie (Single Table Inheritance)¶
| Entity | Tabelle | Diskriminator | Beschreibung |
|---|---|---|---|
VendorTenant |
vendor_tenants |
Basis (abstrakt) | STI-Eltern-Entity mit gemeinsamen Spalten |
M365VendorTenant |
vendor_tenants |
microsoft |
Microsoft 365 Tenant mit M365-spezifischen Spalten |
ZscalerVendorTenant |
vendor_tenants |
zscaler |
Zscaler Tenant mit ZIA/ZPA-spezifischen Spalten |
AtlassianVendorTenant |
vendor_tenants |
atlassian |
Atlassian Cloud Tenant mit OAuth Tokens, Site-Info, Guard Tier (v2.5.0) |
Siehe den Abschnitt Single Table Inheritance (STI) weiter unten für Details.
Configuration Management Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
Snapshot |
snapshots |
Point-in-Time Konfigurationserfassungen |
Blueprint |
blueprints |
Konfigurationsvorlagen und Baselines |
BlueprintAnalysis |
blueprint_analyses |
KI-gestützte Analyseergebnisse für Blueprint-Einstellungen |
ConfigurationDrift |
configuration_drifts |
Erkannte Drift-Einträge zwischen Snapshots |
ConfigurationMonitor |
configuration_monitors |
Aktive Drift-Monitoring-Konfigurationen |
SeveritySuggestion |
severity_suggestions |
KI-basierte Severity-Anreicherung für Compliance-Regeln (v2.4.0) |
Operations Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
Workflow |
workflows |
Geplante Aufgabendefinitionen |
WorkflowExecution |
workflow_executions |
Aufgabenausfuehrungsprotokolle mit Status und Output |
RollbackHistory |
rollback_histories |
Rollback-Operationsprotokolle mit Pre/Post-State |
Anomaly Detection Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
AnomalyBaseline |
anomaly_baselines |
ML-basierte Anomalie-Detection-Baseline-Profile |
AnomalyEvent |
anomaly_events |
Erkannte Anomalie-Events mit Schweregrad und Kontext |
AnomalyMetric |
anomaly_metrics |
Zeitreihen-Anomalie-Detection-Metriken |
CustomProbe |
custom_probes |
Benutzerdefinierte Custom Monitoring Probe-Definitionen |
CustomProbeExecution |
custom_probe_executions |
Custom Probe-Ausfuehrungsergebnisse |
KRITIS/NIS2 Compliance Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
Incident |
incidents |
Sicherheitsvorfälle mit NIS2-Meldefristen |
RiskAssessment |
risk_assessments |
Risikobewertungen mit Wahrscheinlichkeits-/Auswirkungs-Scoring |
ChangeRequest |
change_requests |
Change Management Requests |
ChangeApproval |
change_approvals |
Approval Chain-Einträge für Change Requests |
ComplianceCheck |
compliance_checks |
Compliance-Bewertungsergebnisse über Frameworks |
BcdrTest |
bcdr_tests |
BC/DR-Testprotokolle mit RTO/RPO-Tracking |
AuditEvidence |
audit_evidences |
Audit-Nachweisartefakte für Compliance-Audits |
ReadinessAssessment |
readiness_assessments |
Copilot Readiness Assessment-Ergebnisse (44 Checks) |
Infrastruktur-Entities¶
| Entity | Tabelle | Beschreibung |
|---|---|---|
AuditLog |
audit_logs |
Unveränderliche Aktionsprotokolle (wer hat was wann getan) |
NotificationConfig |
notification_configs |
Benachrichtigungskanal-Konfigurationen |
NotificationLog |
notification_logs |
Benachrichtigungs-Zustellstatus-Einträge |
Report |
reports |
Generierte Report-Metadaten und Speicherreferenzen |
SystemSetting |
system_settings |
Systemweite Key-Value-Konfigurationseinstellungen |
UTCMQuotaUsage |
utcm_quota_usages |
UTCM API Quota-Nutzungsverfolgung pro Tenant |
Single Table Inheritance (STI)¶
Die vendor_tenants-Tabelle verwendet TypeORMs Single Table Inheritance-Pattern mit einer vendor-Diskriminatorspalte, um mehrere Vendor-Typen in einer Tabelle zu unterstützen.
STI-Struktur¶
vendor_tenants Tabelle
├── id (uuid, PK)
├── vendor (varchar) ─── Diskriminator: 'microsoft' | 'zscaler' | 'atlassian'
├── name (varchar)
├── org_id (uuid, FK → internal_tenants)
├── created_at (timestamp)
├── updated_at (timestamp)
│
├── [Microsoft-spezifische Spalten]
│ ├── tenant_id (varchar, nullable)
│ ├── domain (varchar, nullable)
│ ├── connection_type (varchar, nullable)
│ ├── enabled_workloads (jsonb, nullable)
│ ├── write_credentials (jsonb, nullable)
│ └── granted_permissions (jsonb, nullable)
│
├── [Zscaler-spezifische Spalten]
│ ├── zia_cloud (varchar, nullable)
│ ├── zia_api_key (varchar, nullable)
│ ├── zia_admin_username (varchar, nullable)
│ ├── zia_admin_password (varchar, nullable)
│ ├── zpa_customer_id (varchar, nullable)
│ ├── zpa_client_id (varchar, nullable)
│ ├── zpa_client_secret (varchar, nullable)
│ └── zpa_cloud (varchar, nullable)
│
└── [Atlassian-spezifische Spalten] (v2.5.0)
├── oauth_access_token (text, nullable)
├── oauth_refresh_token (text, nullable)
├── oauth_token_expires_at (timestamp, nullable)
├── site_id (varchar, nullable)
├── site_url (varchar, nullable)
├── site_name (varchar, nullable)
└── guard_tier (varchar, nullable)
TypeORM-Implementierung¶
// Basis-Entity
@Entity('vendor_tenants')
@TableInheritance({ column: { type: 'varchar', name: 'vendor' } })
export class VendorTenant extends BaseEntity {
@Column()
name: string;
@ManyToOne(() => InternalTenant)
@JoinColumn({ name: 'org_id' })
organization: InternalTenant;
}
// Microsoft Child-Entity
@ChildEntity('microsoft')
export class M365VendorTenant extends VendorTenant {
@Column({ name: 'tenant_id', nullable: true })
tenantId: string;
@Column({ nullable: true })
domain: string;
@Column({ name: 'enabled_workloads', type: 'jsonb', nullable: true })
enabledWorkloads: string[];
}
// Zscaler Child-Entity
@ChildEntity('zscaler')
export class ZscalerVendorTenant extends VendorTenant {
@Column({ name: 'zia_cloud', nullable: true })
ziaCloud: string;
@Column({ name: 'zia_api_key', nullable: true })
ziaApiKey: string;
// ... weitere ZIA/ZPA-Spalten
}
// Atlassian Child-Entity (v2.5.0)
@ChildEntity('atlassian')
export class AtlassianVendorTenant extends VendorTenant {
@Column({ name: 'site_id', nullable: true })
siteId: string;
@Column({ name: 'site_url', nullable: true })
siteUrl: string;
@Column({ name: 'guard_tier', nullable: true })
guardTier: string;
// ... weitere OAuth- und Site-Spalten
}
Neue Vendor hinzufügen
Neue Vendor werden durch Erstellen einer @ChildEntity hinzugefügt, die VendorTenant erweitert. Vendor-spezifische Spalten werden in derselben Tabelle mit nullable: true hinzugefügt. Keine neuen Tabellen erforderlich.
Row-Level Security (RLS)¶
PostgreSQL Row-Level Security stellt sicher, dass Anwendungsabfragen nur Daten zurueckgeben, die zur Organisation des authentifizierten Benutzers gehören -- selbst wenn Anwendungsebenen-Checks umgangen werden.
Zwei-Rollen-Architektur¶
| Rolle | RLS-Verhalten | Zweck |
|---|---|---|
tcm_admin |
BYPASSRLS |
Migrationen, Admin-Operationen, Schema-Verwaltung |
tcm_app |
Respektiert RLS | Anwendungsabfragen, benutzerseitige Operationen |
RLS-Policy-Pattern¶
-- RLS auf tenant-scoped Tabellen aktivieren
ALTER TABLE snapshots ENABLE ROW LEVEL SECURITY;
-- Policy: Benutzer sehen nur Daten ihrer Organisation
CREATE POLICY tenant_isolation ON snapshots
USING (org_id = current_setting('app.current_org_id')::uuid);
-- Die Anwendung setzt die Session-Variable vor jeder Abfrage
SET app.current_org_id = '<user-org-uuid>';
RLS-geschuetzte Tabellen¶
RLS-Policies werden auf 18 tenant-scoped Tabellen angewendet:
| Kategorie | Tabellen |
|---|---|
| Tenants | vendor_tenants |
| Config Management | snapshots, configuration_drifts, configuration_monitors, blueprints, blueprint_analyses |
| Operations | workflows, workflow_executions, rollback_histories |
| Compliance | incidents, risk_assessments, change_requests, compliance_checks, bcdr_tests, audit_evidences |
| Anomaly | anomaly_baselines, anomaly_events, custom_probes |
Schema-per-Tenant-Isolation¶
Über RLS hinaus bietet TCM365 physische Datentrennung für Data-Plane-Tabellen durch Per-Tenant PostgreSQL-Schemas.
Schema-Namenskonvention¶
public -- Gemeinsame Control-Plane-Tabellen (users, groups, system_settings)
tenant_{uuid} -- Per-Tenant Data-Plane-Tabellen (snapshots, drifts, monitors)
Beispiel: Eine Organisation mit ID a1b2c3d4-... erhält Schema tenant_a1b2c3d4.
Data-Plane-Tabellen (23 Tabellen pro Tenant-Schema)¶
Diese Tabellen werden in jedem Tenant-Schema dupliziert:
snapshots,configuration_drifts,configuration_monitorsworkflows,workflow_executions,rollback_historiesanomaly_baselines,anomaly_events,anomaly_metricscustom_probes,custom_probe_executionsblueprints,blueprint_analysesincidents,risk_assessments,change_requests,change_approvalscompliance_checks,bcdr_tests,audit_evidencesnotification_configs,reports,utcm_quota_usages
TenantSchemaManager¶
Der TenantSchemaManager-Service verwaltet den Schema-Lebenszyklus:
@Injectable()
export class TenantSchemaManager {
// Schema erstellen, wenn eine neue Organisation hinzugefügt wird
async createTenantSchema(orgId: string): Promise<void>;
// Migrationen auf einem bestimmten Tenant-Schema ausführen
async migrateTenantSchema(orgId: string): Promise<void>;
// Schema löschen, wenn eine Organisation entfernt wird
async dropTenantSchema(orgId: string): Promise<void>;
}
Migrations-Hinweise
Bei der Erstellung von Migrationen, die Data-Plane-Tabellen betreffen, muss die Migration sowohl das public-Schema (Vorlage) als auch alle bestehenden tenant_*-Schemas aktualisieren. Siehe Migration Troubleshooting für Anleitungen.
Entity-Beziehungen¶
Wichtige Beziehungen¶
erDiagram
InternalTenant ||--o{ VendorTenant : "hat viele"
InternalTenant ||--o{ User : "hat viele"
InternalTenant ||--o{ Group : "hat viele"
VendorTenant ||--o{ Snapshot : "hat viele"
VendorTenant ||--o{ ConfigurationDrift : "hat viele"
VendorTenant ||--o{ ConfigurationMonitor : "hat viele"
VendorTenant ||--o{ Workflow : "hat viele"
Snapshot ||--o{ ConfigurationDrift : "Quelle/Ziel"
ChangeRequest ||--o{ ChangeApproval : "hat viele"
User }o--|| InternalTenant : "gehört zu"
User }o--o{ Group : "Mitglied von"
Legacy Cleanup abgeschlossen (v2.4.0)
Ab v2.4.0 verwenden alle Entities ausschliesslich vendor_tenant_id als Fremdschluessel zur vendor_tenants-Tabelle. Die frühere m365_tenants-Tabelle und die zugehörigen m365_tenant_id-Spalten wurden vollständig entfernt.
Migrationen¶
TCM365 hat 32 TypeORM-Migrationen, die das vollständige Datenbankschema aufbauen.
Migrations-Befehle¶
cd backend-js
# Alle ausstehenden Migrationen ausführen
npm run migration:run
# Neue Migration aus Entity-Änderungen generieren
npm run migration:generate src/database/migrations/BeschreibenderName
# Letzte angewendete Migration zurücksetzen
npm run migration:revert
Migrations-Best-Practices¶
- Immer generieren, nie von Hand schreiben. Verwenden Sie
migration:generate, um Entity-Änderungen automatisch zu erkennen. - Beide Richtungen testen. Stellen Sie sicher, dass
up()unddown()beide funktional sind. - Tenant-Schemas aktualisieren. Data-Plane-Tabellenaenderungen müssen auf alle
tenant_*-Schemas angewendet werden. - snake_case für Spalten. TypeORM transformiert camelCase-Properties in snake_case-Spalten.
- Standard nullable für neue Spalten. Vermeiden Sie das Brechen bestehender Daten mit NOT NULL-Constraints auf neuen Spalten.
DataSource-Konfiguration¶
// backend-js/src/database/data-source.ts
export const AppDataSource = new DataSource({
type: 'postgres',
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 10),
username: process.env.DATABASE_USERNAME,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
entities: [__dirname + '/../entities/*.entity{.ts,.js}'],
migrations: [__dirname + '/migrations/*{.ts,.js}'],
synchronize: false, // Niemals true in der Produktion
logging: process.env.DATABASE_LOGGING === 'true',
});
Niemals Synchronize aktivieren
synchronize: true ändert das Datenbankschema bei jedem Start automatisch, um es an die Entities anzupassen. Dies kann zu Datenverlust in der Produktion führen. Verwenden Sie immer Migrationen.
JSONB-Spalten¶
TCM365 verwendet PostgreSQL JSONB-Spalten für flexible Metadatenspeicherung, wo Schema-Flexibilitaet benötigt wird:
| Entity | Spalte | Inhalt |
|---|---|---|
Snapshot |
data |
Vollständiger Konfigurationssnapshot (vendor-spezifisches JSON) |
M365VendorTenant |
enabled_workloads |
Array der aktivierten M365 Workloads |
M365VendorTenant |
write_credentials |
Verschluesselte Schreiboperations-Credentials |
M365VendorTenant |
granted_permissions |
Array der erteilten Graph API-Berechtigungen |
ConfigurationDrift |
changes |
Drift-Aenderungsdetails (Vorher/Nachher-Werte) |
ConfigurationMonitor |
resource_filters |
Ressourcentyp-Filter für Monitoring |
Blueprint |
configuration |
Blueprint-Konfigurationsvorlagendaten |
ComplianceCheck |
results |
Compliance-Bewertungsergebnisse pro Regel |
AnomalyBaseline |
baseline_data |
ML-berechnetes Baseline-Statistikmodell |
CustomProbe |
probe_config |
Custom Probe-Definition und Parameter |
Performance-Aspekte¶
Indexierungsstrategie¶
TCM365 erstellt Indizes auf häufig abgefragten Spalten:
- Fremdschluessel: Alle
org_id,vendor_tenant_id,m365_tenant_id-Spalten - Status-Spalten:
statusauf Snapshots, Workflows, Incidents - Zeitstempel:
created_atfür Zeitbereichsabfragen - Zusammengesetzt:
(org_id, vendor_tenant_id, created_at)für tenant-scoped Zeitabfragen
Abfrage-Patterns¶
- TypeORM Repository-Methoden (
find,findOne,save) statt roher Abfragen verwenden QueryBuilderfür komplexe Joins und Aggregationen nutzentakeundskipfür Paginierung verwenden (niemals unbegrenzte Ergebnismengen laden)ordernach Zeitstempel absteigend für Neueste-Zuerst-Abfragen anwenden
Datenbank-Diagnostik¶
TCM365 bietet integrierte Datenbankdiagnostik:
| Endpoint | Zweck |
|---|---|
GET /health |
Datenbank-Konnektivitaetspruefung mit Latenzmessung |
GET /api/v1/diagnostics |
Vollständige Datenbankgesundheit inkl. Migrationsstatus |
POST /api/v1/diagnostics/repair?action=run_migrations |
Ausstehende Migrationen über API ausführen |