Dashboard zeigt Realdaten
Dieser Commit ist enthalten in:
@@ -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 = []
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren