Skip to content

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:

  1. Support Ticketing (SupportService): General customer service inquiries, platform assistance, and technical bug reports.
  2. Order Dispute Arbitration (DisputeService, AtomicReturnCaseService): Financial and legal arbitration over locked escrow funds, with formal evidence gathering and Maker-Checker fund release or restitution.
mermaid
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 --> OUTBOX

2. 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 RPC decide_support_ticket asserts that current_revision === expected_revision.
  • Conflict Defense: If two agents attempt to claim or update the same ticket simultaneously, the second agent receives 409 Conflict (40001 Serialization 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:

typescript
// 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:

mermaid
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
    end

3.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_outbox to survive WhatsApp API latency spikes.

Released under Proprietary Enterprise License.