// Minimal detection service: receives satellite/infra events, writes to Postgres and emits to Redis const express = require('express'); const bodyParser = require('body-parser'); const { Pool } = require('pg'); const Redis = require('ioredis'); const { v4: uuidv4 } = require('uuid'); const pool = new Pool({ connectionString: process.env.DATABASE_URL || 'postgresql://localhost/integral' }); const redis = new Redis(process.env.REDIS_URL || 'redis://localhost:6379'); const app = express(); app.use(bodyParser.json()); /** Expected payload: { namespace: "satellite" | "infrastructure", type: "pothole-detection", timestamp: "2025-11-30T10:00:00Z", location: { lat: -29.12, lon: 26.22 }, severity: 3, images: ["https://..."], provenance: {...} } **/ app.post('/detect', async (req, res) => { try { const { namespace, type, timestamp, location, severity=1, images=[], provenance={} } = req.body; const id = uuidv4(); const q = `INSERT INTO objects (id, namespace, type, timestamp, location, severity, images, provenance) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING *`; const values = [id, namespace, type, timestamp || new Date().toISOString(), location || null, severity, JSON.stringify(images), provenance]; const result = await pool.query(q, values); const obj = result.rows[0]; // publish event for verification await redis.publish('infra:faults:created', JSON.stringify({ id: obj.id, namespace, type, location, severity })); res.status(201).json(obj); } catch (err) { console.error(err); res.status(500).json({ error: 'detection failed' }); } }); app.listen(process.env.PORT || 3001, () => console.log('detection-service listening on 3001'));