diff --git a/v2_adminpanel/routes/admin_routes.py b/v2_adminpanel/routes/admin_routes.py index 116fdc8..39b204a 100644 --- a/v2_adminpanel/routes/admin_routes.py +++ b/v2_adminpanel/routes/admin_routes.py @@ -24,14 +24,21 @@ def dashboard(): cur = conn.cursor() try: # Hole Statistiken mit sicheren Defaults - # Anzahl aktiver Lizenzen - cur.execute("SELECT COUNT(*) FROM licenses WHERE is_active = true") + # Anzahl aktiver Lizenzen (nur echte Daten, keine Testdaten) + cur.execute("SELECT COUNT(*) FROM licenses WHERE is_active = true AND is_test = false") active_licenses = cur.fetchone()[0] if cur.rowcount > 0 else 0 - # Anzahl Kunden - cur.execute("SELECT COUNT(*) FROM customers") + # Anzahl Kunden (nur echte Kunden, keine Testkunden) + cur.execute("SELECT COUNT(*) FROM customers WHERE is_test = false") total_customers = cur.fetchone()[0] if cur.rowcount > 0 else 0 + # Testdaten separat zählen für optionale Anzeige + cur.execute("SELECT COUNT(*) FROM customers WHERE is_test = true") + test_customers_count = cur.fetchone()[0] if cur.rowcount > 0 else 0 + + cur.execute("SELECT COUNT(*) FROM licenses WHERE is_test = true") + test_licenses_count = cur.fetchone()[0] if cur.rowcount > 0 else 0 + # Anzahl aktiver Sessions (Admin-Panel) cur.execute("SELECT COUNT(*) FROM sessions WHERE is_active = true") active_sessions = cur.fetchone()[0] if cur.rowcount > 0 else 0 @@ -50,9 +57,11 @@ def dashboard(): if table_exists: cur.execute(""" - SELECT COUNT(DISTINCT license_id) - FROM license_heartbeats - WHERE timestamp > NOW() - INTERVAL '15 minutes' + SELECT COUNT(DISTINCT lh.license_id) + FROM license_heartbeats lh + JOIN licenses l ON l.id = lh.license_id + WHERE lh.timestamp > NOW() - INTERVAL '15 minutes' + AND l.is_test = false """) active_usage = cur.fetchone()[0] if cur.rowcount > 0 else 0 except Exception as e: @@ -64,7 +73,7 @@ def dashboard(): conn = get_connection() cur = conn.cursor() - # Top 10 Lizenzen - vereinfacht + # Top 10 Lizenzen - nur echte Lizenzen cur.execute(""" SELECT l.license_key, @@ -73,6 +82,7 @@ def dashboard(): FROM licenses l LEFT JOIN customers c ON l.customer_id = c.id LEFT JOIN sessions s ON l.id = s.license_id + WHERE l.is_test = false AND c.is_test = false GROUP BY l.license_key, c.name ORDER BY session_count DESC LIMIT 10 @@ -93,54 +103,157 @@ def dashboard(): """) recent_activities = cur.fetchall() if cur.rowcount > 0 else [] + # Lizenztypen zählen (nur echte Lizenzen) + # Note: This assumes you have a license_type field or similar to distinguish between full and test versions + # For now, counting all non-test licenses as full licenses + cur.execute(""" + SELECT COUNT(*) as full_licenses + FROM licenses + WHERE is_test = false + """) + license_count = cur.fetchone() + full_licenses = license_count[0] if license_count and license_count[0] else 0 + # For now, we don't distinguish between full and test versions + test_version_licenses = 0 + + # Lizenzstatus zählen (nur echte Lizenzen) + cur.execute(""" + SELECT + COUNT(CASE WHEN is_active = true AND (valid_until IS NULL OR valid_until > NOW()) THEN 1 END) as active, + COUNT(CASE WHEN valid_until < NOW() THEN 1 END) as expired, + COUNT(CASE WHEN is_active = false THEN 1 END) as inactive + FROM licenses + WHERE is_test = false + """) + license_status = cur.fetchone() + active_licenses_count = license_status[0] if license_status and license_status[0] else 0 + expired_licenses = license_status[1] if license_status and license_status[1] else 0 + inactive_licenses = license_status[2] if license_status and license_status[2] else 0 + + # Bald ablaufende Lizenzen (nur echte Lizenzen) + cur.execute(""" + SELECT + l.id, + l.license_key, + c.name as customer_name, + l.valid_until, + EXTRACT(DAY FROM (l.valid_until - NOW())) as days_remaining + FROM licenses l + JOIN customers c ON l.customer_id = c.id + WHERE l.is_test = false + AND c.is_test = false + AND l.is_active = true + AND l.valid_until IS NOT NULL + AND l.valid_until > NOW() + AND l.valid_until < NOW() + INTERVAL '30 days' + ORDER BY l.valid_until ASC + LIMIT 10 + """) + expiring_licenses = cur.fetchall() if cur.rowcount > 0 else [] + + # Zuletzt erstellte Lizenzen (nur echte Lizenzen) + cur.execute(""" + SELECT + l.id, + l.license_key, + c.name as customer_name, + l.created_at, + CASE + WHEN l.is_active = false THEN 'deaktiviert' + WHEN l.valid_until < NOW() THEN 'abgelaufen' + WHEN l.valid_until < NOW() + INTERVAL '30 days' THEN 'läuft bald ab' + ELSE 'aktiv' + END as status + FROM licenses l + JOIN customers c ON l.customer_id = c.id + WHERE l.is_test = false + AND c.is_test = false + ORDER BY l.created_at DESC + LIMIT 5 + """) + recent_licenses = cur.fetchall() if cur.rowcount > 0 else [] + # Stats Objekt für Template erstellen stats = { 'total_customers': total_customers, - 'total_licenses': active_licenses, + 'total_licenses': active_licenses, # This was already filtered for is_test = false 'active_sessions': active_sessions, # Admin-Panel Sessions 'active_usage': active_usage, # Aktive Kunden-Nutzung - 'active_licenses': active_licenses, - 'full_licenses': 0, - 'test_licenses': 0, - 'test_data_count': 0, - 'test_customers_count': 0, + 'active_licenses': active_licenses_count, + 'full_licenses': full_licenses, + 'test_licenses': test_version_licenses, # Test versions, not test data + 'test_data_count': test_licenses_count, # Actual test data count + 'test_customers_count': test_customers_count, 'test_resources_count': 0, - 'expired_licenses': 0, - 'inactive_licenses': 0, + 'expired_licenses': expired_licenses, + 'inactive_licenses': inactive_licenses, 'last_backup': None, 'security_level': 'success', 'security_level_text': 'Sicher', 'blocked_ips_count': 0, 'failed_attempts_today': 0, 'recent_security_events': [], - 'expiring_licenses': [], - 'recent_licenses': [] + 'expiring_licenses': expiring_licenses, + 'recent_licenses': recent_licenses } - # Resource stats als Dictionary mit allen benötigten Feldern - resource_stats = { - 'domain': { - 'available': 0, - 'allocated': 0, - 'quarantine': 0, - 'total': 0, - 'available_percent': 100 - }, - 'ipv4': { - 'available': 0, - 'allocated': 0, - 'quarantine': 0, - 'total': 0, - 'available_percent': 100 - }, - 'phone': { - 'available': 0, - 'allocated': 0, - 'quarantine': 0, - 'total': 0, - 'available_percent': 100 - } - } + # Resource Pool Statistics (nur echte Ressourcen, keine Testdaten) + resource_stats = {} + resource_types = ['domain', 'ipv4', 'phone'] + + for resource_type in resource_types: + try: + cur.execute(""" + SELECT + COUNT(CASE WHEN status = 'available' THEN 1 END) as available, + COUNT(CASE WHEN status = 'allocated' THEN 1 END) as allocated, + COUNT(CASE WHEN status = 'quarantine' THEN 1 END) as quarantine, + COUNT(*) as total + FROM resource_pool + WHERE type = %s AND is_test = false + """, (resource_type,)) + + result = cur.fetchone() + if result: + available = result[0] or 0 + allocated = result[1] or 0 + quarantine = result[2] or 0 + total = result[3] or 0 + available_percent = int((available / total * 100)) if total > 0 else 0 + + resource_stats[resource_type] = { + 'available': available, + 'allocated': allocated, + 'quarantine': quarantine, + 'total': total, + 'available_percent': available_percent + } + else: + resource_stats[resource_type] = { + 'available': 0, + 'allocated': 0, + 'quarantine': 0, + 'total': 0, + 'available_percent': 0 + } + except Exception as e: + # Falls die Tabelle nicht existiert + current_app.logger.warning(f"Could not get resource stats for {resource_type}: {str(e)}") + resource_stats[resource_type] = { + 'available': 0, + 'allocated': 0, + 'quarantine': 0, + 'total': 0, + 'available_percent': 0 + } + + # Count test resources separately + try: + cur.execute("SELECT COUNT(*) FROM resource_pool WHERE is_test = true") + test_resources_count = cur.fetchone()[0] if cur.rowcount > 0 else 0 + stats['test_resources_count'] = test_resources_count + except: + pass license_distribution = [] hourly_sessions = []