-- UTF-8 Encoding für deutsche Sonderzeichen sicherstellen SET client_encoding = 'UTF8'; CREATE TABLE IF NOT EXISTS customers ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, CONSTRAINT unique_email UNIQUE (email) ); CREATE TABLE IF NOT EXISTS licenses ( id SERIAL PRIMARY KEY, license_key TEXT UNIQUE NOT NULL, customer_id INTEGER REFERENCES customers(id), license_type TEXT NOT NULL, valid_from DATE NOT NULL, valid_until DATE NOT NULL, is_active BOOLEAN DEFAULT TRUE ); CREATE TABLE IF NOT EXISTS sessions ( id SERIAL PRIMARY KEY, license_id INTEGER REFERENCES licenses(id), session_id TEXT UNIQUE NOT NULL, ip_address TEXT, user_agent TEXT, started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP, ended_at TIMESTAMP, is_active BOOLEAN DEFAULT TRUE ); -- Audit-Log-Tabelle für Änderungsprotokolle CREATE TABLE IF NOT EXISTS audit_log ( id SERIAL PRIMARY KEY, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, username TEXT NOT NULL, action TEXT NOT NULL, entity_type TEXT NOT NULL, entity_id INTEGER, old_values JSONB, new_values JSONB, ip_address TEXT, user_agent TEXT, additional_info TEXT ); -- Index für bessere Performance bei Abfragen CREATE INDEX idx_audit_log_timestamp ON audit_log(timestamp DESC); CREATE INDEX idx_audit_log_username ON audit_log(username); CREATE INDEX idx_audit_log_entity ON audit_log(entity_type, entity_id); -- Backup-Historie-Tabelle CREATE TABLE IF NOT EXISTS backup_history ( id SERIAL PRIMARY KEY, filename TEXT NOT NULL, filepath TEXT NOT NULL, filesize BIGINT, backup_type TEXT NOT NULL, -- 'manual' oder 'scheduled' status TEXT NOT NULL, -- 'success', 'failed', 'in_progress' error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by TEXT NOT NULL, tables_count INTEGER, records_count INTEGER, duration_seconds NUMERIC, is_encrypted BOOLEAN DEFAULT TRUE ); -- Index für bessere Performance CREATE INDEX idx_backup_history_created_at ON backup_history(created_at DESC); CREATE INDEX idx_backup_history_status ON backup_history(status); -- Login-Attempts-Tabelle für Rate-Limiting CREATE TABLE IF NOT EXISTS login_attempts ( ip_address VARCHAR(45) PRIMARY KEY, attempt_count INTEGER DEFAULT 0, first_attempt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_attempt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, blocked_until TIMESTAMP NULL, last_username_tried TEXT, last_error_message TEXT ); -- Index für schnelle Abfragen CREATE INDEX idx_login_attempts_blocked_until ON login_attempts(blocked_until); CREATE INDEX idx_login_attempts_last_attempt ON login_attempts(last_attempt DESC);