diff --git a/server/server.js b/server/server.js index 7319ed2..238a88f 100644 --- a/server/server.js +++ b/server/server.js @@ -1841,6 +1841,73 @@ app.post('/api/turtle/:id/refresh-inventory', async (req, res) => { } }); +// ========== Cross-Project Integration API ========== +// These endpoints allow the Inventory Manager system to query turtle state + +const INVENTORY_SERVER_URL = process.env.INVENTORY_SERVER_URL || ''; // e.g. http://inventory-server:3001 + +// Get all turtle summaries (for inventory dashboard sidebar widget) +app.get('/api/integration/turtle-summary', (req, res) => { + const summaries = []; + for (const [id, turtle] of turtles) { + summaries.push({ + id, + name: turtle.name || `Turtle ${id}`, + state: turtle.currentStateName || 'unknown', + fuel: turtle.fuelLevel ?? null, + position: turtle.position || null, + inventoryUsed: turtle.inventory + ? turtle.inventory.filter(s => s && s.name).length + : 0, + connected: turtle.connected || false, + }); + } + res.json({ turtles: summaries }); +}); + +// Proxy to inventory server (locate items for turtle pickup) +app.get('/api/integration/inventory-locate', async (req, res) => { + if (!INVENTORY_SERVER_URL) { + return res.json({ configured: false, message: 'INVENTORY_SERVER_URL not configured' }); + } + try { + const params = new URLSearchParams(req.query); + const resp = await fetch(`${INVENTORY_SERVER_URL}/api/integration/locate-item?${params}`); + const data = await resp.json(); + res.json({ configured: true, ...data }); + } catch (err) { + res.status(502).json({ configured: true, error: `Cannot reach inventory server: ${err.message}` }); + } +}); + +// Proxy to inventory server (low stock alerts — turtles could auto-mine missing resources) +app.get('/api/integration/inventory-alerts', async (req, res) => { + if (!INVENTORY_SERVER_URL) { + return res.json({ configured: false, message: 'INVENTORY_SERVER_URL not configured' }); + } + try { + const resp = await fetch(`${INVENTORY_SERVER_URL}/api/integration/low-stock`); + const data = await resp.json(); + res.json({ configured: true, ...data }); + } catch (err) { + res.status(502).json({ configured: true, error: `Cannot reach inventory server: ${err.message}` }); + } +}); + +// Proxy to inventory server (storage space check — should turtles keep mining?) +app.get('/api/integration/storage-status', async (req, res) => { + if (!INVENTORY_SERVER_URL) { + return res.json({ configured: false, message: 'INVENTORY_SERVER_URL not configured' }); + } + try { + const resp = await fetch(`${INVENTORY_SERVER_URL}/api/integration/storage-status`); + const data = await resp.json(); + res.json({ configured: true, ...data }); + } catch (err) { + res.status(502).json({ configured: true, error: `Cannot reach inventory server: ${err.message}` }); + } +}); + // Graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ›‘ Shutting down server...'); @@ -1852,4 +1919,7 @@ server.listen(PORT, () => { console.log(`āœ… Server ready!`); console.log(`\nConfigured turtles to send updates to:`); console.log(` http://localhost:${PORT}/api/turtle/update`); + if (INVENTORY_SERVER_URL) { + console.log(`šŸ“¦ Inventory server integration: ${INVENTORY_SERVER_URL}`); + } });