f0ce322a7c
A press fetched at most three receipts, because fetching one means downloading it and having a model read the PDF, and a backlog of forty cannot finish inside one serverless invocation. Working through a real backlog meant pressing the button a dozen times, which is the shape of a stopgap rather than a feature. The loop now lives in the page: it keeps asking for another bounded pass until one comes back with nothing new, which is the honest signal that the mailboxes hold nothing more for the purchases still open. Progress shows as it goes and there is a Stop, read inside the loop so it takes effect on the current pass rather than after every remaining one. Deliberately not a queue drained by cron. The finest schedule this app runs is hourly, so a queue would mean pressing a button and waiting an hour for anything to happen: worse than what it replaces, and a new table and worker to maintain. The cost of putting the loop in the browser is that it runs while the tab is open, which is acceptable for work somebody just asked for. A cap of 25 passes is a backstop, not a budget: it exists so a pass that keeps reporting work it never completes cannot run forever. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>