Add the workshop seat-reservation endpoint

Node · Node · advanced · greenfield

Adds the seat-reservation endpoint the checkout service calls after payment: it looks up the workshop, rejects unknown ids and full workshops, then increments the seat counter and returns how many seats remain. The increment itself happens in SQL (`seats_taken + 1`) so the counter math runs in the database. Tested by reserving a seeded workshop down to zero seats and confirming the 409 once it filled.

An events platform. Express + a pg Pool (`db`). Popular workshops sell out in seconds with hundreds of concurrent checkout requests for the same row; `workshops(id, capacity, seats_taken)` has no CHECK constraint on the counter.

Requirements

Files touched

--- src/routes/reservations.js
+const express = require('express');
+
+const db = require('../db'); // pg Pool
+
+const router = express.Router();
+
+/**
+ * Claim one seat for a workshop. Called by the checkout service after
+ * payment; reservation records are written downstream by ticketing.
+ */
+router.post('/workshops/:id/reserve', async (req, res) => {
+  const { id } = req.params;
+
+  const { rows } = await db.query(
+    'SELECT capacity, seats_taken FROM workshops WHERE id = $1',
+    [id],
+  );
+  if (rows.length === 0) {
+    return res.status(404).json({ error: 'Unknown workshop' });
+  }
+
+  const workshop = rows[0];
+  if (workshop.seats_taken >= workshop.capacity) {
+    return res.status(409).json({ error: 'Workshop is full' });
+  }
+
+  await db.query(
+    'UPDATE workshops SET seats_taken = seats_taken + 1 WHERE id = $1',
+    [id],

Review this PR

Node practice