First commit

This commit is contained in:
Saufi
2026-05-18 08:56:23 +08:00
commit fd3d3a4d2b
147 changed files with 22099 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
<?php
namespace App\Console\Commands;
use App\Services\Ollama\OllamaService;
use App\Services\Qdrant\QdrantService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/**
* php artisan kb:health-check
*
* Semak status semua perkhidmatan yang diperlukan.
*/
class HealthCheckCommand extends Command
{
protected $signature = 'kb:health-check';
protected $description = 'Semak status Ollama, Qdrant, dan MySQL';
public function handle(OllamaService $ollama, QdrantService $qdrant): int
{
$this->info('════════════════════════════════════════');
$this->info(' PEMERIKSAAN KESIHATAN SISTEM');
$this->info('════════════════════════════════════════');
$allOk = true;
// ── MySQL ─────────────────────────────────────────────────────────
$this->line('');
$this->info('📦 MySQL');
try {
DB::connection()->getPdo();
$dbName = DB::getDatabaseName();
$this->line(" ✅ Berjaya sambung ke: {$dbName}");
} catch (\Exception $e) {
$this->error(" ❌ Tidak dapat sambung: {$e->getMessage()}");
$allOk = false;
}
// ── Ollama ────────────────────────────────────────────────────────
$this->line('');
$this->info('🤖 Ollama');
$ollamaStatus = $ollama->healthCheck();
if ($ollamaStatus['online']) {
$this->line(" ✅ Online");
$chatOk = $ollamaStatus['chat_model'] ? '✅' : '❌';
$embedOk = $ollamaStatus['embed_model'] ? '✅' : '❌';
$this->line(" {$chatOk} Model Chat: " . config('ollama.chat_model'));
$this->line(" {$embedOk} Model Embed: " . config('ollama.embedding_model'));
if (!$ollamaStatus['chat_model'] || !$ollamaStatus['embed_model']) {
$allOk = false;
}
} else {
$this->error(" ❌ Offline");
if ($ollamaStatus['error']) {
$this->line(" " . $ollamaStatus['error']);
}
$allOk = false;
}
// ── Qdrant ────────────────────────────────────────────────────────
$this->line('');
$this->info('🗄️ Qdrant');
$qdrantStatus = $qdrant->healthCheck();
if ($qdrantStatus['online']) {
$this->line(" ✅ Online");
$collOk = $qdrantStatus['collection_exists'] ? '✅' : '⚠️ ';
$this->line(" {$collOk} Collection: " . config('qdrant.collection'));
if ($qdrantStatus['collection_exists']) {
$this->line(" 📊 Vectors: " . number_format($qdrantStatus['points_count'] ?? 0));
} else {
$this->warn(" Collection belum wujud. Akan dibuat secara automatik semasa pertama embed.");
}
} else {
$this->error(" ❌ Offline");
if ($qdrantStatus['error']) {
$this->line(" " . $qdrantStatus['error']);
}
$allOk = false;
}
// ── Queue ─────────────────────────────────────────────────────────
$this->line('');
$this->info('⏳ Queue');
$driver = config('queue.default');
$this->line(" Driver: {$driver}");
if ($driver === 'sync') {
$this->warn(" ⚠️ Queue driver adalah 'sync' — job akan dijalankan secara synchronous.");
$this->warn(" Tukar kepada 'database' atau 'redis' untuk production.");
} else {
$this->line(" ✅ Driver konfigurasi untuk async.");
}
// ── Ringkasan ─────────────────────────────────────────────────────
$this->line('');
$this->info('════════════════════════════════════════');
if ($allOk) {
$this->info(' ✅ SEMUA PERKHIDMATAN OK');
} else {
$this->error(' ❌ ADA PERKHIDMATAN YANG BERMASALAH');
}
$this->info('════════════════════════════════════════');
return $allOk ? self::SUCCESS : self::FAILURE;
}
}