/** * Communication Admin API Route - Stats Proxy * * Proxies requests to Matrix/Jitsi admin endpoints via backend * Aggregates statistics from both services */ import { NextRequest, NextResponse } from 'next/server' // Service URLs const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000' const CONSENT_SERVICE_URL = process.env.CONSENT_SERVICE_URL || 'http://localhost:8081' const MATRIX_ADMIN_URL = process.env.MATRIX_ADMIN_URL || 'http://localhost:8448' const JITSI_URL = process.env.JITSI_URL || 'http://localhost:8443' // Matrix Admin Token (for Synapse Admin API) const MATRIX_ADMIN_TOKEN = process.env.MATRIX_ADMIN_TOKEN || '' interface MatrixStats { total_users: number active_users: number total_rooms: number active_rooms: number messages_today: number messages_this_week: number status: 'online' | 'offline' | 'degraded' } interface JitsiStats { active_meetings: number total_participants: number meetings_today: number average_duration_minutes: number peak_concurrent_users: number total_minutes_today: number status: 'online' | 'offline' | 'degraded' } async function fetchFromBackend(): Promise<{ matrix: MatrixStats jitsi: JitsiStats active_meetings: unknown[] recent_rooms: unknown[] } | null> { try { const response = await fetch(`${BACKEND_URL}/api/v1/communication/admin/stats`, { headers: { 'Content-Type': 'application/json' }, signal: AbortSignal.timeout(5000), }) if (response.ok) { return await response.json() } } catch (error) { console.log('Backend not reachable, trying consent service:', error) } return null } async function fetchFromConsentService(): Promise<{ matrix: MatrixStats jitsi: JitsiStats active_meetings: unknown[] recent_rooms: unknown[] } | null> { try { const response = await fetch(`${CONSENT_SERVICE_URL}/api/v1/communication/admin/stats`, { headers: { 'Content-Type': 'application/json' }, signal: AbortSignal.timeout(5000), }) if (response.ok) { return await response.json() } } catch (error) { console.log('Consent service not reachable:', error) } return null } async function fetchMatrixStats(): Promise { try { // Check if Matrix is reachable const healthCheck = await fetch(`${MATRIX_ADMIN_URL}/_matrix/client/versions`, { signal: AbortSignal.timeout(5000) }) if (healthCheck.ok) { // Try to get user count from admin API if (MATRIX_ADMIN_TOKEN) { try { const usersResponse = await fetch(`${MATRIX_ADMIN_URL}/_synapse/admin/v2/users?limit=1`, { headers: { 'Authorization': `Bearer ${MATRIX_ADMIN_TOKEN}` }, signal: AbortSignal.timeout(5000), }) if (usersResponse.ok) { const data = await usersResponse.json() return { total_users: data.total || 0, active_users: 0, total_rooms: 0, active_rooms: 0, messages_today: 0, messages_this_week: 0, status: 'online' } } } catch { // Admin API not available } } return { total_users: 0, active_users: 0, total_rooms: 0, active_rooms: 0, messages_today: 0, messages_this_week: 0, status: 'degraded' // Server reachable but no admin access } } } catch (error) { console.error('Matrix stats fetch error:', error) } return { total_users: 0, active_users: 0, total_rooms: 0, active_rooms: 0, messages_today: 0, messages_this_week: 0, status: 'offline' } } async function fetchJitsiStats(): Promise { try { // Check if Jitsi is reachable const healthCheck = await fetch(`${JITSI_URL}/http-bind`, { method: 'HEAD', signal: AbortSignal.timeout(5000) }) return { active_meetings: 0, total_participants: 0, meetings_today: 0, average_duration_minutes: 0, peak_concurrent_users: 0, total_minutes_today: 0, status: healthCheck.ok ? 'online' : 'offline' } } catch (error) { console.error('Jitsi stats fetch error:', error) return { active_meetings: 0, total_participants: 0, meetings_today: 0, average_duration_minutes: 0, peak_concurrent_users: 0, total_minutes_today: 0, status: 'offline' } } } export async function GET(request: NextRequest) { try { // Try backend first let data = await fetchFromBackend() // Fallback to consent service if (!data) { data = await fetchFromConsentService() } // If both fail, try direct service checks if (!data) { const [matrixStats, jitsiStats] = await Promise.all([ fetchMatrixStats(), fetchJitsiStats() ]) data = { matrix: matrixStats, jitsi: jitsiStats, active_meetings: [], recent_rooms: [] } } return NextResponse.json({ ...data, last_updated: new Date().toISOString() }) } catch (error) { console.error('Communication stats error:', error) return NextResponse.json( { error: 'Fehler beim Abrufen der Statistiken', matrix: { status: 'offline', total_users: 0, active_users: 0, total_rooms: 0, active_rooms: 0, messages_today: 0, messages_this_week: 0 }, jitsi: { status: 'offline', active_meetings: 0, total_participants: 0, meetings_today: 0, average_duration_minutes: 0, peak_concurrent_users: 0, total_minutes_today: 0 }, active_meetings: [], recent_rooms: [], last_updated: new Date().toISOString() }, { status: 503 } ) } }