{
  "filename": "reserve.cjs",
  "rule": "- name: stock-never-negative\n  where: \"reserve.cjs\"\n  ensure: >-\n    The stock UPDATE must include available >= the requested quantity in its WHERE predicate, so concurrent reservations cannot decrement below zero.",
  "corrected": "async function reserve(client, tenantId, sku, quantity) {\n  if (!Number.isSafeInteger(quantity) || quantity <= 0) {\n    throw new Error(\"Quantity must be a positive integer\");\n  }\n  const result = await client.query(\n    `UPDATE inventory SET available = available - $1\n     WHERE tenant_id = $2 AND sku = $3 AND available >= $1\n     RETURNING available`,\n    [quantity, tenantId, sku],\n  );\n  if (result.rowCount !== 1) throw new Error(\"Stock not available\");\n  return result.rows[0].available;\n}\nmodule.exports = { reserve };\n",
  "broken": "async function reserve(client, tenantId, sku, quantity) {\n  if (!Number.isSafeInteger(quantity) || quantity <= 0) {\n    throw new Error(\"Quantity must be a positive integer\");\n  }\n  const result = await client.query(\n    `UPDATE inventory SET available = available - $1\n     WHERE tenant_id = $2 AND sku = $3\n     RETURNING available`,\n    [quantity, tenantId, sku],\n  );\n  if (result.rowCount !== 1) throw new Error(\"Stock not available\");\n  return result.rows[0].available;\n}\nmodule.exports = { reserve };\n",
  "regression": [
    " AND available >= $1",
    ""
  ],
  "test_scenarios": [
    [
      "Quantity larger than stock",
      "No row changes"
    ],
    [
      "Two reservations of the final unit",
      "Exactly one succeeds"
    ],
    [
      "Zero, negative, or noninteger quantity",
      "Rejected before SQL"
    ],
    [
      "SKU contains SQL punctuation",
      "Bound as data, not SQL"
    ]
  ],
  "test_source": null,
  "test_command": "node --test tests/reservation.test.cjs"
}