Skip to content

WebSocket Command Response Migration

Target audience: frontend developers

Status: breaking while auction functionality is unreleased

Effective date: 2026-08-29

Current contract

Auction staff controls remain asynchronous commands: the server returns command.acknowledged, then publishes their outcome as realtime events or a correlated command.failed / command.rejected envelope.

auction.bid.place is intentionally different. It is a synchronous, transactional command because the bidder must receive a terminal result for every submitted bid.

Command kind Immediate response Meaning
auction.bid.place ack or error Bid committed/replayed, or explicitly rejected
Staff auction writes command.acknowledged Accepted for asynchronous execution
Queries/subscriptions ack or query-specific events Request completed

Bid placement migration

Send a stable client-generated id and a strict payload:

{
  "id": "bid-request-001",
  "type": "auction.bid.place",
  "data": {
    "auctionId": "auction-1",
    "amountMinor": "150000"
  }
}

A committed bid returns:

{
  "id": "bid-request-001",
  "type": "ack",
  "data": {
    "eventType": "auction.bid.place",
    "status": "accepted",
    "commandId": "bid-request-001",
    "auctionId": "auction-1",
    "cycleId": "cycle-1",
    "bidId": "bid-1",
    "amountMinor": "150000",
    "stateVersion": 42
  }
}

status: "replayed" means the identical command was already committed. A reused id with different bid details is rejected. Schema, authorization, and business failures use the existing correlated error envelope.

On an uncertain connection or database response, retry the identical payload with the same id. Never generate a new id for the same bid intent. Do not send auction versions or client timestamps; PostgreSQL validates each request against the latest committed state under an auction-row lock.

Realtime auction.bid.created and auction.bid.updated events still update the shared room feed. A terminal bid acknowledgement answers the requester; feed events synchronize every participant.

Staff commands

These continue to use asynchronous acknowledgement and event-driven outcomes:

  • auction.status.update
  • auction.pause, auction.resume, auction.end
  • auction.bid.mark
  • auction.winner.declare, auction.winner.record_lot
  • announcement and floor-presence commands

Keep pending UI for these commands until their domain event or correlated failure arrives.

Checklist

  • Require a stable id for every bid request.
  • Treat bid ack and error as terminal.
  • Handle both accepted and replayed as committed bids.
  • Retry uncertain bid responses with the same id and payload.
  • Continue ordering the shared feed by serverSequence.
  • Keep asynchronous handling for staff commands.