Skip to content

feat(bond): Phase 3.5 payout confirmation actions on mobile#603

Open
Catrya wants to merge 1 commit into
mainfrom
anti-abuse-bond-phase35
Open

feat(bond): Phase 3.5 payout confirmation actions on mobile#603
Catrya wants to merge 1 commit into
mainfrom
anti-abuse-bond-phase35

Conversation

@Catrya
Copy link
Copy Markdown
Member

@Catrya Catrya commented May 22, 2026

  • Add and to the Action enum
  • Add helper (none/pending/acknowledged/completed) with retry support
  • Bond payout screen: hide form on acknowledged/completed, show info + single CLOSE button
  • My Trades badge: PAYOUT IN PROGRESS on acknowledged; order's real status on completed
  • Trade Details: extend the previous non-bond message with a bond-paid line; rate hint only if is in history
  • : accept default to
  • : keep tracked order untouched on bond acks; preserve current status (don't fall to default)
  • Notification extractor: return null for the two new actions (no SnackBar fires)
  • Exhaustive switches in notification mapper/item updated as no-ops (compiler requirement; functional wiring deferred)
  • l10n: new keys in en/es/it/de/fr
  • Tests: bond payout helpers 9→17 cases; regression test for

Summary by CodeRabbit

  • New Features

    • Added bond invoice acceptance and payout completion support with dedicated UI flows and localized messaging across five languages.
    • Introduced bond payout phase tracking for improved order state management.
  • Bug Fixes

    • Made order status field optional to handle edge case payloads.
  • Tests

    • Added comprehensive test coverage for bond payout phase transitions and order parsing.

Review Change Stack

  - Add  and  to the Action enum
  - Add  helper (none/pending/acknowledged/completed) with retry support
  - Bond payout screen: hide form on acknowledged/completed, show info + single CLOSE button
  - My Trades badge: PAYOUT IN PROGRESS on acknowledged; order's real status on completed
  - Trade Details: extend the previous non-bond message with a bond-paid line; rate hint only if  is in
  history
  - : accept  default to
  - : keep tracked order untouched on bond acks; preserve current status (don't fall to
  default)
  - Notification extractor: return null for the two new actions (no SnackBar fires)
  - Exhaustive switches in notification mapper/item updated as no-ops (compiler requirement; functional wiring
  deferred)
  - l10n: new keys in en/es/it/de/fr
  - Tests: bond payout helpers 9→17 cases; regression test for
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Walkthrough

This PR implements support for two new bond-related actions—bondInvoiceAccepted and bondPayoutCompleted—to recognize and display invoice acceptance and payout completion in the anti-abuse bond flow. Changes include a new phase-state machine, order state preservation during acknowledgement, dedicated UI for completed phases, updated trade/message detail displays, and full localization.

Changes

Bond Payout Acknowledgement & Completion

Layer / File(s) Summary
Action enum and Order model updates
lib/data/models/enums/action.dart, lib/data/models/order.dart, test/models/order_test.dart
Action enum adds bondInvoiceAccepted and bondPayoutCompleted entries. Order.fromJson treats status as optional, defaulting to Status.pending when absent or null, with test coverage for null status parsing.
Bond payout phase determination
lib/shared/utils/bond_payout_helpers.dart, test/shared/utils/bond_payout_helpers_test.dart
Introduces BondPayoutPhase enum (none/pending/acknowledged/completed) and bondPayoutPhase(messages) function that computes current phase from timestamped bond-related messages, with tests covering pending, acknowledged, completed, and retry scenarios.
Order state preservation for bond ack actions
lib/features/order/models/order_state.dart
OrderState.updateWith detects bond payout ack actions and prevents order field replacement. _getStatusFromAction preserves current status for ack actions instead of deriving from payload to avoid accidental state transitions.
Bond payout invoice screen conditional rendering
lib/features/order/screens/bond_payout_invoice_screen.dart
Screen checks computed bond phase and renders informational UI with phase-specific localized message and close button for acknowledged/completed phases; original submission form remains the fallback for pending phase.
Message detail and trade list UI updates
lib/features/trades/widgets/mostro_message_detail_widget.dart, lib/features/trades/widgets/trades_list_item.dart
MostroMessageDetail derives bond phase and displays phase-specific localized messages with optional rating suffix. TradesListItem computes dynamic bondBadgeLabel from phase/claim state instead of boolean flag and passes it to status chip rendering.
Notification routing and message mapping
lib/features/notifications/utils/notification_data_extractor.dart, lib/features/notifications/utils/notification_message_mapper.dart, lib/features/notifications/widgets/notification_item.dart
Routes bondInvoiceAccepted and bondPayoutCompleted through notification extraction (return null), message key mapping (stub placeholders), and tap handling (navigate to /trade_detail/{orderId}).
Multilingual support for bond payout UI
lib/l10n/intl_*.arb
Adds five localization keys across all five languages (English, German, Spanish, French, Italian): in-progress badge, accepted/completed messages, completion-with-rating variant, and close button label.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

  • MostroP2P/mobile#596: Adds initial bond payout claim UI and route; this PR extends it with acknowledged/completed phase rendering.
  • MostroP2P/mobile#116: Refactors trades list status chip rendering; this PR builds on that refactor to add bond badge label logic.
  • MostroP2P/mobile#552: Modifies Action enum initialization; this PR adds new enum values to the same enum.

Suggested Reviewers

  • AndreaDiazCorreia
  • BraCR10
  • mostronatorcoder

Poem

🐰 Two actions hop in, phase by phase,
acknowledged, completed—the bond's full race.
State preserved safe, no tumbles today,
with messages localized in every way,
the invoice accepted, the payout complete,
anti-abuse flows make the user's feat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding mobile support for bond payout confirmation actions (Phase 3.5).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch anti-abuse-bond-phase35

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
Copy Markdown
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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/features/notifications/utils/notification_message_mapper.dart`:
- Around line 98-100: Replace the "TODO: implement title key if needed"
placeholder returned for actions mostro.Action.bondInvoiceAccepted and
mostro.Action.bondPayoutCompleted with a real localized title lookup (e.g., use
the appropriate S.of(context).<orderUpdateTitle> or similar ARB key) inside the
notification message mapper in notification_message_mapper.dart; update the same
placeholder occurrences referenced around lines 204-206 as well, ensuring you
call the correct S.of(context).<key> accessor used elsewhere in this mapper so
no raw string falls back to the user.

In `@lib/l10n/intl_fr.arb`:
- Around line 1591-1595: The new French ARB entries (keys
bondPayoutInProgressBadge, bondInvoiceAcceptedMessage,
bondPayoutCompletedMessage, bondPayoutCompletedWithRating,
bondPayoutCloseButton) currently contain French text but should follow the repo
convention of using English placeholder text for new feature keys; update each
value to an English placeholder equivalent (e.g., "PAYMENT IN PROGRESS", "Mostro
accepted the Lightning invoice you provided to receive your share of the
anti-abuse bond. Please wait for payment to complete.", "You have received
payment of your share of the anti-abuse bond.", "You have received payment of
your share of the anti-abuse bond. You may rate your counterparty.", "CLOSE") so
translations can be added in a follow-up localization PR.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d945bb9e-5423-4a91-8842-b2bb702fd632

📥 Commits

Reviewing files that changed from the base of the PR and between 1382e71 and 75b7bba.

📒 Files selected for processing (17)
  • lib/data/models/enums/action.dart
  • lib/data/models/order.dart
  • lib/features/notifications/utils/notification_data_extractor.dart
  • lib/features/notifications/utils/notification_message_mapper.dart
  • lib/features/notifications/widgets/notification_item.dart
  • lib/features/order/models/order_state.dart
  • lib/features/order/screens/bond_payout_invoice_screen.dart
  • lib/features/trades/widgets/mostro_message_detail_widget.dart
  • lib/features/trades/widgets/trades_list_item.dart
  • lib/l10n/intl_de.arb
  • lib/l10n/intl_en.arb
  • lib/l10n/intl_es.arb
  • lib/l10n/intl_fr.arb
  • lib/l10n/intl_it.arb
  • lib/shared/utils/bond_payout_helpers.dart
  • test/models/order_test.dart
  • test/shared/utils/bond_payout_helpers_test.dart

Comment on lines +98 to 100
case mostro.Action.bondInvoiceAccepted:
case mostro.Action.bondPayoutCompleted:
return 'TODO: implement title key if needed';
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot May 22, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace TODO placeholder keys with real localization keys.

Returning "TODO: ..." here can leak raw placeholder text to users via mapper fallback. Use a valid localized fallback key (e.g., order update) instead.

Suggested fix
       case mostro.Action.restore:
       case mostro.Action.orders:
       case mostro.Action.lastTradeIndex:
       case mostro.Action.addBondInvoice:
       case mostro.Action.bondInvoiceAccepted:
       case mostro.Action.bondPayoutCompleted:
-        return 'TODO: implement  title key if needed';
+        return 'notification_order_update_title';
@@
       case mostro.Action.restore:
       case mostro.Action.orders:
       case mostro.Action.lastTradeIndex:
       case mostro.Action.addBondInvoice:
       case mostro.Action.bondInvoiceAccepted:
       case mostro.Action.bondPayoutCompleted:
-        return 'TODO: implement message key if needed';
+        return 'notification_order_update_message';

As per coding guidelines: "Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals".

Also applies to: 204-206

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/features/notifications/utils/notification_message_mapper.dart` around
lines 98 - 100, Replace the "TODO: implement title key if needed" placeholder
returned for actions mostro.Action.bondInvoiceAccepted and
mostro.Action.bondPayoutCompleted with a real localized title lookup (e.g., use
the appropriate S.of(context).<orderUpdateTitle> or similar ARB key) inside the
notification message mapper in notification_message_mapper.dart; update the same
placeholder occurrences referenced around lines 204-206 as well, ensuring you
call the correct S.of(context).<key> accessor used elsewhere in this mapper so
no raw string falls back to the user.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not blocking. getTitleKey is unreachable for these actions because notification_data_extractor.dart (this PR) returns null for both, which short-circuits both foreground SnackBar and background push paths before any title lokup happens. Same pattern as addBondInvoice (merged in PR #596). The TODO string is dead code; wiring real notification text is explicitly deferred to a follow-up PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Catrya, thanks for the clear explanation! That makes sense — since notification_data_extractor.dart already returns null for both bondInvoiceAccepted and bondPayoutCompleted, these switch branches in the mapper are indeed unreachable dead code for all notification paths (foreground SnackBar and background push). The TODO strings won't surface to users. Acknowledged, and the pattern is consistent with addBondInvoice from #596.

Would you like me to open a follow-up issue to track wiring the real notification title/message keys for these two actions when the time comes?


✏️ Learnings added
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 603
File: lib/features/notifications/utils/notification_message_mapper.dart:98-100
Timestamp: 2026-05-22T23:04:42.075Z
Learning: In MostroP2P/mobile, `notification_data_extractor.dart` returns `null` for `bondInvoiceAccepted` and `bondPayoutCompleted` actions (same as `addBondInvoice`), which short-circuits both foreground SnackBar and background push notification paths before any title/message key lookup in `notification_message_mapper.dart`. The `TODO: implement title/message key if needed` placeholder strings in the mapper are intentional dead code — real notification text for these bond payout actions is explicitly deferred to a future follow-up PR.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: mostronator
Repo: MostroP2P/mobile PR: 463
File: lib/features/wallet/widgets/wallet_status_card.dart:100-105
Timestamp: 2026-02-14T01:35:16.623Z
Learning: Do not localize the term 'sats' (satoshis) in the Mostro mobile app. Treat 'sats' as a universal Bitcoin unit and keep it as hardcoded text in Dart UI code (e.g., wallet_status_card.dart) where appropriate for consistency. Localization keys may exist in .arb files, but avoid replacing 'sats' with localized strings in UI labels or values. If you need to display different units, prefer explicit conversion or a configurable unit setting rather than localizing the 'sats' string itself.

Comment thread lib/l10n/intl_fr.arb
Comment on lines +1591 to +1595
"bondPayoutInProgressBadge": "PAIEMENT EN COURS",
"bondInvoiceAcceptedMessage": "Mostro a accepté la facture Lightning que vous avez fournie pour recevoir votre part du dépôt anti-abus. Veuillez patienter jusqu'à ce que le paiement soit terminé.",
"bondPayoutCompletedMessage": "Vous avez reçu le paiement de votre part du dépôt anti-abus.",
"bondPayoutCompletedWithRating": "Vous avez reçu le paiement de votre part du dépôt anti-abus. Vous pouvez évaluer votre contrepartie.",
"bondPayoutCloseButton": "FERMER",
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot May 22, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use English placeholder text for new fr.arb feature keys (per repo convention).

These newly added values are fully translated to French, but this repo’s convention for new features is to keep fr.arb placeholder text in English and translate in a follow-up localization PR.

Based on learnings: “for new features, use English placeholder text in de.arb and fr.arb, with full translations handled in a follow-up PR.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/l10n/intl_fr.arb` around lines 1591 - 1595, The new French ARB entries
(keys bondPayoutInProgressBadge, bondInvoiceAcceptedMessage,
bondPayoutCompletedMessage, bondPayoutCompletedWithRating,
bondPayoutCloseButton) currently contain French text but should follow the repo
convention of using English placeholder text for new feature keys; update each
value to an English placeholder equivalent (e.g., "PAYMENT IN PROGRESS", "Mostro
accepted the Lightning invoice you provided to receive your share of the
anti-abuse bond. Please wait for payment to complete.", "You have received
payment of your share of the anti-abuse bond.", "You have received payment of
your share of the anti-abuse bond. You may rate your counterparty.", "CLOSE") so
translations can be added in a follow-up localization PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not blocking. The convention cited doesn't match repo practice: PR #596 (immediate Phase 3 precedent, same author, same feature family) added 11 bond keys with full fr/de translations. CLAUDE.md guidance is "Always use localized strings" and CI accepts populated values. If we want to switch to placeholder-only fr/de for new features, that's a policy change to discuss separately.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@Catrya, that's a fair and well-evidenced correction — thank you. The review comment was based on an inaccurate learning, and PR #596's precedent (same author, same feature family, full fr/de translations) clearly shows that fully-translated values in fr.arb and de.arb are the established practice here. I'll update the long-term memory accordingly.

(。•́︿•̀。)


✏️ Learnings added
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 603
File: lib/l10n/intl_fr.arb:1591-1595
Timestamp: 2026-05-22T23:05:28.893Z
Learning: In MostroP2P/mobile, Flutter localization ARB files under lib/l10n (e.g., intl_fr.arb, intl_de.arb) should contain fully translated values for new feature keys at the time the feature is added. CLAUDE.md guidance is "Always use localized strings." Do NOT flag fully translated fr/de values as non-conventional — that matches established repo practice (see PR `#596` and PR `#603` as precedents for the bond payout feature family). Placeholder metadata blocks (e.g., key blocks) are not required unless an explicit type or description is needed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


⛔ Learnings removed
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 592
File: lib/l10n/intl_fr.arb:709-709
Timestamp: 2026-05-14T19:41:20.593Z
Learning: For MostroP2P/mobile Flutter localization ARB files under lib/l10n, do not require key metadata blocks for placeholder keys. flutter gen-l10n will generate valid Dart code (e.g., inferred parameter types like `String forAmount(Object amount)`) even when key metadata is omitted. Only require metadata blocks when an explicit type and/or description is needed. Treat “normalizing all placeholder keys to include metadata” as a separate, non-blocking concern. Also, follow the project convention: for new features, use English placeholder text in de.arb and fr.arb, with full translations handled in a follow-up PR.

🧠 Learnings used
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 592
File: lib/l10n/intl_fr.arb:709-709
Timestamp: 2026-05-14T19:41:20.593Z
Learning: For MostroP2P/mobile Flutter localization ARB files under lib/l10n, do not require key metadata blocks for placeholder keys. flutter gen-l10n will generate valid Dart code (e.g., inferred parameter types like `String forAmount(Object amount)`) even when key metadata is omitted. Only require metadata blocks when an explicit type and/or description is needed. Treat “normalizing all placeholder keys to include metadata” as a separate, non-blocking concern. Also, follow the project convention: for new features, use English placeholder text in de.arb and fr.arb, with full translations handled in a follow-up PR.

Copy link
Copy Markdown

@ermeme ermeme Bot left a comment

Choose a reason for hiding this comment

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

Re-reviewed the latest head. The bond payout phase handling, state preservation, UI gating, and tests all look consistent. I do not see a blocking issue on this revision.

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.

1 participant