Skip to content

fix: reset project completed status when order expires or refunds#185

Merged
yyg-max merged 5 commits into
linux-do:masterfrom
q3cc:fix/reset-completed-status-after-order-expiration
Jun 23, 2026
Merged

fix: reset project completed status when order expires or refunds#185
yyg-max merged 5 commits into
linux-do:masterfrom
q3cc:fix/reset-completed-status-after-order-expiration

Conversation

@q3cc

@q3cc q3cc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Problem

When users reserve paid CDK items but don't complete payment, the following issue occurs:

  1. User reserves an item → item is LPOPed from Redis
  2. All items are reserved → Redis stock becomes 0
  3. One user completes payment → project is marked as IsCompleted=true
  4. Other orders expire after 15 minutes → items are RPushed back to Redis
  5. Issue: IsCompleted remains true even though Redis has stock again
  6. Result: Frontend shows "Project Completed" and users cannot claim available items

例行检查

  • x 我已阅读并理解 贡献者公约
  • x 我已阅读并同意 贡献者许可协议 (CLA),确认我的贡献将根据项目的 MIT 许可证进行许可,
  • x 我知晓如果此 PR 并不做出实质性更改,或可被认为是为了PR被合并而提交PR的,则可能不会被合并,

Root Cause

  • FulfillForReceiver() sets IsCompleted=true when Redis stock is 0
  • expireOrder() returns items to Redis but doesn't reset IsCompleted
  • Frontend checks is_completed field and disables the claim button
  • Backend only checks Redis stock in IsReceivable(), not IsCompleted

Solution

Added logic to check and reset IsCompleted when items are returned to inventory:

Changes

  1. tasks.go: Added resetProjectCompletedStatus()

    • Called after expireOrder() returns items to Redis
    • Checks if project has IsCompleted=true but Redis has stock
    • Resets IsCompleted=false if condition met
  2. service.go: Added resetProjectCompletedStatusAfterRefund()

    • Called when refund succeeds and items are returned
    • Handles both immediate refund and retry scenarios
    • Same logic as expiration cleanup

Testing

  • ✅ Compiled successfully without errors
  • ✅ Logic verified for both expiration and refund paths
  • ✅ CAS update with WHERE clause ensures idempotency

Impact

  • Projects will correctly show as available after expired orders release items
  • No breaking changes to existing functionality
  • Minimal performance impact (one query per expired order)

Fixes the issue where legitimate users cannot claim items that become available after order expiration.

Issue: When all items are reserved but users don't complete payment, the project gets marked as completed even after orders expire and items are returned to stock.

Changes:
- Add resetProjectCompletedStatus in tasks.go to check and reset IsCompleted flag when expired orders return items
- Add resetProjectCompletedStatusAfterRefund in service.go to handle refund scenarios
- Reset IsCompleted when Redis has stock but project is marked as completed
- Applied to both order expiration cleanup and refund success paths

This ensures projects become available again after reserved items are released back to inventory.
@q3cc

q3cc commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

看起来 在 LDC 系统中 支付过期时间是 5 分钟 为什么这里 15 分钟才回放()

@yyg-max yyg-max requested a review from Noxiven June 16, 2026 07:27

@yyg-max yyg-max left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

1.resetProjectCompletedStatusAfterRefund和resetProjectCompletedStatus合并为一个放到Project当作函数方法/放utils.go
2.补上合适的事务

…ct method

- Merge resetProjectCompletedStatusAfterRefund and resetProjectCompletedStatus into single method
- Add Project.ResetCompletedStatusIfHasStock() in utils.go
- Remove 65 lines of duplicate code across service.go and tasks.go
- Maintain original code style without logging
@q3cc q3cc requested a review from yyg-max June 16, 2026 08:28

@yyg-max yyg-max left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

事务还是没看到,可以参考项目写的

Comment thread internal/apps/project/utils.go Outdated
@q3cc q3cc force-pushed the fix/reset-completed-status-after-order-expiration branch from 6f1cfc8 to ce443c2 Compare June 17, 2026 02:33
q3cc added 2 commits June 17, 2026 10:35
…ansaction

- Move method from utils.go to models.go per maintainer feedback
- Wrap logic in db.Transaction() for atomicity
- Add error handling at all call sites (tasks.go and service.go)
- Log errors when reset fails for better observability
@q3cc q3cc requested a review from yyg-max June 17, 2026 02:38
Comment thread internal/apps/project/models.go Outdated
@q3cc q3cc requested a review from yyg-max June 17, 2026 03:16
@q3cc q3cc force-pushed the fix/reset-completed-status-after-order-expiration branch from 5044c87 to 74e4719 Compare June 17, 2026 07:23
Comment thread internal/apps/payment/service.go Outdated
@q3cc q3cc force-pushed the fix/reset-completed-status-after-order-expiration branch from 74e4719 to 142d440 Compare June 18, 2026 03:26
@q3cc q3cc requested a review from yyg-max June 18, 2026 03:27
@yyg-max yyg-max merged commit 56e4456 into linux-do:master Jun 23, 2026
11 checks passed
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