Skip to content

Conversation

@Catrya
Copy link
Member

@Catrya Catrya commented Oct 8, 2025

close #326

  - Replace timeout detection for waiting-buyer-invoice/waiting-payment → pending
  - Handle via direct gift wraps: Action.canceled (taker) / Action.newOrder (maker)
  - Remove 38383 event monitoring for timeout scenarios only
  - Eliminate timeout-specific logic: _checkTimeoutAndCleanup, _subscribeToPublicEvents
  - Remove Action.timeoutReversal enum and all related logic
  - Remove MostroMessage.createTimeoutReversal() factory method
  - Clean up FSM transitions and notification handling
  - Remove timeout detection constants from Config
  - Update documentation

Summary by CodeRabbit

  • New Features

    • Switched to gift-wrap–based timeout and cancellation handling; direct encrypted messages now drive order timeouts, reactivations, and cleanup.
  • Notifications

    • Added explicit maker reactivation and cancellation notifications; removed the dedicated “timeout reversal” notification path—those events now surface as generic/temporary notifications.
  • UI

    • Unified order detail status/action display and pending-state behavior; removed special “timeout reversal” messaging.
  • Documentation

    • Rewrote architecture and timeout/cleanup docs to reflect the gift-wrap–centric model and updated flows.

Catrya added 4 commits October 8, 2025 15:17
  - Replace timeout detection for waiting-buyer-invoice/waiting-payment → pending
  - Handle via direct gift wraps: Action.canceled (taker) / Action.newOrder (maker)
  - Remove 38383 event monitoring for timeout scenarios only
  - Eliminate timeout-specific logic: _checkTimeoutAndCleanup, _subscribeToPublicEvents
  - Preserve other functionality unchanged
  - Remove Action.timeoutReversal enum and all related logic
  - Remove MostroMessage.createTimeoutReversal() factory method
  - Clean up FSM transitions and notification handling
  - Remove timeout detection constants from Config
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Walkthrough

Replaces timestamp/public-event timeout detection with gift-wrap instruction processing. Removes Action.timeoutReversal and its factory, drops related config constants, centralizes session deletion and notifications in notifiers, updates notification/UI mappings, and rewrites docs to describe the gift-wrap-based flow.

Changes

Cohort / File(s) Summary
Docs: timeout/session model rewrite
CLAUDE.md, docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md
Rewrote timeout detection to a gift-wrap-based model; updated components, dataflows, maker/taker behaviors, and examples; refreshed last-updated.
Config cleanup
lib/core/config.dart
Removed notificationChannelId, notificationId, timeoutDetectionTimeout, and messageStorageTimeout.
Action enum update
lib/data/models/enums/action.dart
Removed Action.timeoutReversal.
Mostro message model
lib/data/models/mostro_message.dart
Removed MostroMessage.createTimeoutReversal(...) factory and related imports.
Notification typing & mapping
lib/data/models/notification.dart, lib/features/notifications/utils/notification_data_extractor.dart, lib/features/notifications/utils/notification_message_mapper.dart
Removed explicit timeoutReversal handling; such actions now fall through to default/temporary/system mappings.
Notification UI interaction
lib/features/notifications/widgets/notification_item.dart
Removed timeoutReversal tap case; action now falls through to other handlers.
Order state mapping
lib/features/order/models/order_state.dart
Removed timeoutReversal handling from status derivation and pending-state action maps.
Mostro notifier: core flow
lib/features/order/notfiers/abstract_mostro_notifier.dart, lib/features/order/notfiers/order_notifier.dart, lib/features/order/notfiers/...
Shifted timeout/cancel handling to gift-wrap actions: superclass handles newOrder reactivation and explicit canceled session deletion/notifications/navigation; removed timestamp/timer-based helpers and the timeoutReversal branches; order_notifier delegates and subscribes to public events.
Trades detail UI
lib/features/trades/widgets/mostro_message_detail_widget.dart
Removed timeoutReversal-specific text path; unified action/status display.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Mostro
  participant App as App (AbstractMostroNotifier)
  participant Sess as SessionStore
  participant UI as UI / Notifier

  rect #E6F5FF
    note right of Mostro: Gift-wrap messages drive timeout/cancel flow
    Mostro->>App: gift-wrap(Action.newOrder, orderId, payload)
    alt Existing session in waiting-buyer-invoice / waiting-payment
      App->>UI: emit orderTimeoutMaker notification
      App->>Sess: update session -> Pending
      UI-->>User: show pending + notification
    else No existing session
      App->>Sess: store/init session
    end
  end

  rect #FFF2E6
    Mostro->>App: gift-wrap(Action.canceled, orderId)
    App->>Sess: delete session
    App->>UI: emit orderCanceled notification
    App->>UI: conditional navigate home
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • grunch

