Files
boc/quixzoom-capture-pipeline/replay/integrate-with-ukg.js
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

200 lines
6.7 KiB
JavaScript

/**
* QUIXZOOM Replay Engine + UKG Integration
*
* Kopplar Replay Engine till Urban Knowledge Graph för:
* - Spela upp historiska händelser
* - Jämföra algoritm-versioner
* - Debugga i efterhand
*/
const ReplayEngine = require('./engine');
const UKG = require('../urban-knowledge-graph/ukg');
const ObjectIdentityPipeline = require('../identity-engine/pipeline');
const ChangeDetectionEngine = require('../change-detection/engine');
class UKGReplayIntegration {
constructor() {
this.ukg = new UKG();
this.oie = new ObjectIdentityPipeline();
this.changeDetection = new ChangeDetectionEngine();
this.replay = new ReplayEngine({ speed: 100 });
this.setupHandlers();
}
setupHandlers() {
// Zoomer startar
this.replay.registerHandler('zoomer_started', async (payload) => {
console.log(` → Zoomer ${payload.zoomerId} started`);
return { status: 'recording' };
});
// Observation skapad
this.replay.registerHandler('observation_created', async (payload, context) => {
console.log(` → Observation: ${payload.objectType}`);
// Kör genom OIE
const identityResult = await this.oie.process({
id: payload.observationId,
objectType: payload.objectType,
location: payload.location,
timestamp: payload.timestamp,
attributes: payload.attributes,
});
return {
observationId: payload.observationId,
identityAction: identityResult.action,
objectId: identityResult.objectId,
};
});
// Identity matchad
this.replay.registerHandler('identity_matched', async (payload, context) => {
console.log(` → Identity: ${payload.objectId} (${(payload.confidence * 100).toFixed(0)}%)`);
// Hämta föregående observation
const previousObs = this.findPreviousObservation(payload.objectId);
const currentObs = this.findObservation(payload.observationId);
if (previousObs && currentObs) {
// Kör change detection
const changes = this.changeDetection.detectChanges(
payload.objectId,
currentObs,
previousObs
);
return {
objectId: payload.objectId,
confidence: payload.confidence,
changes: changes.changes,
severity: changes.severity,
};
}
return { objectId: payload.objectId, confidence: payload.confidence };
});
// Evidence tillagd
this.replay.registerHandler('evidence_added', async (payload) => {
console.log(` → Evidence: ${payload.evidenceType}`);
// Lägg till i UKG
this.ukg.addEvidence(payload.objectId, {
id: payload.evidenceId,
type: payload.evidenceType,
source: payload.source,
timestamp: payload.timestamp,
});
return { evidenceId: payload.evidenceId };
});
// Kunskapsgap upptäckt
this.replay.registerHandler('knowledge_gap_detected', async (payload) => {
console.log(` → Gap: ${payload.gapType} (priority: ${payload.priority})`);
// Skapa uppdrag
const mission = {
id: `mission_${Date.now()}`,
type: 'verify',
target: payload.objectId,
gapType: payload.gapType,
priority: payload.priority,
};
return { mission };
});
// Uppdrag skapat
this.replay.registerHandler('mission_created', async (payload) => {
console.log(` → Mission: ${payload.missionType}`);
return { missionId: payload.missionId };
});
// Instruktion skickad
this.replay.registerHandler('instruction_sent', async (payload) => {
console.log(` → Instruction: "${payload.instruction}"`);
return { sent: true };
});
}
findPreviousObservation(objectId) {
// Hämta senaste observation för objektet
// Förenklad implementation
return null;
}
findObservation(observationId) {
// Hämta observation
// Förenklad implementation
return null;
}
async replayEvents(events) {
console.log('=== UKG REPLAY INTEGRATION ===\n');
this.replay.loadEvents(events);
await this.replay.play();
console.log('\n=== REPLAY COMPLETE ===');
console.log('Stats:', this.replay.getStats());
return this.replay.results;
}
async compareAlgorithms(events, versionA, versionB) {
console.log('=== ALGORITHM COMPARISON ===\n');
const comparison = await this.replay.compareVersions(
events,
versionA.handlers,
versionB.handlers
);
console.log('\nComparison:');
console.log(` Total events: ${comparison.comparison.totalEvents}`);
console.log(` Differences: ${comparison.comparison.differences}`);
console.log(` Difference rate: ${comparison.comparison.differenceRate}`);
if (comparison.comparison.differences > 0) {
console.log('\n Details:');
for (const diff of comparison.comparison.details.slice(0, 5)) {
console.log(` [${diff.index}] ${diff.type}:`);
console.log(` A: ${JSON.stringify(diff.versionA)}`);
console.log(` B: ${JSON.stringify(diff.versionB)}`);
}
}
return comparison;
}
}
// Exportera
module.exports = UKGReplayIntegration;
// Demo
if (require.main === module) {
const integration = new UKGReplayIntegration();
// Skapa scenario
const baseTime = Date.now();
const events = [
{ id: 'evt_001', type: 'zoomer_started', timestamp: baseTime, payload: { zoomerId: 'zoomer_00001' } },
{ id: 'evt_002', type: 'observation_created', timestamp: baseTime + 6000, payload: { observationId: 'obs_001', objectType: 'street_lamp', location: { lat: 13.725, lng: 100.555 }, timestamp: baseTime + 6000, attributes: { material: 'steel', height: 7.8, rust: false } } },
{ id: 'evt_003', type: 'identity_matched', timestamp: baseTime + 7000, payload: { observationId: 'obs_001', objectId: 'street_lamp_000001', confidence: 0.94 } },
{ id: 'evt_004', type: 'evidence_added', timestamp: baseTime + 7000, payload: { evidenceType: 'image', evidenceId: 'ev_001', objectId: 'street_lamp_000001', source: 'zoomer_00001' } },
{ id: 'evt_005', type: 'knowledge_gap_detected', timestamp: baseTime + 8000, payload: { gapType: 'angle', gapId: 'gap_001', objectId: 'street_lamp_000001', priority: 'medium' } },
{ id: 'evt_006', type: 'mission_created', timestamp: baseTime + 9000, payload: { missionType: 'verify_angle', missionId: 'mission_001' } },
{ id: 'evt_007', type: 'instruction_sent', timestamp: baseTime + 10000, payload: { instruction: 'Gå två meter närmare' } },
];
integration.replayEvents(events).then(() => {
console.log('\n=== UKG STATE ===');
console.log(`Objects: ${integration.ukg.objects.size}`);
console.log(`Observations: ${integration.ukg.observations.size}`);
console.log(`Evidence: ${integration.ukg.evidence.size}`);
});
}