File size: 3,225 Bytes
529090e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import 'dotenv/config';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import neo4j from 'neo4j-driver';

// ESM Shim
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Output sti til rapporten
const REPORT_PATH = path.resolve(__dirname, '../../../../docs/HOLOGRAPHIC_GAP_REPORT.json');

async function runHolographicAnalysis() {
  console.log('🌌 Operation Holographic Match: Initializing...');
  
  const uri = process.env.NEO4J_URI;
  const user = process.env.NEO4J_USER;
  const password = process.env.NEO4J_PASSWORD;

  if (!uri || !user || !password) {
    console.error('❌ FEJL: Mangler Neo4j credentials.');
    process.exit(1);
  }

  const driver = neo4j.driver(uri, neo4j.auth.basic(user, password));
  const session = driver.session();

  try {
    console.log('🧠 Connecting to Cortex...');
    
    // THE HOLOGRAPHIC QUERY (Fra Blackboardet)
    // Finder udbud (Tenders) hvor vi MANGLER koden (File content) til at løse opgaven
    // Bemærk: Denne query antager at t.keywords eksisterer på Tender noder.
    // Vores tidligere scripts har muligvis ikke sat denne property eksplicit på noden, men relationen har 'matches'.
    // Lad os justere queryen til at bruge relationen POTENTIAL_FIT's 'matches' property.
    
    const result = await session.run(`
      MATCH (org:Organization)-[f:POTENTIAL_FIT]->(t:Tender)
      // Unwind alle keywords fra 'matches' arrayet på relationen
      UNWIND f.matches as keyword
      WITH t, keyword, org
      // Tjek om vi har en fil der matcher dette keyword
      CALL {
        WITH keyword
        MATCH (file:File)
        WHERE toLower(file.name) CONTAINS toLower(keyword) 
           OR toLower(file.path) CONTAINS toLower(keyword)
        RETURN count(file) > 0 as hasCapability
      }
      WITH t, keyword, hasCapability
      WHERE NOT hasCapability
      // Aggreger manglende keywords per tender
      RETURN t.title as Title, 
             t.buyer as Buyer,
             'Gap Detected' as Status,
             t.url as Url,
             collect(keyword) as MissingKeywords
      LIMIT 20
    `);

    const gaps = result.records.map(r => ({
      title: r.get('Title'),
      buyer: r.get('Buyer'),
      status: r.get('Status'),
      url: r.get('Url'),
      missingKeywords: r.get('MissingKeywords'),
      recommendation: "INITIATE R&D SPRINT"
    }));

    console.log(`🔍 Analysis Complete. Found ${gaps.length} capability gaps.`);

    // Gem rapporten
    fs.writeFileSync(REPORT_PATH, JSON.stringify(gaps, null, 2));
    console.log(`📄 Report saved to: ${REPORT_PATH}`);

    if (gaps.length > 0) {
        console.log('\nTop 3 Missing Capabilities (Opportunities):');
        gaps.slice(0, 3).forEach((g, i) => {
            console.log(`${i+1}. ${g.title} (${g.buyer})`);
            console.log(`   Missing: ${g.missingKeywords.join(', ')}`);
        });
    } else {
        console.log('✨ No gaps found! We are fully synced with the market.');
    }

  } catch (error) {
    console.error('💥 Holographic Failure:', error);
  } finally {
    await session.close();
    await driver.close();
  }
}

runHolographicAnalysis();