Poem

I hop through wraps and skip the clock,
NewOrder sings and canceled knocks.
Sessions tucked or set to Pending,
No made-up reversals, just gifts amending.
A rabbit’s tidy cleanup—bounce and hop! 🐇🎁

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Refactor: flow from waiting to pending status" is directly related to a core aspect of the changeset. The pull request fundamentally refactors how orders transition between states (from waiting-buyer-invoice/waiting-payment to pending), replacing timeout-based detection with direct gift-wrap action handling. While the title doesn't capture the full architectural scope of replacing 38383 event monitoring with gift-wrap instructions, it accurately describes a real and significant part of the change: the status flow transitions that result from this refactor. The title is specific and clear enough that teammates scanning history would understand this involves status flow changes.
Linked Issues Check ✅ Passed The code changes comprehensively implement all requirements from issue #326. For taker cancellations, Action.canceled handling now deletes the session via sessionNotifier and displays a cancellation notification. For maker reactivation, Action.newOrder with the same order ID detects republishing after taker timeout, returns the order to pending state, and shows the orderTimeoutMaker notification. The PR eliminates the entire timeout-based detection mechanism by removing Action.timeoutReversal, the createTimeoutReversal() factory method, timeout detection constants from Config, and the 38383 event subscription logic. These changes replace the problematic delayed-relay issue with direct Mostro-initiated gift wrap messages as specified in the issue requirements.
Out of Scope Changes Check ✅ Passed All code changes in this PR are directly aligned with the scope defined in issue #326. The modifications include removing the timeout reversal action and factory method, updating notification handling to remove timeout-specific logic, cleaning up Config constants related to timeout detection, refactoring notifier classes to handle gift-wrap actions, updating UI widgets to remove timeout reversal references, and updating architecture documentation to reflect the new gift-wrap-based approach. Each change either removes legacy timeout-based logic or implements the new gift-wrap-driven state transition mechanism. No unrelated refactoring, bug fixes, or feature additions outside the stated objectives are present.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refectorWaiting-to-Pending

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: 0

🧹 Nitpick comments (1)
docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md (1)

145-145: Fix markdown linting issues.

Three fenced code blocks (lines 145, 154, 486) are missing language specifiers. While this doesn't affect functionality, it's good practice to specify the language for proper syntax highlighting.

Apply this diff to add language specifiers:

 #### **Behavior by Gift Wrap Action**
 
 **MAKER (Order Creator) - Receives `Action.newOrder`**:
-```
+```text
 1. User creates order → Someone takes it → waiting state in My Trades
 2. Taker doesn't respond → Mostro sends Action.newOrder gift wrap to maker
 **TAKER (Order Accepter) - Receives `Action.canceled`**:
-```
+```text
 1. User takes order → Order appears in My Trades with waiting state
 2. User doesn't respond in time → Mostro sends Action.canceled gift wrap to taker
 ### Complete Gift Wrap Flow
 
-```
+```text
 1. Order in waiting state (waitingBuyerInvoice or waitingPayment)
 2. Timeout occurs on Mostro server

Also applies to: 154-154, 486-486

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a1d667 and 64f8a17.

📒 Files selected for processing (13)
  • CLAUDE.md (2 hunks)
  • docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md (6 hunks)
  • lib/core/config.dart (0 hunks)
  • lib/data/models/enums/action.dart (1 hunks)
  • lib/data/models/mostro_message.dart (0 hunks)
  • lib/data/models/notification.dart (0 hunks)
  • lib/features/notifications/utils/notification_data_extractor.dart (0 hunks)
  • lib/features/notifications/utils/notification_message_mapper.dart (0 hunks)
  • lib/features/notifications/widgets/notification_item.dart (0 hunks)
  • lib/features/order/models/order_state.dart (0 hunks)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (1 hunks)
  • lib/features/order/notfiers/order_notifier.dart (1 hunks)
  • lib/features/trades/widgets/mostro_message_detail_widget.dart (1 hunks)
💤 Files with no reviewable changes (7)
  • lib/features/order/models/order_state.dart
  • lib/data/models/mostro_message.dart
  • lib/features/notifications/utils/notification_data_extractor.dart
  • lib/core/config.dart
  • lib/data/models/notification.dart
  • lib/features/notifications/utils/notification_message_mapper.dart
  • lib/features/notifications/widgets/notification_item.dart
