Kunden & Lizenzen Fix

Dieser Commit ist enthalten in:
2025-06-19 19:14:33 +02:00
Ursprung b822504413
Commit afa2b52494
4 geänderte Dateien mit 73 neuen und 44 gelöschten Zeilen

Datei anzeigen

@@ -569,3 +569,25 @@ BEGIN
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
END IF; END IF;
END $$; END $$;
-- Migration: Add device_type column to device_registrations table
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'device_registrations' AND column_name = 'device_type') THEN
ALTER TABLE device_registrations ADD COLUMN device_type VARCHAR(50) DEFAULT 'unknown';
-- Update existing records to have a device_type based on operating system
UPDATE device_registrations
SET device_type = CASE
WHEN operating_system ILIKE '%windows%' THEN 'desktop'
WHEN operating_system ILIKE '%mac%' THEN 'desktop'
WHEN operating_system ILIKE '%linux%' THEN 'desktop'
WHEN operating_system ILIKE '%android%' THEN 'mobile'
WHEN operating_system ILIKE '%ios%' THEN 'mobile'
ELSE 'unknown'
END
WHERE device_type IS NULL OR device_type = 'unknown';
END IF;
END $$;

Datei anzeigen

@@ -0,0 +1,20 @@
-- Migration: Add device_type column to device_registrations table
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'device_registrations' AND column_name = 'device_type') THEN
ALTER TABLE device_registrations ADD COLUMN device_type VARCHAR(50) DEFAULT 'unknown';
-- Update existing records to have a device_type based on operating system
UPDATE device_registrations
SET device_type = CASE
WHEN operating_system ILIKE '%windows%' THEN 'desktop'
WHEN operating_system ILIKE '%mac%' THEN 'desktop'
WHEN operating_system ILIKE '%linux%' THEN 'desktop'
WHEN operating_system ILIKE '%android%' THEN 'mobile'
WHEN operating_system ILIKE '%ios%' THEN 'mobile'
ELSE 'unknown'
END
WHERE device_type IS NULL OR device_type = 'unknown';
END IF;
END $$;

Datei anzeigen

