-- Erstelle die fehlenden Resource Pool Tabellen -- Nur ausführen wenn die Tabellen noch nicht existieren -- Resource Pool Haupttabelle CREATE TABLE IF NOT EXISTS resource_pools ( id SERIAL PRIMARY KEY, resource_type VARCHAR(20) NOT NULL CHECK (resource_type IN ('domain', 'ipv4', 'phone')), resource_value VARCHAR(255) NOT NULL, status VARCHAR(20) DEFAULT 'available' CHECK (status IN ('available', 'allocated', 'quarantine')), allocated_to_license INTEGER REFERENCES licenses(id) ON DELETE SET NULL, status_changed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, status_changed_by VARCHAR(50), quarantine_reason VARCHAR(100) CHECK (quarantine_reason IN ('abuse', 'defect', 'maintenance', 'blacklisted', 'expired', 'review', NULL)), quarantine_until TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, notes TEXT, UNIQUE(resource_type, resource_value) ); -- Historie für Resource-Aktionen CREATE TABLE IF NOT EXISTS resource_history ( id SERIAL PRIMARY KEY, resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, license_id INTEGER REFERENCES licenses(id) ON DELETE SET NULL, action VARCHAR(50) NOT NULL CHECK (action IN ('allocated', 'deallocated', 'quarantined', 'released', 'created', 'deleted')), action_by VARCHAR(50) NOT NULL, action_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, details JSONB, ip_address TEXT ); -- Metriken für Resource Performance CREATE TABLE IF NOT EXISTS resource_metrics ( id SERIAL PRIMARY KEY, resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, metric_date DATE NOT NULL, usage_count INTEGER DEFAULT 0, performance_score DECIMAL(5,2) DEFAULT 0.00, cost DECIMAL(10,2) DEFAULT 0.00, revenue DECIMAL(10,2) DEFAULT 0.00, issues_count INTEGER DEFAULT 0, availability_percent DECIMAL(5,2) DEFAULT 100.00, UNIQUE(resource_id, metric_date) ); -- Zuordnungstabelle zwischen Lizenzen und Ressourcen CREATE TABLE IF NOT EXISTS license_resources ( id SERIAL PRIMARY KEY, license_id INTEGER REFERENCES licenses(id) ON DELETE CASCADE, resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, assigned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, assigned_by VARCHAR(50), is_active BOOLEAN DEFAULT TRUE, UNIQUE(license_id, resource_id) ); -- Erweiterung der licenses Tabelle um Resource-Counts DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'licenses' AND column_name = 'domain_count') THEN ALTER TABLE licenses ADD COLUMN domain_count INTEGER DEFAULT 1 CHECK (domain_count >= 0 AND domain_count <= 10), ADD COLUMN ipv4_count INTEGER DEFAULT 1 CHECK (ipv4_count >= 0 AND ipv4_count <= 10), ADD COLUMN phone_count INTEGER DEFAULT 1 CHECK (phone_count >= 0 AND phone_count <= 10); END IF; END $$; -- Indizes für Performance CREATE INDEX IF NOT EXISTS idx_resource_status ON resource_pools(status); CREATE INDEX IF NOT EXISTS idx_resource_type_status ON resource_pools(resource_type, status); CREATE INDEX IF NOT EXISTS idx_resource_allocated ON resource_pools(allocated_to_license) WHERE allocated_to_license IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_resource_quarantine ON resource_pools(quarantine_until) WHERE status = 'quarantine'; CREATE INDEX IF NOT EXISTS idx_resource_history_date ON resource_history(action_at DESC); CREATE INDEX IF NOT EXISTS idx_resource_history_resource ON resource_history(resource_id); CREATE INDEX IF NOT EXISTS idx_resource_metrics_date ON resource_metrics(metric_date DESC); CREATE INDEX IF NOT EXISTS idx_license_resources_active ON license_resources(license_id) WHERE is_active = TRUE; -- Prüfe ob Tabellen erfolgreich erstellt wurden DO $$ DECLARE table_count INT; BEGIN SELECT COUNT(*) INTO table_count FROM information_schema.tables WHERE table_schema = 'public' AND table_name IN ('resource_pools', 'resource_history', 'resource_metrics', 'license_resources'); IF table_count = 4 THEN RAISE NOTICE 'Alle 4 Resource-Tabellen wurden erfolgreich erstellt!'; ELSE RAISE WARNING 'Nur % von 4 Tabellen wurden erstellt!', table_count; END IF; END $$;