File size: 8,890 Bytes
b921752
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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();