feat: an unpaid cart's files are kept 2 days, a paid order's 30

Files are uploaded before payment so the price and the security check use
the file itself, but an abandoned cart kept them for 30 days. Now a finished
upload is held 2 days, a quote waiting for review 7, an approved quote 2 more
to be paid, and the paid order keeps its originals for 30 days from upload.
A payment never starts for files that are gone; one under way holds them a
day. Files attached to an order take the order's window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cauê Faleiros
2026-09-30 12:09:02 -03:00
parent eb254da501
commit 933bd30cbd
7 changed files with 71 additions and 2 deletions

View File

@@ -85,6 +85,16 @@ def intent(body: PaymentIntent, session_id=Depends(owner)):
raise HTTPException(404 if 'not found' in str(refusal) else 409, str(refusal))
if c.execute('SELECT 1 FROM dtf_local.orders WHERE quote_id=%s', (body.quote_id,)).fetchone():
raise HTTPException(409, 'Quote is already paid')
# Never charge for files that are gone: an unpaid cart's files are
# removed after a while. A payment under way keeps them a day longer,
# time enough for the provider's notice to become the order.
uploads = payments.quote_uploads(quote['approved'])
live = c.execute('''SELECT count(*) AS n FROM dtf_local.uploads WHERE id=ANY(%s)
AND purged_at IS NULL AND expires_at>now()''', (uploads,)).fetchone()['n']
if live != len(set(uploads)):
raise HTTPException(410, 'Os arquivos deste pedido expiraram porque ele não foi pago a tempo. '
'Monte o pedido de novo para pagar.')
payments.hold_uploads(c, uploads, '1 day')
# Never a second charge: an approved payment is waiting for its
# notification to become the order, and a card in review may still be.
# A card waiting for the bank's confirmation (3-D Secure) blocks only