Files
boc/quixzoom-capture-pipeline/api/weak-supervision-api.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

174 lines
4.8 KiB
JavaScript

/**
* QUIXZOOM Weak Supervision API
*
* Endpoints:
* POST /api/detect — Detektera objekt i bild
* POST /api/detect/batch — Batch-detektion
* GET /api/models — Lista tillgängliga modeller
* GET /api/stats — Statistik
*/
const express = require('express');
const WeakSupervisionPipeline = require('../weak-supervision/pipeline');
const fs = require('fs');
const path = require('path');
class WeakSupervisionAPI {
constructor(port = 3002) {
this.app = express();
this.pipeline = new WeakSupervisionPipeline({
confidenceThreshold: 0.3,
iouThreshold: 0.5,
});
this.port = port;
this.stats = {
totalRequests: 0,
totalImages: 0,
totalDetections: 0,
avgLatency: 0,
};
this.setupRoutes();
}
setupRoutes() {
this.app.use(express.json({ limit: '50mb' }));
// Health check
this.app.get('/health', (req, res) => {
res.json({ status: 'ok', service: 'weak-supervision' });
});
// Detektera en bild
this.app.post('/api/detect', async (req, res) => {
const start = Date.now();
try {
const { imagePath, imageBase64 } = req.body;
let filePath = imagePath;
// Om base64, spara till temporär fil
if (imageBase64) {
const buffer = Buffer.from(imageBase64, 'base64');
filePath = `/tmp/ws-${Date.now()}.jpg`;
fs.writeFileSync(filePath, buffer);
}
if (!filePath || !fs.existsSync(filePath)) {
return res.status(400).json({ error: 'Image not found' });
}
const result = await this.pipeline.detect(filePath);
// Uppdatera statistik
this.stats.totalRequests++;
this.stats.totalImages++;
this.stats.totalDetections += result.consolidated.length;
const latency = Date.now() - start;
this.stats.avgLatency = (this.stats.avgLatency * (this.stats.totalRequests - 1) + latency) / this.stats.totalRequests;
res.json({
success: true,
latency: latency,
detections: result.consolidated,
rawResults: {
yolo: result.modelResults.yolo?.length || 0,
groundingDINO: result.modelResults.groundingDINO?.length || 0,
sam2: result.modelResults.sam2?.length || 0,
},
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Batch-detektion
this.app.post('/api/detect/batch', async (req, res) => {
const start = Date.now();
try {
const { imagePaths } = req.body;
if (!Array.isArray(imagePaths)) {
return res.status(400).json({ error: 'imagePaths must be an array' });
}
const results = [];
for (const imagePath of imagePaths) {
if (!fs.existsSync(imagePath)) {
results.push({ path: imagePath, error: 'Not found' });
continue;
}
const result = await this.pipeline.detect(imagePath);
results.push({
path: imagePath,
detections: result.consolidated,
});
this.stats.totalDetections += result.consolidated.length;
}
this.stats.totalRequests++;
this.stats.totalImages += imagePaths.length;
const latency = Date.now() - start;
res.json({
success: true,
latency,
processed: imagePaths.length,
results,
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Lista modeller
this.app.get('/api/models', (req, res) => {
res.json({
models: [
{ name: 'yolov8', available: this.pipeline.models.yolo.available, weight: 0.3 },
{ name: 'groundingDINO', available: false, weight: 0.3 },
{ name: 'sam2', available: false, weight: 0.2 },
{ name: 'ocr', available: false, weight: 0.1 },
{ name: 'depth', available: false, weight: 0.1 },
],
});
});
// Statistik
this.app.get('/api/stats', (req, res) => {
res.json({
...this.stats,
uptime: process.uptime(),
});
});
}
start() {
this.app.listen(this.port, () => {
console.log(`[WS API] Listening on port ${this.port}`);
console.log(`[WS API] Endpoints:`);
console.log(` POST /api/detect`);
console.log(` POST /api/detect/batch`);
console.log(` GET /api/models`);
console.log(` GET /api/stats`);
});
}
}
// Starta om detta är huvudfil
if (require.main === module) {
const api = new WeakSupervisionAPI();
api.start();
}
module.exports = WeakSupervisionAPI;