🧰 Additional context used
📓 Path-based instructions (5)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/data/models/enums/action.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/data/models/enums/action.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
lib/data/**

📄 CodeRabbit inference engine (AGENTS.md)

Store persistence and API code under lib/data/

Files:

  • lib/data/models/enums/action.dart
docs/**

📄 CodeRabbit inference engine (AGENTS.md)

Store additional project guidance and documentation in docs/

Files:

  • docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md
🧠 Learnings (2)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
📚 Learning: 2025-07-20T23:33:17.689Z
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Applied to files:

  • lib/features/order/notfiers/order_notifier.dart
🪛 markdownlint-cli2 (0.18.1)
docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md

145-145: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


154-154: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


486-486: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (7)
lib/features/trades/widgets/mostro_message_detail_widget.dart (1)

45-45: LGTM! Simplified UI rendering aligns with timeoutReversal removal.

The change simplifies the UI by always displaying the combined status and action, eliminating the previous conditional path for timeoutReversal. This is consistent with the removal of Action.timeoutReversal across the codebase and the shift to gift wrap-based timeout handling.

lib/data/models/enums/action.dart (1)

41-41: LGTM! timeoutReversal removal is consistent with gift wrap-based flow.

The removal of the timeoutReversal enum member aligns with the PR's shift from synthetic timeout messages to direct gift wrap instructions (Action.newOrder and Action.canceled). This change is consistent with updates across notification handling, message factories, and UI components.

lib/features/order/notfiers/order_notifier.dart (1)

19-24: LGTM! Timeout handling correctly delegated to AbstractMostroNotifier.

The simplified implementation correctly delegates timeout and cancellation logic to AbstractMostroNotifier. The synchronous handleEvent call (without await) is correct per the established pattern where handleEvent returns void, not Future<void>.

Based on learnings.

lib/features/order/notfiers/abstract_mostro_notifier.dart (2)

141-154: LGTM! Maker timeout reactivation correctly implemented.

The newOrder handling correctly detects timeout reactivation for makers:

  • Validates session exists and order is in a waiting state (waitingBuyerInvoice or waitingPayment)
  • Preserves the session (allows order to return to pending)
  • Shows appropriate notification to maker
  • Consistent with PR objectives where makers receive Action.newOrder after taker timeout

156-180: Verify error handling for session deletion.

The cancellation handling correctly deletes sessions and navigates appropriately. However, the await sessionNotifier.deleteSession(orderId) call at line 164 lacks explicit error handling. If session deletion fails, the user still sees the notification and navigation occurs, potentially leaving orphaned state.

Consider wrapping the session deletion in a try-catch block:

         // Delete session - this applies to both maker and taker scenarios
         final sessionNotifier = ref.read(sessionNotifierProvider.notifier);
-        await sessionNotifier.deleteSession(orderId);
+        try {
+          await sessionNotifier.deleteSession(orderId);
+        } catch (e) {
+          logger.e('Failed to delete session for canceled order $orderId', error: e);
+          // Continue with notification/navigation even if deletion fails
+        }
         
         logger.i('Session deleted for canceled order $orderId');

Do you want me to verify if deleteSession already has internal error handling that makes this wrapper unnecessary?

CLAUDE.md (1)

144-184: LGTM! Documentation accurately reflects gift wrap-based implementation.

The updated documentation correctly describes the new gift wrap-based timeout detection:

  • Direct instruction processing via encrypted messages (no monitoring/timestamp comparison)
  • Maker scenario receives Action.newOrder with session preservation
  • Taker scenario receives Action.canceled with session deletion
  • Simplified logic compared to previous public event monitoring

Documentation is consistent with the implementation in abstract_mostro_notifier.dart.

docs/architecture/TIMEOUT_DETECTION_AND_SESSION_CLEANUP.md (1)

42-137: LGTM! Comprehensive documentation of gift wrap-based timeout detection.

The updated timeout detection section thoroughly documents the new implementation:

  • Direct gift wrap instruction processing replaces public event monitoring
  • Clear code examples from AbstractMostroNotifier showing newOrder and canceled handling
  • Maker/taker scenarios correctly described with session lifecycle details
  • Simplified detection logic well explained

Documentation accurately reflects the implementation changes across the PR.

@Catrya Catrya marked this pull request as draft October 8, 2025 23:12
@Catrya Catrya changed the title Refector waiting to pending Refactor: flow from waiting to pending status Oct 8, 2025
@Catrya Catrya marked this pull request as ready for review October 9, 2025 16:12
@Catrya
Copy link
Member Author

Catrya commented Oct 9, 2025

@coderabbitai review all

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 9, 2025

@Catrya: I'll review all the changes in this PR.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

… events

  - Add selective public event monitoring in OrderNotifier
  - Detect when Mostro automatically cancels pending orders (pending → canceled)
  - Delete session to remove expired orders from My Trades
  - Show cancellation notification to user
  - Maintain existing gift wrap timeout system unchanged
  - Only affects maker-created orders that expire automatically
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64f8a17 and 4b982a6.

📒 Files selected for processing (1)
  • lib/features/order/notfiers/order_notifier.dart (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/order/notfiers/order_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/order/notfiers/order_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/order/notfiers/order_notifier.dart
🧠 Learnings (2)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/order_notifier.dart
📚 Learning: 2025-07-20T23:33:17.689Z
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Applied to files:

  • lib/features/order/notfiers/order_notifier.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
lib/features/order/notfiers/order_notifier.dart (2)

24-29: LGTM: Timeout logic correctly delegated to superclass.

The simplified handleEvent implementation correctly delegates timeout and cancellation handling to AbstractMostroNotifier, centralizing the logic as intended by the refactoring.


163-163: Verify localization of notification message.

The hardcoded string 'orderCanceled' is passed to showCustomMessage(). Per coding guidelines, user-facing strings must use S.of(context).keyName for localization.

Verify that showCustomMessage() internally handles localization for this key, or if the caller should pass a localized string instead.

As per coding guidelines.

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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b982a6 and 824fadd.

📒 Files selected for processing (2)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (1 hunks)
  • lib/features/order/notfiers/order_notifier.dart (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
🧠 Learnings (2)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/features/order/notfiers/order_notifier.dart
📚 Learning: 2025-07-20T23:33:17.689Z
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.

Applied to files:

  • lib/features/order/notfiers/order_notifier.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (3)
lib/features/order/notfiers/order_notifier.dart (3)

20-20: LGTM!

The placement of _subscribeToPublicEvents() in the constructor is appropriate, ensuring public event monitoring starts when the notifier is initialized.


25-28: LGTM!

The delegation to the superclass is correct. The comment accurately reflects that timeout/cancellation logic has been centralized in AbstractMostroNotifier.


180-183: LGTM!

Proper cleanup of the subscription in the dispose method.

@Catrya Catrya requested a review from grunch October 21, 2025 03:07
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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 824fadd and a46a26d.

📒 Files selected for processing (2)
  • lib/features/order/models/order_state.dart (0 hunks)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (1 hunks)
💤 Files with no reviewable changes (1)
  • lib/features/order/models/order_state.dart
🧰 Additional context used
📓 Path-based instructions (3)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🧠 Learnings (2)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
PR: MostroP2P/mobile#327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🔇 Additional comments (1)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)

142-155: LGTM - Maker reactivation handling is well-implemented.

The logic correctly identifies when a maker receives order republication after taker timeout by checking for an existing session with waitingBuyerInvoice or waitingPayment status. The notification pattern follows the established two-layer localization architecture.

Based on learnings.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/features/order/notfiers/abstract_mostro_notifier.dart (2)

60-70: Maker reactivation condition uses post-hydration status; likely never true. Capture previousStatus before update and use it here.

Since state is updated with msg before handleEvent, state.status will already be pending on Action.newOrder, so the waitingBuyerInvoice/waitingPayment check won’t match. Also tighten the timestamp gate and ensure session is set.

Apply:

@@
-              if (mounted) {
-                state = state.updateWith(msg);
-              }
+              // capture pre-hydration status for side-effect decisions
+              final previousStatus = state.status;
+              if (mounted) {
+                state = state.updateWith(msg);
+              }
@@
-                logger.i('Message timestamp check passed, calling handleEvent for ${msg.action}');
-                unawaited(handleEvent(msg));
+                logger.i('Message timestamp check passed, calling handleEvent for ${msg.action}');
+                unawaited(handleEvent(msg, previousStatus: previousStatus));
@@
-  Future<void> handleEvent(MostroMessage event, {bool bypassTimestampGate = false}) async {
+  Future<void> handleEvent(MostroMessage event, {bool bypassTimestampGate = false, Status? previousStatus}) async {
@@
       case Action.newOrder:
-        // Check if Mostro is republishing the order after timeout
+        // Check if Mostro is republishing the order after timeout
         final currentSession = ref.read(sessionProvider(orderId));
-        if (currentSession != null && 
-            (state.status == Status.waitingBuyerInvoice || state.status == Status.waitingPayment)) {
+        if (currentSession != null &&
+            (previousStatus == Status.waitingBuyerInvoice || previousStatus == Status.waitingPayment)) {
+          // keep local session in sync
+          session = currentSession;
           // This is a maker receiving order republication after taker timeout
           logger.i('MAKER: Received order reactivation from Mostro - taker timed out, order returned to pending');
           
           // Show notification: counterpart didn't respond, order will be republished
-          if (isRecent || !bypassTimestampGate) {
+          if (isRecent && !bypassTimestampGate) {
             final notifProvider = ref.read(notificationActionsProvider.notifier);
             notifProvider.showCustomMessage('orderTimeoutMaker');
           }
         }
         break;

This ensures the branch triggers correctly and side effects remain gated to recent events. Based on learnings.

Also applies to: 105-105, 142-155


20-21: Uninitialized late Session session field creates LateInitializationError risk at line 124.

Constructor initialization (line 41) is conditional: if getSessionByOrderId(orderId) returns null, the session field is never set. When handleEvent later calls extractFromMostroMessage(event, ref, session: session) at line 124, accessing the uninitialized late field crashes.

Since the extractor accepts nullable Session?, change late Session session; to Session? session; and initialize it to null, then pass it safely to the extractor.

🧹 Nitpick comments (1)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)

123-136: Tighten notification gating to match intent (“Only notify for recent events”).

Current condition (isRecent || !bypassTimestampGate) allows notifications whenever the gate isn’t bypassed. Make it strictly recent + not bypassed.

-    if (notificationData != null && (isRecent || !bypassTimestampGate)) {
+    if (notificationData != null && isRecent && !bypassTimestampGate) {
       sendNotification(
         notificationData.action,
         values: notificationData.values,
         isTemporary: notificationData.isTemporary,
         eventId: notificationData.eventId,
       );
-    } else if (notificationData != null && bypassTimestampGate) {
+    } else if (notificationData != null && bypassTimestampGate) {
       logger.i('Skipping notification for old event: ${event.action} (timestamp: ${event.timestamp})');
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a46a26d and 0546d57.

📒 Files selected for processing (1)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🧠 Learnings (3)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
PR: MostroP2P/mobile#327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: 2025-10-01T14:10:17.742Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-01T14:10:17.742Z
Learning: Applies to lib/**/*.dart : Check `mounted` before using BuildContext after async gaps

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🔇 Additional comments (1)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)

