Skip to content

fix: recheck failed-payment eligibility before sending - #399

Open
hamitarsln wants to merge 4 commits into
tin-computer:mainfrom
hamitarsln:codex/payment-recovery-recheck
Open

hamitarsln wants to merge 4 commits into
tin-computer:mainfrom
hamitarsln:codex/payment-recovery-recheck

Conversation

@hamitarsln

@hamitarsln hamitarsln commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

The send-time recheck only looked for the invoice ID in the open-invoice list. If the balance became zero while the invoice still appeared open, Tin still sent the approved recovery email.

Reuse failed_invoices at that recheck. The invoice must still have a balance, a failed attempt and automatic collection. Skip it before recording a send when it no longer qualifies.

Verification

  • Reproduced twice: zero balance, manual collection and no failed attempt each still sent an email before the fix.

  • Added regressions and a positive case: a partial payment with money still owed still sends once.

  • Merged current main and kept both sets of tests. 119 payment-recovery, Stripe and failure-message tests passed, no skips. Ruff and diff checks passed.

  • CI failed in an unchanged extension concurrency test: its helper stopped after 100 event-loop turns before WebCrypto completed. Reproduced twice with an occupied crypto thread pool.

  • The test-only helper now uses a bounded elapsed-time wait. Added a regression that fails on the old helper. All 244 browser/extension/collection tests pass on Node 22; the 119 payment/Stripe/failure tests pass again. No production extension code changed.

  • A later CI run exposed a separate lock-page test race. The test now waits for its first setup response before advancing the server fixture. Reproduced twice with a delayed response; both repeats pass after the fix. The full 244-test browser suite passes again on Node 22. No event assertions or app code changed.

Notes

Synthetic Stripe and Gmail only. No customer email was sent. Existing retry receipts and approval rules stay in place.

Tested on staging

The combined QA branch was deployed on 13 Oct. Claw staging has no Stripe/Google Workspace test connections yet. No send-time integration test ran. Stripe test mode bypasses the send path, so a test-mode run alone would not prove this fix. The exact PR-head staging check remains pending.

@hamitarsln
hamitarsln requested a review from a team as a code owner October 12, 2026 08:13
Copilot AI balanced review requested due to automatic review settings October 12, 2026 08:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused fix matches the documented behavior and includes appropriate regression coverage.

0 open findings

What changed in this PR

This PR prevents approved payment-recovery emails from being sent when the invoice is no longer eligible.

Changes:

  • Reuses failed_invoices during the send-time recheck.
  • Adds regression and partial-payment tests.
  • Documents the expanded eligibility recheck.
File Description
src/​tin_lite/​payment_recovery_activities.py Revalidates invoice eligibility before sending.
tests/​test_payment_recovery.py Covers eligibility changes and partial payments.
docs/​payment-recovery.md Documents send-time eligibility checks.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants