feat: display available stock balance on products page based on n8n inventory updates

This commit is contained in:
Cauê Faleiros
2026-05-25 11:26:00 -03:00
parent 4ce1e9aedb
commit c47a64d831
4 changed files with 120 additions and 6 deletions

View File

@@ -45,6 +45,16 @@ const initDB = async () => {
await pool.query(`CREATE UNIQUE INDEX IF NOT EXISTS unique_order_product ON orders (pedido_id, produto_id);`).catch(err => {
console.error("Notice: Could not create unique index (might already exist or there are duplicates):", err.message);
});
await pool.query(`
CREATE TABLE IF NOT EXISTS stock (
produto_id VARCHAR(100) PRIMARY KEY,
nome TEXT,
saldo INTEGER DEFAULT 0,
delta_estoque INTEGER DEFAULT 0,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`);
console.log("Database initialized successfully.");
} catch (err) {
@@ -106,6 +116,17 @@ app.get('/api/data', verifyToken, async (req, res) => {
}
});
// GET stock (for the frontend)
app.get('/api/stock', verifyToken, async (req, res) => {
try {
const result = await pool.query('SELECT * FROM stock');
res.json(result.rows);
} catch (error) {
console.error("Error fetching stock:", error);
res.status(500).json({ error: 'Internal Server Error' });
}
});
// POST data (for n8n) - Protected by API_KEY internally or via middleware if needed
// Leaving it as it was, checking API_KEY manually? Wait, the previous version didn't actually use 'authenticate' middleware on the POST!
// Let's add the authenticate middleware to the POST endpoint.
@@ -178,6 +199,51 @@ app.post('/api/data', authenticateAPIKey, async (req, res) => {
})();
});
// POST stock (for n8n)
app.post('/api/stock', authenticateAPIKey, async (req, res) => {
res.status(201).json({ message: 'Stock data received, processing in background' });
const newData = req.body;
const payload = Array.isArray(newData) ? newData : [newData];
(async () => {
const client = await pool.connect();
try {
await client.query('BEGIN');
const insertQuery = `
INSERT INTO stock (produto_id, nome, saldo, delta_estoque)
VALUES ($1, $2, $3, $4)
ON CONFLICT (produto_id) DO UPDATE SET
nome = EXCLUDED.nome,
saldo = EXCLUDED.saldo,
delta_estoque = EXCLUDED.delta_estoque,
updated_at = CURRENT_TIMESTAMP
`;
for (const item of payload) {
const idProduto = item.idProduto || item.ID_Produto || '';
if (!idProduto) continue;
const values = [
String(idProduto),
item.nome || item.Descricao_Produto || 'Unknown',
parseInt(item.saldo) || 0,
parseInt(item.delta_estoque) || 0
];
await client.query(insertQuery, values);
}
await client.query('COMMIT');
} catch (error) {
await client.query('ROLLBACK');
console.error("Database stock insert error:", error);
} finally {
client.release();
}
})();
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`Nexstar Backend running at http://localhost:${PORT}`);
console.log(`Endpoint for n8n: POST http://localhost:${PORT}/api/data`);