Files
wevia-brain/s89-ai-apis/kb-sync-monitor.php
2026-04-12 23:01:36 +02:00

122 lines
6.0 KiB
PHP
Executable File

<?php
header('Content-Type: application/json');
// CORS locked by WAF shield
$pdo = new PDO('pgsql:host=localhost;dbname=adx_system','admin','admin123');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("SET search_path TO admin,public");
$action = $_GET['action'] ?? 'full_status';
switch($action) {
case 'full_status':
// Stats
$stats = [];
$stats['total_kb'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.knowledge_base")->fetchColumn();
$stats['total_conversations'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.claude_conversations_kb")->fetchColumn();
$stats['total_commonia'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.commonia_knowledge")->fetchColumn();
$stats['categories'] = (int)$pdo->query("SELECT COUNT(DISTINCT category) FROM admin.knowledge_base WHERE category IS NOT NULL AND category != ''")->fetchColumn();
$stats['today_synced'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.claude_conversations_kb WHERE last_synced_at::date = CURRENT_DATE")->fetchColumn();
// KB files
$files = [];
foreach (glob('/opt/wevads/hamid-files/kb_*.md') as $f) {
$title = trim(preg_replace('/^#+\s*/', '', fgets(fopen($f, 'r'))));
$files[] = [
'name' => basename($f),
'size' => round(filesize($f)/1024, 1) . ' KB',
'title' => $title,
'modified' => date('Y-m-d H:i', filemtime($f))
];
}
$stats['total_files'] = count($files);
// Pipeline counts
$pipeline = [
'files' => count($files),
'knowledge_base' => $stats['total_kb'],
'conversations_kb' => $stats['total_conversations'],
'commonia' => $stats['total_commonia'],
'sessions' => $stats['total_conversations']
];
// Conversations (claude_conversations_kb)
$conversations = $pdo->query("SELECT id, title, summary, category, importance_score, last_synced_at, created_at FROM admin.claude_conversations_kb ORDER BY id DESC LIMIT 100")->fetchAll(PDO::FETCH_ASSOC);
// Knowledge base
$knowledge = $pdo->query("SELECT id, title, category, LEFT(content,500) as content, source, created_at FROM admin.knowledge_base ORDER BY id DESC LIMIT 100")->fetchAll(PDO::FETCH_ASSOC);
// Commonia
$commonia = $pdo->query("SELECT id, type, title, category, LEFT(content,300) as content, question, LEFT(answer,300) as answer, priority, created_at FROM admin.commonia_knowledge ORDER BY id DESC LIMIT 100")->fetchAll(PDO::FETCH_ASSOC);
// Sync log
$logFile = '/var/log/wevads/claude_kb_sync.log';
$syncLog = file_exists($logFile) ? implode("\n", array_slice(file($logFile), -30)) : 'No log';
// Last sync
$lastSync = $pdo->query("SELECT MAX(last_synced_at) FROM admin.claude_conversations_kb")->fetchColumn();
// Cron check
$cronOut = shell_exec('crontab -l 2>/dev/null | grep kb-sync');
$cronActive = !empty(trim($cronOut ?? ''));
echo json_encode([
'stats' => $stats,
'pipeline' => $pipeline,
'conversations' => $conversations,
'knowledge' => $knowledge,
'commonia' => $commonia,
'files' => $files,
'sync_log' => $syncLog,
'last_sync' => $lastSync,
'cron_active' => $cronActive
]);
break;
case 'sync':
// Run the sync
$log = "/var/log/wevads/claude_kb_sync.log";
@mkdir(dirname($log), 0755, true);
$results = [];
// Step 1: KB files -> knowledge_base
$synced = 0;
foreach (glob('/opt/wevads/hamid-files/kb_*.md') as $f) {
$bn = basename($f, '.md');
$title = trim(preg_replace('/^#+\s*/', '', fgets(fopen($f, 'r'))));
$stmt = $pdo->prepare("SELECT COUNT(*) FROM admin.knowledge_base WHERE title LIKE ?");
$stmt->execute(["%{$bn}%"]);
if ($stmt->fetchColumn() == 0 && $title) {
$cat = explode('_', str_replace('kb_', '', $bn))[0];
$content = file_get_contents($f);
$ins = $pdo->prepare("INSERT INTO admin.knowledge_base (category, title, content, created_at) VALUES (?,?,?,NOW())");
$ins->execute([$cat, $title, substr($content, 0, 5000)]);
$synced++;
}
}
$results['new_kb_files'] = $synced;
// Step 2: knowledge_base -> claude_conversations_kb
$last = $pdo->query("SELECT COALESCE(MAX(created_at),'2020-01-01') FROM admin.claude_conversations_kb")->fetchColumn();
$stmt2 = $pdo->prepare("INSERT INTO admin.claude_conversations_kb (title, summary, category, importance_score, created_at, last_synced_at) SELECT LEFT(title,200), LEFT(content,1000), UPPER(COALESCE(NULLIF(category,''),'GENERAL')), CASE WHEN category IN ('infrastructure','framework','architecture') THEN 9 WHEN category IN ('operations','security','methods') THEN 8 ELSE 7 END, created_at, NOW() FROM admin.knowledge_base WHERE created_at > ? AND title IS NOT NULL AND title != '' ORDER BY created_at LIMIT 50");
$stmt2->execute([$last]);
$results['new_conversations'] = $stmt2->rowCount();
$results['total_conversations'] = (int)$pdo->query("SELECT COUNT(*) FROM admin.claude_conversations_kb")->fetchColumn();
// Step 3: -> commonia_knowledge
$lastComm = $pdo->query("SELECT COALESCE(MAX(created_at),'2020-01-01') FROM admin.commonia_knowledge WHERE type='claude_session'")->fetchColumn();
$stmt3 = $pdo->prepare("INSERT INTO admin.commonia_knowledge (type, category, title, content, priority, created_at) SELECT 'claude_session', LOWER(category), LEFT(title,200), LEFT(summary,500), importance_score, created_at FROM admin.claude_conversations_kb WHERE created_at > ? AND title IS NOT NULL ORDER BY created_at LIMIT 50 ON CONFLICT DO NOTHING");
$stmt3->execute([$lastComm]);
$results['new_commonia'] = $stmt3->rowCount();
$msg = date('Y-m-d H:i:s') . " SYNC: files={$results['new_kb_files']} convs={$results['new_conversations']} (total={$results['total_conversations']}) commonia={$results['new_commonia']}\n";
file_put_contents($log, $msg, FILE_APPEND);
echo json_encode(['success' => true, 'results' => $results]);
break;
default:
echo json_encode(['error' => 'Unknown action']);
}