feat(whatsapp): add shopper help and post-purchase actions - #664
Conversation
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
|
Warning Review limit reached
Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds WhatsApp shopper-agent support for starting disputes, checking dispute status, and checking refund status, including buyer authorization, Redis-backed confirmation handling, safe output validation, deterministic routing, service wiring, and tests. ChangesWhatsApp post-purchase dispute and refund flows
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Shopper
participant WhatsAppService
participant WhatsAppIntentService
participant WhatsAppPostPurchaseService
participant RedisService
participant DisputeService
Shopper->>WhatsAppService: Send dispute request
WhatsAppService->>WhatsAppIntentService: Parse shopper intent
WhatsAppIntentService-->>WhatsAppService: Return start_dispute
WhatsAppService->>WhatsAppPostPurchaseService: prepareDispute
WhatsAppPostPurchaseService->>RedisService: Store pending dispute
WhatsAppPostPurchaseService-->>WhatsAppService: confirmation_required
WhatsAppService-->>Shopper: Send confirm/cancel controls
Shopper->>WhatsAppService: Confirm dispute
WhatsAppService->>WhatsAppPostPurchaseService: handlePendingReply
WhatsAppPostPurchaseService->>RedisService: Consume pending dispute
WhatsAppPostPurchaseService->>DisputeService: openBuyerDispute
WhatsAppService-->>Shopper: Send dispute result
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/backend/src/domains/orders/dispute/dispute.service.ts (1)
185-259: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate order-fetch + eligibility orchestration between
openBuyerDisputeandassertBuyerCanOpenDispute.Both methods independently: fetch the order via
prisma.order.findUniquewith the sameinclude, callassertBuyerOwnsOrder/assertOrderCanBeDisputed, and re-run the "existing active dispute"findFirst. The underlying business rules stay centralized (both call the same shared assertion helpers), so there's no correctness-drift risk today, but this is two DB round-trips per shopper action (once during WhatsApp confirmation staging, once again at confirm-time) and ~35 lines of duplicated orchestration that will need to be kept in sync if the eligibility flow gains steps later (e.g., an additional guard).Consider extracting a shared private helper (e.g.,
loadDisputableOrder(orderId, buyerId): Promise<OrderForDispute>) that bothopenBuyerDisputeandassertBuyerCanOpenDisputecall.🤖 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 `@apps/backend/src/domains/orders/dispute/dispute.service.ts` around lines 185 - 259, Extract the duplicated order-loading and dispute-eligibility orchestration from openBuyerDispute and assertBuyerCanOpenDispute into a shared private helper such as loadDisputableOrder(orderId, buyerId). Have the helper fetch the order, apply assertBuyerOwnsOrder and assertOrderCanBeDisputed, and reject active disputes; then have both public methods reuse it while preserving each method’s existing transaction and return behavior.apps/backend/src/channels/whatsapp/whatsapp.service.spec.ts (1)
1679-1793: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for
get_dispute_statusand the ineligible/cancel dispute paths.Current new tests cover
get_refund_status(read),start_disputehappy-path confirmation, and pending-confirmation success, but notget_dispute_status, nor the branch whereprepareDisputereturnsconfirmationButtons: false(ineligible/expired → plain-text/support redirect), nor a "cancel" pending-reply outcome.🤖 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 `@apps/backend/src/channels/whatsapp/whatsapp.service.spec.ts` around lines 1679 - 1793, Extend the WhatsApp service tests around the existing refund and dispute cases to cover get_dispute_status with shopper-safe output and message delivery, prepareDispute returning confirmationButtons: false with the expected plain-text/support redirect, and handlePendingReply returning the cancel outcome with the corresponding response. Reuse the existing setup and assertions for user, phone, intent, and service calls.
🤖 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 `@apps/backend/src/domains/orders/order/order.service.ts`:
- Around line 1879-1897: Update getLatestByBuyer to filter out PENDING_PAYMENT,
CANCELLED, and other non-actionable or terminal order statuses, selecting the
most recent order that can still support dispute or refund-status flows.
Preserve the existing buyer, order-type, ordering, and selected fields.
---
Nitpick comments:
In `@apps/backend/src/channels/whatsapp/whatsapp.service.spec.ts`:
- Around line 1679-1793: Extend the WhatsApp service tests around the existing
refund and dispute cases to cover get_dispute_status with shopper-safe output
and message delivery, prepareDispute returning confirmationButtons: false with
the expected plain-text/support redirect, and handlePendingReply returning the
cancel outcome with the corresponding response. Reuse the existing setup and
assertions for user, phone, intent, and service calls.
In `@apps/backend/src/domains/orders/dispute/dispute.service.ts`:
- Around line 185-259: Extract the duplicated order-loading and
dispute-eligibility orchestration from openBuyerDispute and
assertBuyerCanOpenDispute into a shared private helper such as
loadDisputableOrder(orderId, buyerId). Have the helper fetch the order, apply
assertBuyerOwnsOrder and assertOrderCanBeDisputed, and reject active disputes;
then have both public methods reuse it while preserving each method’s existing
transaction and return behavior.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 33a2dc07-867b-4aae-923b-2857af561af2
📒 Files selected for processing (14)
apps/backend/src/channels/whatsapp/agent/shopper-agent-tool.registry.spec.tsapps/backend/src/channels/whatsapp/agent/shopper-agent-tool.registry.tsapps/backend/src/channels/whatsapp/agent/shopper-agent.types.tsapps/backend/src/channels/whatsapp/whatsapp-intent.service.spec.tsapps/backend/src/channels/whatsapp/whatsapp-intent.service.tsapps/backend/src/channels/whatsapp/whatsapp-post-purchase.service.spec.tsapps/backend/src/channels/whatsapp/whatsapp-post-purchase.service.tsapps/backend/src/channels/whatsapp/whatsapp.constants.tsapps/backend/src/channels/whatsapp/whatsapp.module.tsapps/backend/src/channels/whatsapp/whatsapp.service.spec.tsapps/backend/src/channels/whatsapp/whatsapp.service.tsapps/backend/src/domains/orders/dispute/dispute.service.tsapps/backend/src/domains/orders/order/order.service.spec.tsapps/backend/src/domains/orders/order/order.service.ts
What does this PR do?
Adds the final WIZZA shopper help and post-purchase actions for linked accounts. WIZZA can now prepare eligible disputes with an explicit one-time confirmation, read the shopper's current dispute status, and report real buyer-refund settlement status through canonical order/dispute services. Ineligible or expired dispute requests are directed to Twizrr support without changing store-management behavior.
Type of change
Area affected
How to test this
Expected result: eligible dispute requests require explicit confirmation, duplicate confirmations cannot create duplicate disputes, status responses use real domain data, and unsupported/ineligible cases return safe guidance without exposing provider, store, or fulfillment internals.
Pre-commit checklist
Screenshots
N/A. Backend and WhatsApp behavior only.
Notes for reviewer
Runtime behavior
Validation
No schema/migrations, checkout/cart/payment behavior, payout math, delivery/Shipbubble behavior, product search/ranking, image search, public product URLs, web routes, store management, .env.local, secrets, or private prompt values were changed.
Summary by CodeRabbit
New Features
Bug Fixes
Tests