Files
boc/vims-backend/demo/reality-alert-full-demo.js
T
Bernt 6de2455917 v1.2.0: Add Global Markets footer, translated to 9 languages
- Added GLOBAL_MARKETS_TITLE to all translation files
- Updated footer with 12 markets (4 active + 8 upcoming)
- Translated market section to: zh-cn, zh-tw, ja, ko, th, vi, id, ms, hi
- Built and deployed to production
- CloudFront invalidation: I3RTMXVFDJXWLG3SYX208OP1CC
2026-07-08 19:56:03 +00:00

215 lines
6.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Reality Alert™ Full Demo
* Demonstrates complete pipeline with simulated AI responses
*/
const { RealityAlertService, ALERT_SEVERITY, ALERT_CATEGORIES } = require('../src/services/realityAlert');
// Mock the AI services for demo
class MockObjectDetectionService {
async detect(imageSource, options) {
// Simulate detection based on image URL hints
const url = imageSource.toString();
if (url.includes('diesel')) {
return {
objects: [
{ type: 'pump_station', confidence: 0.92 },
{ type: 'spill', confidence: 0.87 }
],
confidence: 0.92,
objectId: 'pump-station-001'
};
}
if (url.includes('missing')) {
return {
objects: [
{ type: 'manhole', confidence: 0.78 }
],
confidence: 0.78,
objectId: 'manhole-123'
};
}
if (url.includes('ice')) {
return {
objects: [
{ type: 'heat_pump', confidence: 0.85 },
{ type: 'ice_formation', confidence: 0.91 }
],
confidence: 0.91,
objectId: 'heatpump-456'
};
}
return {
objects: [{ type: 'unknown', confidence: 0.3 }],
confidence: 0.3,
objectId: null
};
}
}
class MockChangeDetectionService {
async compare(imageSource, options) {
const url = imageSource.toString();
if (url.includes('diesel')) {
return {
anomalies: [{
type: 'spill',
severity: 'critical',
description: 'Diesel spill detected near pump station',
confidence: 0.87
}],
comparison: { overallDifference: 0.45 }
};
}
if (url.includes('missing')) {
return {
anomalies: [{
type: 'missing',
severity: 'high',
description: 'Manhole cover missing',
confidence: 0.78
}],
comparison: { overallDifference: 0.32 }
};
}
if (url.includes('ice')) {
return {
anomalies: [{
type: 'ice_formation',
severity: 'medium',
description: 'Excessive ice formation on heat pump',
confidence: 0.91
}],
comparison: { overallDifference: 0.28 }
};
}
return {
anomalies: [],
comparison: { overallDifference: 0.05 }
};
}
}
class MockRiskClassifierService {
classify(analysis) {
const anomalies = analysis.changes?.anomalies || [];
if (anomalies.some(a => a.severity === 'critical')) return { level: 'red' };
if (anomalies.some(a => a.severity === 'high')) return { level: 'orange' };
if (anomalies.some(a => a.severity === 'medium')) return { level: 'yellow' };
return { level: 'green' };
}
}
async function runFullDemo() {
console.log('🚨 Landvex Reality Alert™ - Full Pipeline Demo');
console.log('===============================================\n');
// Create service with mocked AI
const service = new RealityAlertService();
service.objectDetection = new MockObjectDetectionService();
service.changeDetection = new MockChangeDetectionService();
service.riskClassifier = new MockRiskClassifierService();
// Test scenarios
const scenarios = [
{
name: 'Diesel Spill',
observation: {
imageUrl: 'https://example.com/photos/diesel-spill-001.jpg',
gpsLocation: { lat: 59.3293, lng: 18.0686, address: 'Stureplan, Stockholm' },
zoomerId: 'zoomer-123',
description: 'Dark liquid leaking from pump station'
}
},
{
name: 'Missing Manhole Cover',
observation: {
imageUrl: 'https://example.com/photos/missing-manhole-001.jpg',
gpsLocation: { lat: 59.3421, lng: 18.0554, address: 'Drottninggatan 12, Stockholm' },
zoomerId: 'zoomer-456',
description: 'Manhole cover is missing, dangerous hole in sidewalk'
}
},
{
name: 'Ice Formation on Heat Pump',
observation: {
imageUrl: 'https://example.com/photos/ice-heatpump-001.jpg',
gpsLocation: { lat: 59.3123, lng: 18.0234, address: 'Ringvägen 45, Stockholm' },
zoomerId: 'zoomer-789',
description: 'Heat pump covered in thick ice'
}
}
];
for (const scenario of scenarios) {
console.log(`\n📸 SCENARIO: ${scenario.name}`);
console.log('─'.repeat(50));
console.log(` Location: ${scenario.observation.gpsLocation.address}`);
console.log(` Description: ${scenario.observation.description}`);
console.log(` Zoomer: ${scenario.observation.zoomerId}\n`);
const result = await service.processObservation(scenario.observation);
if (result.status === 'verified') {
console.log('✅ OBSERVATION VERIFIED BY AI');
console.log(`\n🚨 REALITY ALERT: ${result.alert.id}`);
console.log(` Severity: ${result.alert.severity.toUpperCase()}`);
console.log(` Category: ${result.alert.category}`);
console.log(` Risk Score: ${result.alert.riskScore}/100`);
console.log(` AI Description: ${result.alert.description}`);
console.log(`\n📡 ROUTING INTELLIGENCE`);
console.log(` Primary: ${result.alert.routing.primary}`);
console.log(` Secondary: ${result.alert.routing.secondary.join(', ')}`);
console.log(` Emergency: ${result.alert.routing.emergency ? '⚠️ YES' : 'No'}`);
console.log(`\n💰 ZOOMER REWARD`);
console.log(` Amount: $${result.reward.amount}`);
console.log(` Breakdown: base $${result.reward.breakdown.base} × severity ${result.reward.breakdown.severityBonus} × category ${result.reward.breakdown.categoryBonus}`);
} else if (result.status === 'rejected') {
console.log('❌ REJECTED:', result.message);
}
}
console.log('\n\n📊 DASHBOARD SUMMARY');
console.log('═'.repeat(50));
const allAlerts = service.getPendingAlerts();
console.log(`Total Active Alerts: ${allAlerts.length}`);
const bySeverity = {};
const byCategory = {};
allAlerts.forEach(a => {
bySeverity[a.severity] = (bySeverity[a.severity] || 0) + 1;
byCategory[a.category] = (byCategory[a.category] || 0) + 1;
});
console.log('\nBy Severity:');
Object.entries(bySeverity).forEach(([sev, count]) => {
const icon = sev === 'critical' ? '🔴' : sev === 'high' ? '🟠' : sev === 'medium' ? '🟡' : '🟢';
console.log(` ${icon} ${sev}: ${count}`);
});
console.log('\nBy Category:');
Object.entries(byCategory).forEach(([cat, count]) => {
console.log(`${cat}: ${count}`);
});
console.log('\n✅ Demo complete!');
}
// Run if called directly
if (require.main === module) {
runFullDemo().catch(console.error);
}
module.exports = { runFullDemo };