Comfy-Org / Comfy-Org/ComfyUI_frontend
Missing-checkout-completion report dedupes per tab, not per attempt
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
## Problem / Goal
`cloud_checkout_completion_missing` (added in #17000) is deduplicated by `hasReportedPendingCheckoutRecoveryExhaustion`, a `let` inside `useSubscriptionInternal()`. That is per composable instance and in memory, so the emitted count is not one per failed checkout:
- Two open ComfyUI tabs during a checkout each run their own recovery ladder and each report.
- A reload resets the flag and `pendingCheckoutRecoveryAttempt`, re-arming a fresh cycle that can report again — for up to the 6h `PENDING_SUBSCRIPTION_CHECKOUT_MAX_AGE_MS` life of the attempt.
The analysis side is already handled: #17000 puts `checkout_attempt_id` in `context`, so duplicates collapse downstream. The emission side is not, so the raw event count cannot be used as a numerator over checkouts without deduplicating first.
## Proposed Solution
Persist the "already reported" marker alongside the attempt rather than in composable state — a `sessionStorage`/`localStorage` key derived from `attempt_id`, checked and set in `reportMissingCheckoutCompletion()`. It should be cleared by `clearPendingSubscriptionCheckoutAttempt()` so it cannot outlive its attempt.
Note the storage-key lifetime needs to match the attempt's 6h max age, otherwise the marker leaks.
## Acceptance Criteria
- [ ] One report per `attempt_id` across reloads
- [ ] One report per `attempt_id` across concurrent tabs
- [ ] The marker is cleared when the pending attempt is cleared or expires
- [ ] Tests covering the reload and two-tab cases
---
Raised by @benjcooley on #17000 (https://github.com/Comfy-Org/ComfyUI_frontend/pull/17000#discussion_r3938354883). The analysis-side half was fixed in that PR; this is the deferred emission-side half.
Contributor guide
Research direction
Start in useSubscriptionInternal() and trace reportMissingCheckoutCompletion(), pendingCheckoutRecoveryAttempt, and clearPendingSubscriptionCheckoutAttempt(). Review the existing PENDING_SUBSCRIPTION_CHECKOUT_MAX_AGE_MS handling and the session or local storage behavior, then run or extend the relevant tests for reloads and concurrent tabs. Done means one report per attempt_id and cleanup when the attempt is cleared or expires.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100