Add a receipt-to-expense-report recipe and runnable playground. Users open a PNG/JPEG/WebP receipt from Puter, read it as a Blob, review and correct extracted fields, explicitly approve an expense, and save the approved report CSV through the Puter Save dialog.
Report saves use unique snapshots ordered by an atomic sequence reserved before writing. A timed-out write arriving late cannot overwrite a later snapshot. Paginated history supports manual recovery. The file workflow preserves this persistence code.
Addresses PUT-1977. Depends on #4215; base: codex/ai-category-cleanup-recipe.
Validation at 6c8844ed78c3e5ef36ccf85f24c7f10eef4e6345:
- Both executable recipe suites passed together, 396 tests, including delayed-save and both desktop/legacy-popup cancellation regressions. The combined docs build passed without warnings.
- Chromium exercised real SDK/desktop popup/backend file selection, Blob conversion, review/approval, actual KV saves, Save cancellation, CSV readback, and page-reload/reopen with identical exported contents. The new browser pass used deterministic AI HTTP fixtures. Earlier pre-picker live extraction used the actual Puter driver and configured provider.
- Seven live persistence checks passed through the real SDK, HTTP, Puter KV driver, and Dynalite. A-timeout/reopen/B-success/late-A selected B and retained both snapshots. Lost set/increment responses, concurrent sequence allocation, numeric ordering, and history pagination also passed. Transport faults were injected at fetch, not into the driver.
- Independent local review completed after correcting cancellation handling and unconfirmed-save messaging.
The isolated Docker browser server was healthy at its actual ephemeral origin. Tests used synthetic users/files, in-memory SQLite/storage, real Dynalite, and mocked Redis, with test-only sharp resolution and compiled import.meta.url adaptations. Restart durability was not tested. Browser cancellation coverage uses dialog Cancel buttons; browser-blocked popups and direct browser-window closure were not tested.
KV reads can lag, and concurrent editors can produce divergent snapshots. History retains them for manual reconciliation; there is no automatic merge or transaction. Snapshot storage grows with saves, and the counter/report namespace must not be reset or reused while active. A failed file-save response is unconfirmed, so users should check the destination before retrying.
Stack: main → #4215 → #4216. Current head: 02596cd0fef35207248ae06aaabad0199875c3a4.
Both recipe patches are unchanged and isolated from the code stack on current main. The combined tree matches main plus only the two original recipe patches. All 396 recipe tests and the docs build passed.
Activity
2This pull request is a draft
Merging is unavailable until it is marked ready for review.