157-184: Verified: no double-notification risk. Extractor returns null for Action.canceled.

The NotificationDataExtractor explicitly returns null for Action.canceled with the comment "Canceled orders don't generate persistent notifications," so the manual showCustomMessage('orderCanceled') call at line 175 is the only notification path and poses no duplication risk. The implementation is correct.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0546d57 and 27944c4.

📒 Files selected for processing (1)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
lib/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/*.dart: Use post-frame callbacks for UI side effects (e.g., SnackBars/dialogs)
Use S.of(context).keyName for all user-facing strings (no hardcoded text)
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization (use S.of(context))
Check mounted before using BuildContext after async gaps
Use const constructors where possible

Name Riverpod providers as Provider or Notifier

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: All code comments must be in English
Use clear, concise English for variable and function names
Maintain zero flutter analyze issues
Use latest Flutter/Dart APIs (e.g., prefer withValues() over withOpacity())
Remove unused imports and dependencies

**/*.dart: Use Dart formatter defaults (two-space indentation, trailing commas) and run flutter format before committing
Resolve all Flutter analyzer warnings (flutter analyze must be clean)

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
lib/features/**

📄 CodeRabbit inference engine (AGENTS.md)

Place application feature code under lib/features//, grouped by domain

Files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🧠 Learnings (2)
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
PR: MostroP2P/mobile#327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🔇 Additional comments (1)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)

141-155: LGTM! Maker reactivation logic correctly implemented.

The detection of order republication after taker timeout is sound. The session and status checks properly identify the maker scenario, and the notification uses the correct two-layer localization pattern established in the codebase.

Copy link
Member

@grunch grunch left a comment

Choose a reason for hiding this comment

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

tACK

@grunch grunch merged commit 423fe62 into main Oct 22, 2025
2 checks passed
@grunch grunch deleted the refectorWaiting-to-Pending branch October 22, 2025 12:28
@coderabbitai coderabbitai bot mentioned this pull request Oct 25, 2025
4 tasks
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.

Change the flow when an order returns to Pending or is Canceled because the user does not respond

4 participants