# Overbooking prevention logic

- **Pattern:** `ab-000541` (`booking-flow-lifecycle.booking-creation.overbooking-prevention`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000541
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000541)

## Why it matters

Group-capacity slots — classes, workshops, shared resources — require a count-against-capacity check, not just a slot-existence check. Without it, 30 attendees can book a room with a capacity of 10, because the system only asked "is the slot taken?" rather than "is the slot full?". OWASP A04 (Insecure Design) applies: the domain model includes a capacity constraint that the server never enforces. Overbooking forces refunds, damages customer trust, and requires manual communication with every affected attendee when the overbooking is discovered.

## Severity rationale

Medium because the defect allows overbooking of capacity-constrained resources, causing real-world operational failures and refunds, but does not expose sensitive data.

## Remediation

Compare the live booking count against `slot.maxCapacity` in your server-side availability check (e.g., `src/lib/booking-service.ts`). This must run server-side on every booking creation path.

```typescript
const currentCount = await db.booking.count({
  where: { slotId: requestedSlotId, status: { not: 'CANCELLED' } }
});

const slot = await db.slot.findUniqueOrThrow({ where: { id: requestedSlotId } });
if (currentCount >= slot.maxCapacity) {
  throw new CapacityError('Slot is at capacity');
}
```

## Detection

- **ID:** `overbooking-prevention`
- **Label:** Overbooking prevention logic
- **Severity:** `medium`
- **What to look for:** If the system allows multiple bookings per slot (e.g., a class with capacity 10, a group booking), look for `count < capacity` logic in the availability check. Count all booking creation paths and verify each one includes a capacity comparison. Locate the `maxCapacity`, `capacity`, or `max_attendees` field in the slot/event model. Enumerate: "X of Y booking paths enforce capacity limits."
- **Pass criteria:** The availability check explicitly compares current booking count against the maximum capacity. A booking is only allowed if `count < max_capacity`. The capacity field must be stored per-slot or per-event (not globally hardcoded). At least 1 capacity comparison must exist in every booking creation path. Report: `"X of Y booking paths enforce capacity limits against [capacity_field] in [model]."`
- **Fail criteria:** No capacity check exists, or capacity is hardcoded as 1 and not configurable, or the check is missing in at least 1 code path. Do NOT pass when capacity is only checked on the frontend — server-side enforcement is required.
- **Skip (N/A) when:** The system is strictly 1:1 (one booking per slot) and enforces this via a unique constraint on `(slotId)` or `(slotId, startTime)` in the database schema.
- **Detail on fail:** `"No capacity check found. The system allows unlimited bookings for an event with max_capacity = 10."`
- **Cross-reference:** The conflict-check in this category covers basic availability; this check extends it to capacity-aware scenarios.
- **Cross-reference:** The waitlist-handling check in Conflict Prevention verifies what happens when capacity is reached.
- **Cross-reference:** The concurrent-request-handling check in Conflict Prevention ensures capacity checks are race-condition safe.
- **Remediation:** Enforce capacity limits in the availability check. Add this in your booking service (e.g., `src/lib/booking-service.ts`) or API handler.

  ```typescript
  const currentCount = await db.booking.count({
    where: { slotId: requestedSlotId, status: { not: 'CANCELLED' } }
  });

  const slot = await db.slot.findUnique({ where: { id: slotId } });
  if (currentCount >= slot.maxCapacity) {
    throw new Error("Slot is at capacity");
  }
  ```

## External references

- cwe CWE-20
- owasp A04
- iso-25010 functional-suitability.functional-correctness

Taxons: injection-and-input-trust

HTML version: https://auditbuffet.com/patterns/ab-000541
