Support & Dispute Systems Architecture
1. Executive Summary & Problem Space
In a student marketplace, transaction friction and order issues are inevitable: unreceived packages, damaged goods, payment queries, and technical platform difficulties.
Debelu decouples customer service into two distinct systems:
- Support Ticketing (
SupportService): General customer service inquiries, platform assistance, and technical bug reports. - Order Dispute Arbitration (
DisputeService,AtomicReturnCaseService): Financial and legal arbitration over locked escrow funds, with formal evidence gathering and Maker-Checker fund release or restitution.
graph TD
subgraph Multi-Channel Customer Ingestion
WEB_TICKET[Storefront Web / Mobile Ticket Form]
WA[Meta WhatsApp Business API Webhook]
NDUZI[Nduzi AI Assistant Escalation]
end
subgraph Service Triage & Case Classification
ROUTER{Classify Intent}
SUP_SVC[SupportService<br/>Optimistic Revision Triage]
DISP_SVC[DisputeService & AtomicReturnCaseService<br/>Escrow Lock & Evidence Gathering]
end
subgraph Storage & Verification Plane
DB_TICKETS[(public.support_tickets<br/>Signed S3 Attachments)]
DB_DISPUTES[(public.disputes & return_case_commands)]
OUTBOX[(public.support_notification_outbox)]
end
WEB_TICKET --> ROUTER
WA --> ROUTER
NDUZI --> ROUTER
ROUTER -->|Platform / Account Help| SUP_SVC
ROUTER -->|Order Defect / Non-Delivery| DISP_SVC
SUP_SVC --> DB_TICKETS
DISP_SVC --> DB_DISPUTES
SUP_SVC --> OUTBOX2. Support Ticketing Lifecycle (SupportService.ts)
Support tickets in Debelu are managed via SupportService ([debelu-backend/src/services/SupportService.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/services/SupportService.ts)).
2.1 Optimistic Concurrency Control in Triage
When support agents triage or resolve tickets, they operate under strict optimistic locking:
- Every ticket maintains an integer
revision. - When an agent submits a decision (
claim,release,update,note), the database RPCdecide_support_ticketasserts thatcurrent_revision === expected_revision. - Conflict Defense: If two agents attempt to claim or update the same ticket simultaneously, the second agent receives
409 Conflict(40001Serialization Failure) with the message: "Ticket changed or already claimed; refresh before deciding."
2.2 Private Signed Attachments
Customer uploaded receipts, defective item photos, and chat attachments are stored in private Supabase buckets:
// Attachment URLs are never exposed as public static links
fileUrl: await signSupportAttachment(m.sender_id, m.file_url)Generates a time-limited HMAC-signed URL (15-minute expiration), preventing unauthenticated scraping of user support photos.
3. Order Dispute Arbitration Lifecycle (DisputeService.ts)
When an order dispute is opened, the escrow state machine immediately freezes funds:
sequenceDiagram
autonumber
actor Buyer
participant Order as OrderService
participant Dispute as DisputeService
participant Return as AtomicReturnCaseService
actor Arbiter as Support Arbiter
participant Ledger as Ledger Engine
Buyer->>Dispute: 1. Open Dispute (order_id, reason, proof)
Dispute->>Order: 2. UPDATE orders SET status='Disputed'
Note over Order: Auto-release 72h timer paused; escrow funds locked
Dispute-->>Arbiter: 3. Alert Dispute Queue (High Priority)
Arbiter->>Dispute: 4. Review evidence (Chat transcripts, PIN status, Hub logs)
alt Ruling: In Favor of Buyer (Refund)
Arbiter->>Return: 5a. Dispatch Campus Runner for Return Item Pickup
Return->>Return: 6a. confirm_pickup -> confirm_inspection
Arbiter->>Ledger: 7a. ReviewedWalletRefundService (Full Refund to Buyer)
else Ruling: In Favor of Vendor (Release)
Arbiter->>Order: 5b. Force Release Escrow (process_order_fund_release)
Order->>Ledger: 6b. Credit Vendor Wallet Balance
end3.1 Dispute States
Open: Newly initiated by buyer; evidence gathering phase.Under_Review: Claimed by a staff arbiter.Resolved_Refund: Arbitrated in buyer's favor; funds returned to wallet or card.Resolved_Released: Arbitrated in vendor's favor; escrow released.Cancelled: Buyer withdrew the dispute.
4. Multi-Channel Ingestion: WhatsApp Business API
In addition to the web app, students can communicate via Debelu's verified WhatsApp Business line:
- Route:
/api/whatsapp/webhook([debelu-backend/src/routes/whatsappWebhookRoutes.ts](file:///c:/Users/frank/OneDrive/Desktop/Chisom/Debelu/New%20Debelu%20Marketplace/debelu-backend/src/routes/whatsappWebhookRoutes.ts)). - Verification Challenge: Cryptographic handshake with Meta's servers validating
hub.verify_token. - Outbox Pattern: Outgoing support responses queue in
public.support_notification_outboxto survive WhatsApp API latency spikes.