50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
// inventory.js
|
|
import express from "express";
|
|
import { pool } from "./db.js"; // pg pool
|
|
const router = express.Router();
|
|
|
|
// Calculate how many server units are in this cart
|
|
const serverIds = new Set(["server1", "server2", "server3"]);
|
|
|
|
router.post("/api/reserve", async (req, res) => {
|
|
const { items } = req.body; // [{id, qty, price}]
|
|
const want = items.filter(i => serverIds.has(i.id))
|
|
.reduce((a, i) => a + i.qty, 0);
|
|
|
|
if (want === 0) return res.json({ ok: true, remaining: await currentRemaining() });
|
|
|
|
const client = await pool.connect();
|
|
try {
|
|
await client.query("BEGIN");
|
|
const { rows } = await client.query("SELECT value_int FROM inventory_state WHERE key='server_slots_remaining' FOR UPDATE");
|
|
const remaining = rows[0].value_int;
|
|
|
|
if (remaining < want) {
|
|
await client.query("ROLLBACK");
|
|
return res.status(409).json({ ok: false, reason: "sold_out", remaining });
|
|
}
|
|
|
|
await client.query(
|
|
"UPDATE inventory_state SET value_int = value_int - $1 WHERE key='server_slots_remaining'",
|
|
[want]
|
|
);
|
|
await client.query("COMMIT");
|
|
res.json({ ok: true, remaining: remaining - want });
|
|
} catch (e) {
|
|
await client.query("ROLLBACK"); throw e;
|
|
} finally {
|
|
client.release();
|
|
}
|
|
});
|
|
|
|
async function currentRemaining() {
|
|
const { rows } = await pool.query("SELECT value_int FROM inventory_state WHERE key='server_slots_remaining'");
|
|
return rows[0].value_int;
|
|
}
|
|
|
|
router.get("/api/inventory", async (req, res) => {
|
|
res.json({ remaining: await currentRemaining() });
|
|
});
|
|
|
|
export default router;
|