chadtmiller.com/checkout-demo
A demo of knotless's review agent
Orders take a discount code
OpenThis adds an optional discount code to place_order. It has bugs that charge customers the wrong amount, and it breaks two rules in AGENTS.md.
- Expiry check is inverted. Valid codes are ignored, and expired codes are applied.
- Percentage discount is a float.
amount * value / 100returns a float. That puts a float intoorders.totaland breaks the integer-cents rule. - Total can go negative. A fixed discount larger than the subtotal makes the total negative. Cap the discount at the subtotal.
- SQL injection. The code is formatted into the SQL string. AGENTS.md requires parameters.
- No tests. AGENTS.md requires a test in
test_checkout.pyfor any change tocheckout.py. Cover a percent code, a fixed code, an expired code, an unknown code, and a discount larger than the subtotal.
checkout.pyline 22Outdated
return 0 | |
kind, value, expires = row | |
if date.fromisoformat(expires) > date.today(): | |
return 0 |
Inverted. This returns 0 when expires is after today, so a valid code gives no discount. An expired code passes through and is applied. It should be expires < today, or <= depending on whether the expiry day is inclusive. The docstring says "until the day it expires".
checkout.pyline 24Outdated
if date.fromisoformat(expires) > date.today(): | |
return 0 | |
if kind == "percent": | |
return amount * value / 100 |
amount * value / 100 is a float, so the order total becomes a float. Use integer math, e.g. amount * value // 100, and decide on the rounding. Also cap the result with min(..., amount), since the fixed branch below can exceed the subtotal and give a negative total.
checkout.pyline 16Outdated
"""What a discount code takes off `amount`: a percentage, or a fixed | |
number of cents, until the day it expires.""" | |
row = db.execute( | |
f"SELECT kind, value, expires FROM discounts WHERE code = '{code}'" |
SQL injection: code is formatted into the query. Use WHERE code = ? with (code,).
Most of round 1 is fixed. The expiry check is no longer inverted, the percentage uses integer division, the fixed discount is capped at the subtotal, and the query is parameterized. One item is still open, and I found one new edge case.
- Still no tests. The diff only touches
checkout.py. AGENTS.md requires a test intest_checkout.pyfor any change tocheckout.py. Please add tests for a percent code, a fixed code, an expired code, an unknown code, and a fixed discount larger than the subtotal. - A percent value over 100 makes the total negative. The
percentbranch isn't capped like the fixed branch is. Ifvalueis 150, the discount is 1.5× the subtotal, so the order total goes below zero. Returnmin(amount * value // 100, amount), or reject such rows. Add a test for it.
checkout.pyline 24
if date.fromisoformat(expires) < date.today(): | |
return 0 | |
if kind == "percent": | |
return amount * value // 100 |
No cap here: a percent value above 100 gives a discount larger than amount, and the total goes negative. Wrap it in min(..., amount).
Checking that the page updates live.
Checking again that the page updates live.
A third live check.
Browser live check 1793377303410
Browser live check 1793377367844
A compressed live check.
Browser live check 1793377468992
A zstd live check.
Another zstd live check.
1 review asking for changes
What changes
place_ordertakes an optional discount code. A code takes a percentage off the subtotal, or a fixed number of cents, until it expires.