@@ -227,10 +227,12 @@ def get_license_devices(license_id):
}) })
return jsonify({ return jsonify({
'success': True,
'license_key': license_data['license_key'], 'license_key': license_data['license_key'],
'device_limit': license_data['device_limit'], 'device_limit': license_data['device_limit'],
'devices': devices, 'devices': devices,
'device_count': len(devices) 'device_count': len(devices),
'active_count': len([d for d in devices if d['is_active']])
}) })
except Exception as e: except Exception as e:
@@ -331,7 +333,7 @@ def deactivate_device(license_id, device_id):
cur.execute(""" cur.execute("""
SELECT dr.device_name, dr.hardware_id, l.license_key SELECT dr.device_name, dr.hardware_id, l.license_key
FROM device_registrations dr FROM device_registrations dr
JOIN licenses l ON dr.license_key = l.license_key JOIN licenses l ON dr.license_id = l.id
WHERE dr.id = %s AND l.id = %s WHERE dr.id = %s AND l.id = %s
""", (device_id, license_id)) """, (device_id, license_id))
@@ -398,7 +400,7 @@ def bulk_delete_licenses():
cur.execute("DELETE FROM sessions WHERE license_key = %s", (license_key,)) cur.execute("DELETE FROM sessions WHERE license_key = %s", (license_key,))
# Lösche Geräte-Registrierungen # Lösche Geräte-Registrierungen
cur.execute("DELETE FROM device_registrations WHERE license_key = %s", (license_key,)) cur.execute("DELETE FROM device_registrations WHERE license_id = %s", (license_id,))
# Lösche Lizenz # Lösche Lizenz
cur.execute("DELETE FROM licenses WHERE id = %s", (license_id,)) cur.execute("DELETE FROM licenses WHERE id = %s", (license_id,))
@@ -543,6 +545,7 @@ def get_license_resources(license_id):
grouped[res_type].append(resource) grouped[res_type].append(resource)
return jsonify({ return jsonify({
'success': True,
'license_key': license_data['license_key'], 'license_key': license_data['license_key'],
'resources': resources, 'resources': resources,
'grouped': grouped, 'grouped': grouped,

Datei anzeigen

@@ -318,7 +318,7 @@ def api_customer_licenses(customer_id):
if not customer: if not customer:
return jsonify({'error': 'Kunde nicht gefunden'}), 404 return jsonify({'error': 'Kunde nicht gefunden'}), 404
# Hole alle Lizenzen des Kunden # Hole alle Lizenzen des Kunden - vereinfachte Version ohne komplexe Subqueries
cur.execute(""" cur.execute("""
SELECT SELECT
l.id, l.id,
@@ -330,36 +330,18 @@ def api_customer_licenses(customer_id):
l.valid_until, l.valid_until,
l.device_limit, l.device_limit,
l.created_at, l.created_at,
(SELECT COUNT(*) FROM sessions s WHERE s.license_id = l.id AND s.is_active = true) as active_sessions,
(SELECT COUNT(DISTINCT hardware_id) FROM device_registrations dr WHERE dr.license_id = l.id) as registered_devices,
CASE CASE
WHEN l.valid_until < CURRENT_DATE THEN 'abgelaufen' WHEN l.valid_until < CURRENT_DATE THEN 'abgelaufen'
WHEN l.valid_until < CURRENT_DATE + INTERVAL '30 days' THEN 'läuft bald ab' WHEN l.valid_until < CURRENT_DATE + INTERVAL '30 days' THEN 'läuft bald ab'
WHEN l.is_active = false THEN 'inaktiv' WHEN l.is_active = false THEN 'inaktiv'
ELSE 'aktiv' ELSE 'aktiv'
END as status, END as status,
-- License Server Status COALESCE(l.domain_count, 0) as domain_count,
(SELECT COUNT(*) FROM license_heartbeats lh WHERE lh.license_id = l.id AND lh.timestamp > NOW() - INTERVAL '5 minutes') as recent_heartbeats, COALESCE(l.ipv4_count, 0) as ipv4_count,
(SELECT MAX(timestamp) FROM license_heartbeats lh WHERE lh.license_id = l.id) as last_heartbeat, COALESCE(l.phone_count, 0) as phone_count
(SELECT COUNT(DISTINCT hardware_id) FROM license_heartbeats lh WHERE lh.license_id = l.id AND lh.timestamp > NOW() - INTERVAL '15 minutes') as active_server_devices,
(SELECT COUNT(*) FROM anomaly_detections ad WHERE ad.license_id = l.id AND ad.resolved = false) as unresolved_anomalies,
l.domain_count,
l.ipv4_count,
l.phone_count,
(SELECT COUNT(*) FROM device_registrations WHERE license_id = l.id AND is_active = TRUE) as active_devices,
-- Actual resource counts
(SELECT COUNT(*) FROM license_resources lr
JOIN resource_pools rp ON lr.resource_id = rp.id
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'domain') as actual_domain_count,
(SELECT COUNT(*) FROM license_resources lr
JOIN resource_pools rp ON lr.resource_id = rp.id
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'ipv4') as actual_ipv4_count,
(SELECT COUNT(*) FROM license_resources lr
JOIN resource_pools rp ON lr.resource_id = rp.id
WHERE lr.license_id = l.id AND lr.is_active = true AND rp.resource_type = 'phone') as actual_phone_count
FROM licenses l FROM licenses l
WHERE l.customer_id = %s WHERE l.customer_id = %s
ORDER BY l.created_at DESC ORDER BY l.created_at DESC, l.id DESC
""", (customer_id,)) """, (customer_id,))
licenses = [] licenses = []
@@ -404,28 +386,28 @@ def api_customer_licenses(customer_id):
'id': row[0], 'id': row[0],
'license_key': row[1], 'license_key': row[1],
'license_type': row[2], 'license_type': row[2],
'is_active': row[3], # Korrigiert von 'is_active' zu 'is_active' 'is_active': row[3],
'is_test': row[4], 'is_test': row[4],
'valid_from': row[5].strftime('%Y-%m-%d') if row[5] else None, 'valid_from': row[5].strftime('%Y-%m-%d') if row[5] else None,
'valid_until': row[6].strftime('%Y-%m-%d') if row[6] else None, 'valid_until': row[6].strftime('%Y-%m-%d') if row[6] else None,
'device_limit': row[7], 'device_limit': row[7],
'created_at': row[8].strftime('%Y-%m-%d %H:%M:%S') if row[8] else None, 'created_at': row[8].strftime('%Y-%m-%d %H:%M:%S') if row[8] else None,
'active_sessions': row[9], 'status': row[9],
'registered_devices': row[10], 'domain_count': row[10],
'status': row[11], 'ipv4_count': row[11],
'domain_count': row[16], 'phone_count': row[12],
'ipv4_count': row[17], 'active_sessions': 0, # Platzhalter
'phone_count': row[18], 'registered_devices': 0, # Platzhalter
'active_devices': row[19], 'active_devices': 0, # Platzhalter
'actual_domain_count': row[20], 'actual_domain_count': len(resources['domains']),
'actual_ipv4_count': row[21], 'actual_ipv4_count': len(resources['ipv4s']),
'actual_phone_count': row[22], 'actual_phone_count': len(resources['phones']),
'resources': resources, 'resources': resources,
# License Server Data # License Server Data (Platzhalter bis Implementation)
'recent_heartbeats': row[12], 'recent_heartbeats': 0,
'last_heartbeat': row[13].strftime('%Y-%m-%d %H:%M:%S') if row[13] else None, 'last_heartbeat': None,
'active_server_devices': row[14], 'active_server_devices': 0,
'unresolved_anomalies': row[15] 'unresolved_anomalies': 0
}) })
return jsonify({ return jsonify({
@@ -439,8 +421,10 @@ def api_customer_licenses(customer_id):
}) })
except Exception as e: except Exception as e:
logging.error(f"Fehler beim Laden der Kundenlizenzen: {str(e)}") import traceback
return jsonify({'error': 'Fehler beim Laden der Daten'}), 500 error_msg = f"Fehler beim Laden der Kundenlizenzen: {str(e)}\nTraceback: {traceback.format_exc()}"
logging.error(error_msg)
return jsonify({'error': f'Fehler beim Laden der Daten: {str(e)}', 'details': error_msg}), 500
finally: finally:
cur.close() cur.close()
conn.close() conn.close()