Skip to content

feat: auto-close dispute UI when order reaches terminal state #503

Open
Catrya wants to merge 5 commits intomainfrom
auto-close-dispute
Open

feat: auto-close dispute UI when order reaches terminal state #503
Catrya wants to merge 5 commits intomainfrom
auto-close-dispute

Conversation

@Catrya
Copy link
Member

@Catrya Catrya commented Feb 27, 2026

fix #494

  • Auto-close dispute when seller releases sats (settledHoldInvoice/success)
  • Auto-close dispute on cooperative cancellation (canceled)
  • Differentiate closure reason via dispute.action: 'user-completed' vs 'cooperative-cancel'
  • Show distinct messages in dispute list and detail view per closure type
  • Add localization keys in en/es/it/fr for both closure messages

Summary by CodeRabbit

  • New Features

    • Disputes auto-close when orders reach terminal completion or cooperative-cancellation states.
    • UI displays distinct messages for "user-completed" and "cooperative-cancel" closures.
    • Trade/status UI now shows cooperative-cancel as a "Canceling" / waiting state instead of a canceled/inactive state.
    • Added localized strings for the new statuses and closure messages (EN/ES/FR/IT).
  • Documentation

    • Added guidance explaining dispute auto-close behavior and rationale.

  - Auto-close dispute when seller releases sats (settledHoldInvoice/success)
  - Auto-close dispute on cooperative cancellation (canceled)
  - Differentiate closure reason via dispute.action: 'user-completed' vs 'cooperative-cancel'
  - Show distinct messages in dispute list and detail view per closure type
  - Add localization keys in en/es/it/fr for both closure messages
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Warning

Rate limit exceeded

@Catrya has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 7e08f75 and a83dac1.

📒 Files selected for processing (1)
  • docs/architecture/ORDER_STATUS_HANDLING.md

Walkthrough

When an order reaches a terminal state (success/settledHoldInvoice or cooperative cancel), the app auto-marks any associated dispute as closed with an action (user-completed or cooperative-cancel) and the UI/localizations display action-specific closed messages.

Changes

Cohort / File(s) Summary
Dispute Model
lib/data/models/dispute.dart
Treat closed as a resolved dispute state and map specific action values (user-completed, cooperative-cancel) to distinct description keys.
Dispute UI
lib/features/disputes/widgets/dispute_status_content.dart
Show disputeClosedUserCompleted or disputeClosedCooperativeCancel when resolved/closed dispute action matches those values; preserves existing fallbacks.
Order State Auto-Close
lib/features/order/models/order_state.dart
On order transition to terminal states (Status.success / Status.settledHoldInvoice) or canceled with cooperative-cancel action, set associated dispute to closed with appropriate action and log the auto-close.
Trades UI
lib/features/trades/widgets/trades_list_item.dart
Treat Status.cooperativelyCanceled as a separate case, showing a waiting background and canceling label instead of the canceled style.
Localization
lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_fr.arb, lib/l10n/intl_it.arb
Add cancelingStatus, disputeClosedUserCompleted, and disputeClosedCooperativeCancel localization keys across languages.
Docs
docs/architecture/ORDER_STATUS_HANDLING.md
Document "Dispute Auto-Close on Terminal State" behavior, triggers, rationale, and UI messaging implications.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant App as Mobile App
    participant OrderState as OrderState
    participant DisputeState as DisputeState
    participant UI as Dispute UI

    User->>App: Completes or cooperatively cancels order
    App->>OrderState: Order transitions to terminal state (success / settledHoldInvoice / canceled)
    OrderState->>OrderState: Locate dispute by orderId
    alt dispute exists and not terminal
        OrderState->>DisputeState: Set dispute.status = "closed", action = "user-completed" / "cooperative-cancel"
    end
    DisputeState->>UI: Emit updated dispute state
    UI->>UI: Select localized message based on dispute.action
    UI->>App: Render closed dispute message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • AndreaDiazCorreia
  • grunch

Poem

