import { NextResponse } from 'next/server' import { prisma } from '@/lib/prisma' import { redis } from '@/lib/redis' export const dynamic = 'force-dynamic' export async function GET() { const start = Date.now() const checks: Record = {} // Database check try { const dbStart = Date.now() const [noteCount, notebookCount, userCount] = await Promise.all([ prisma.note.count(), prisma.notebook.count(), prisma.user.count(), ]) checks.database = { status: 'healthy', latency: `${Date.now() - dbStart}ms`, notes: noteCount, notebooks: notebookCount, users: userCount, } } catch (e) { checks.database = { status: 'unhealthy', error: e instanceof Error ? e.message : 'Unknown error' } } // Redis check try { const redisStart = Date.now() await redis.ping() const info = await redis.info('memory') const dbSize = await redis.dbsize() const memMatch = info.match(/used_memory_human:(\S+)/) checks.redis = { status: 'healthy', latency: `${Date.now() - redisStart}ms`, keys: dbSize, memory: memMatch ? memMatch[1] : 'unknown', } } catch (e) { checks.redis = { status: 'unhealthy', error: e instanceof Error ? e.message : 'Unknown error' } } // AI providers check try { const { getSystemConfig } = await import('@/lib/config') const config = await getSystemConfig() const { resolveAiRoute } = await import('@/lib/ai/router') const tagsRoute = resolveAiRoute('tags', config) const chatRoute = resolveAiRoute('chat', config) checks.ai = { status: 'configured', embedding: { provider: tagsRoute.providerType, model: tagsRoute.modelName }, chat: { provider: chatRoute.providerType, model: chatRoute.modelName }, } } catch (e) { checks.ai = { status: 'unhealthy', error: e instanceof Error ? e.message : 'Unknown error' } } // Disk check try { const { execSync } = await import('child_process') const diskInfo = execSync("df -h /opt/memento | awk 'NR==2{print $2,$3,$4,$5}'").toString().trim() const [total, used, available, percent] = diskInfo.split(/\s+/) checks.storage = { status: parseInt(percent) > 90 ? 'warning' : 'healthy', total, used, available, usagePercent: percent, } } catch { checks.storage = { status: 'unknown' } } const allHealthy = Object.values(checks).every(c => c.status === 'healthy' || c.status === 'configured') const hasDegraded = Object.values(checks).some(c => c.status === 'warning') return NextResponse.json({ status: allHealthy ? (hasDegraded ? 'degraded' : 'healthy') : 'unhealthy', uptime: process.uptime(), version: process.env.npm_package_version || '0.2.0', timestamp: new Date().toISOString(), responseTime: `${Date.now() - start}ms`, components: checks, }, { status: allHealthy ? 200 : 503, }) }