{
  "filename": "Services/CancelOrder.cs",
  "rule": "- name: stale-update-is-not-success\n  where: \"Services/CancelOrder.cs\"\n  ensure: >-\n    Apply must return false when SaveChangesAsync throws DbUpdateConcurrencyException. A stale write must not be reported as successful.",
  "corrected": "using Microsoft.EntityFrameworkCore;\n\npublic sealed class CancelOrder(AppDbContext db) {\n    public async Task<bool> Apply(Order order, byte[] expectedVersion, CancellationToken cancellationToken) {\n        db.Entry(order).Property(x => x.RowVersion).OriginalValue = expectedVersion;\n        order.Status = \"cancelled\";\n        try {\n            await db.SaveChangesAsync(cancellationToken);\n            return true;\n        } catch (DbUpdateConcurrencyException) {\n            return false;\n        }\n    }\n}\n",
  "broken": "using Microsoft.EntityFrameworkCore;\n\npublic sealed class CancelOrder(AppDbContext db) {\n    public async Task<bool> Apply(Order order, byte[] expectedVersion, CancellationToken cancellationToken) {\n        db.Entry(order).Property(x => x.RowVersion).OriginalValue = expectedVersion;\n        order.Status = \"cancelled\";\n        try {\n            await db.SaveChangesAsync(cancellationToken);\n            return true;\n        } catch (DbUpdateConcurrencyException) {\n            return true;\n        }\n    }\n}\n",
  "regression": [
    "        } catch (DbUpdateConcurrencyException) {\n            return false;",
    "        } catch (DbUpdateConcurrencyException) {\n            return true;"
  ],
  "test_scenarios": [
    [
      "Expected version is current",
      "true after save"
    ],
    [
      "Version is stale",
      "false and HTTP conflict"
    ],
    [
      "Another writer wins between load and save",
      "Concurrency exception handled"
    ],
    [
      "Connection failure",
      "Error propagates rather than being called a version conflict"
    ]
  ],
  "test_source": null,
  "test_command": "dotnet test --filter CancelOrderConcurrencyTests"
}