lexguard-backend / scripts /system_diagnostic.js
github-actions[bot]
Deploy to Hugging Face
b921752
Raw
History Blame Contribute Delete
8.89 kB
require('dotenv').config();
const mongoose = require('mongoose');
const StatuteNode = require('../src/models/StatuteNode');
const CaseLaw = require('../src/models/CaseLaw');
const LegalDomainMap = require('../src/models/LegalDomainMap');
const { generateEmbedding } = require('../src/services/embeddingService');
const aiClient = require('../src/services/aiClient');
const color = {
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
reset: '\x1b[0m'
};
async function runDiagnostics() {
console.log(`\n${color.blue}======================================================${color.reset}`);
console.log(`${color.blue}🚀 LEXGUARD FULL SYSTEM DIAGNOSTIC AUDIT 🚀${color.reset}`);
console.log(`${color.blue}======================================================${color.reset}\n`);
const results = {
infrastructure: { passed: 0, failed: 0 },
database: { passed: 0, failed: 0 },
llm: { passed: 0, failed: 0 },
vectorSearch: { passed: 0, failed: 0 }
};
const assert = (condition, testName, category, errorMsg = '') => {
if (condition) {
console.log(`${color.green}✅ [PASS] ${testName}${color.reset}`);
results[category].passed++;
return true;
} else {
console.log(`${color.red}❌ [FAIL] ${testName}${color.reset}`);
if (errorMsg) console.log(` └─ ${color.yellow}${errorMsg}${color.reset}`);
results[category].failed++;
return false;
}
};
// ---------------------------------------------------------
// 1. INFRASTRUCTURE HEALTH
// ---------------------------------------------------------
console.log(`\n${color.blue}--- 1. Infrastructure & Environment ---${color.reset}`);
const requiredVars = ['MONGODB_URI', 'REDIS_URL', 'JWT_SECRET'];
const missingRequired = requiredVars.filter(v => !process.env[v]);
const apiKeys = ['GEMINI_API_KEY', 'GROQ_API_KEY', 'HUGGINGFACE_API_KEY'];
const hasAnyKey = apiKeys.some(v => process.env[v]);
const isLocal = process.env.LLM_PROVIDER === 'local' || process.env.FORCE_LOCAL_LLM === 'true';
const envOk = missingRequired.length === 0 && (hasAnyKey || isLocal);
let envNote = '';
if (missingRequired.length > 0) envNote += `Missing required: ${missingRequired.join(', ')}. `;
if (!hasAnyKey && !isLocal) envNote += `No LLM API keys provided and LLM_PROVIDER is not set to local.`;
assert(envOk, 'Environment Variables Loaded', 'infrastructure', envNote || `LLM Mode: ${isLocal ? 'Local/Mock' : 'Live Cascade'}`);
try {
await mongoose.connect(process.env.MONGODB_URI);
assert(true, 'MongoDB Atlas Connected', 'infrastructure');
} catch (e) {
assert(false, 'MongoDB Atlas Connected', 'infrastructure', e.message);
}
// ---------------------------------------------------------
// 2. DATABASE INTEGRITY
// ---------------------------------------------------------
console.log(`\n${color.blue}--- 2. Database & Accuracy Models ---${color.reset}`);
try {
const numStatutes = await StatuteNode.countDocuments();
assert(numStatutes >= 6000, `Statute Database Seeded (${numStatutes} nodes)`, 'database', 'Statutes count is lower than expected 6000+');
const bnsCount = await StatuteNode.countDocuments({ actName: /Bharatiya Nyaya Sanhita/i });
const bnssCount = await StatuteNode.countDocuments({ actName: /Bharatiya Nagarik Suraksha Sanhita/i });
const bsaCount = await StatuteNode.countDocuments({ actName: /Bharatiya Sakshya Adhiniyam/i });
assert(bnsCount > 0 && bnssCount > 0 && bsaCount > 0, `2023 Criminal Codes (BNS, BNSS, BSA) Ingested`, 'database', 'Missing one or more of the new 2023 criminal codes.');
const numCaseLaws = await CaseLaw.countDocuments();
assert(numCaseLaws >= 10, `Case Law Precedents Seeded (${numCaseLaws} precedents)`, 'database', 'Case Law precedents count is lower than expected.');
const numDomains = await LegalDomainMap.countDocuments();
assert(numDomains > 0, `Ontology Router Maps Seeded (${numDomains} maps)`, 'database', 'LegalDomainMap is empty.');
// Check Embedding Dimensionality (Phase 9 requirement)
const sampleStatute = await StatuteNode.findOne({ embedding: { $ne: null } });
if (sampleStatute) {
const dim = sampleStatute.embedding.length;
assert(dim === 1024, `Embeddings are 1024-dimensional (BGE-m3) [Found: ${dim}d]`, 'database', `Expected 1024d, but found ${dim}d`);
} else {
assert(false, 'Embeddings are 1024-dimensional', 'database', 'No embeddings found in the database.');
}
} catch (e) {
console.error(`${color.red}Error testing database: ${e.message}${color.reset}`);
}
// ---------------------------------------------------------
// 3. LLM API HEALTH & BACKOFF TESTING
// ---------------------------------------------------------
console.log(`\n${color.blue}--- 3. LLM Providers & Fallback Mechanisms ---${color.reset}`);
try {
const response = await aiClient.callLLM({ systemPrompt: "You are a test bot.", userContent: "Say 'Ping'", jsonMode: false });
const isLocal = process.env.LLM_PROVIDER === 'local' || process.env.FORCE_LOCAL_LLM === 'true';
if (isLocal) {
assert(response && typeof response === 'object', 'LLM Provider Configured (Local/Mock Mode)', 'llm');
} else {
assert(response && typeof response === 'string' && response.length > 0, 'LLM Cascade Routing Operational (Live API)', 'llm');
}
} catch (e) {
assert(false, 'LLM Cascade Routing Operational', 'llm', e.message);
}
// ---------------------------------------------------------
// 4. ATLAS VECTOR SEARCH HEALTH
// ---------------------------------------------------------
console.log(`\n${color.blue}--- 4. Atlas Vector Search Integration ---${color.reset}`);
try {
const queryVector = await generateEmbedding("employee termination protocol", "search_query");
assert(queryVector && queryVector.length === 1024, 'BGE-m3 Embedding Generation Successful', 'vectorSearch', 'Failed to generate 1024d embedding via BGE-m3.');
if (queryVector) {
const searchResults = await StatuteNode.aggregate([
{
$vectorSearch: {
index: "lexguard_statutes_vector_index",
path: "embedding",
queryVector: queryVector,
numCandidates: 10,
limit: 1
}
}
]);
assert(searchResults && searchResults.length > 0, '$vectorSearch Index is Active and Queryable', 'vectorSearch', 'Atlas $vectorSearch returned 0 results. Index might be building or misconfigured.');
}
} catch (e) {
assert(false, '$vectorSearch Index is Active and Queryable', 'vectorSearch', e.message);
}
// ---------------------------------------------------------
// 5. FRONTEND BUILD HEALTH
// ---------------------------------------------------------
console.log(`\n${color.blue}--- 5. Frontend Build Health ---${color.reset}`);
try {
const { execSync } = require('child_process');
execSync('npm run build', { cwd: '../frontend', stdio: 'ignore' });
assert(true, 'Vite React Build Compiled Successfully', 'infrastructure');
} catch (e) {
assert(false, 'Vite React Build Compiled Successfully', 'infrastructure', e.message);
}
// ---------------------------------------------------------
// SUMMARY
// ---------------------------------------------------------
console.log(`\n${color.blue}======================================================${color.reset}`);
console.log(`📊 DIAGNOSTIC SUMMARY`);
console.log(`${color.blue}======================================================${color.reset}`);
let allPassed = true;
for (const [category, stats] of Object.entries(results)) {
const total = stats.passed + stats.failed;
if (stats.failed > 0) allPassed = false;
const catColor = stats.failed === 0 ? color.green : color.red;
console.log(`- ${category.toUpperCase()}: ${catColor}${stats.passed}/${total} Passed${color.reset}`);
}
if (allPassed) {
console.log(`\n${color.green}🎉 ALL SYSTEMS OPERATIONAL. LexGuard architecture is fully robust and accurate.${color.reset}\n`);
} else {
console.log(`\n${color.red}⚠️ DIAGNOSTICS FAILED. One or more core systems are experiencing issues.${color.reset}\n`);
}
await mongoose.disconnect();
process.exit(allPassed ? 0 : 1);
}
runDiagnostics();