🐇 I sniffed the order, hopped to see,
Parties done—no quarrel for me.
I closed the case with a gentle thump,
Hops and carrots — dispute at rump! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive The PR includes changes to trades_list_item.dart for the 'Canceling' status display, which is related to the cooperative cancellation flow mentioned in the PR objectives but goes slightly beyond the core dispute auto-close scope. Clarify whether the trades_list_item.dart change (Status.cooperativelyCanceled handling) is integral to the dispute auto-close feature or should be separated into a distinct PR.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: automatically closing disputes in the UI when orders reach terminal states, which is the core objective.
Linked Issues check ✅ Passed The PR implements all coding requirements from #494: auto-closes disputes on terminal order states (success/settledHoldInvoice/canceled), differentiates closure reasons via dispute.action values, shows distinct UI messages, and adds localization keys.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch auto-close-dispute

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/features/order/models/order_state.dart`:
- Around line 194-213: The auto-close branch that sets updatedDispute to action
'cooperative-cancel' currently fires whenever newStatus == Status.canceled;
change it to only run for cooperative cancellation flows by adding a check for
the triggering cancellation action (e.g., require the cancellation Action to be
the cooperative cancel action rather than Action.cancel /
Action.holdInvoicePaymentCanceled / Action.adminCancel). Update the if condition
around updatedDispute.copyWith(... action: 'cooperative-cancel' ...) to verify
the specific cooperative cancellation action (use the existing Action
enum/variable used when status transitions occur) before assigning
'cooperative-cancel' and logging the cooperative message.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4f1bde5 and f98f06f.

📒 Files selected for processing (7)
  • lib/data/models/dispute.dart
  • lib/features/disputes/widgets/dispute_status_content.dart
  • lib/features/order/models/order_state.dart
  • lib/l10n/intl_en.arb
  • lib/l10n/intl_es.arb
  • lib/l10n/intl_fr.arb
  • lib/l10n/intl_it.arb

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
lib/features/order/models/order_state.dart (1)

194-214: LGTM! Past review concern properly addressed.

The cooperative-cancel branch now correctly guards against non-cooperative cancellation actions by checking message.action == Action.cooperativeCancelAccepted (line 208). This ensures 'cooperative-cancel' is only assigned for actual cooperative cancellations, not for Action.cancel, Action.holdInvoicePaymentCanceled, or Action.adminCancel.

Optional refactor: The terminal dispute status list is duplicated. Consider extracting it:

♻️ Optional: Extract constant for terminal dispute statuses
+  static const _terminalDisputeStatuses = {'resolved', 'seller-refunded', 'closed'};
+
   // Auto-close dispute when order reaches terminal state by user action
   if (updatedDispute != null &&
-      !const ['resolved', 'seller-refunded', 'closed']
-          .contains(updatedDispute.status?.toLowerCase()) &&
+      !_terminalDisputeStatuses.contains(updatedDispute.status?.toLowerCase()) &&
       const [Status.success, Status.settledHoldInvoice].contains(newStatus)) {
     // ...
   } else if (updatedDispute != null &&
-      !const ['resolved', 'seller-refunded', 'closed']
-          .contains(updatedDispute.status?.toLowerCase()) &&
+      !_terminalDisputeStatuses.contains(updatedDispute.status?.toLowerCase()) &&
       newStatus == Status.canceled &&
       message.action == Action.cooperativeCancelAccepted) {

,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/features/order/models/order_state.dart` around lines 194 - 214, Duplicate
literal list of terminal dispute statuses should be extracted to a single
constant; create a top-level const like terminalDisputeStatuses = ['resolved',
'seller-refunded', 'closed'] and replace both occurrences of the inline const
list in the updatedDispute guards (the first if and the else-if that check
updatedDispute.status?.toLowerCase()) with terminalDisputeStatuses to remove
duplication and improve readability while keeping the existing logic in the
order state update flow (refer to the updatedDispute null checks and the
newStatus/ message.action conditions).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/features/order/models/order_state.dart`:
- Around line 194-214: Duplicate literal list of terminal dispute statuses
should be extracted to a single constant; create a top-level const like
terminalDisputeStatuses = ['resolved', 'seller-refunded', 'closed'] and replace
both occurrences of the inline const list in the updatedDispute guards (the
first if and the else-if that check updatedDispute.status?.toLowerCase()) with
terminalDisputeStatuses to remove duplication and improve readability while
keeping the existing logic in the order state update flow (refer to the
updatedDispute null checks and the newStatus/ message.action conditions).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f98f06f and 9eefcd1.

📒 Files selected for processing (2)
  • docs/architecture/ORDER_STATUS_HANDLING.md
  • lib/features/order/models/order_state.dart
✅ Files skipped from review due to trivial changes (1)
  • docs/architecture/ORDER_STATUS_HANDLING.md

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.

feat: auto-close dispute UI when order reaches terminal state

1 participant