Skip to content

OrderSystem

Developer edited this page Jun 11, 2026 · 2 revisions

Order System — intake, payment gate & manifest

The stash organisation bot + order picker, wired together. StashScanner builds a stock database from a stash of kit shulkers; the Order System takes orders, holds stock, waits for payment, and dispatches the OrderFiller to deliver them into outgoing chests with a Discord manifest.

It runs natively in the proxy (no separate Node bot) — the order commands are the same Brigadier commands as everything else, so they work in-game, in the terminal, and in the Discord relay channel. An optional Redis adapter lets an external shop / TicketTool bot confirm payment.

Command: .order (alias .ord).

How it flows

.order pvp:5 obby:3          → create order, soft-hold stock, start a 15-min TTL  (awaiting_payment)
   ↓  customer pays
orders:paid signal (or .order paid <id>)   → firm the reservation, enqueue       (paid → filling)
   ↓  OrderFiller pops the job
withdraw reserved shulkers → deposit to the order's outgoing chest → manifest      (delivered / ready)
   ↓
manifest embed posted to Discord (per-kit requested / delivered / short)
  • Soft-hold + TTL. Placing an order atomically reserves the stock so it can't be oversold during checkout. Unpaid holds expire after softHoldMinutes (default 15) — a background reaper releases them.
  • Payment gate. An order is not filled until an orders:paid signal arrives (from your shop / TicketTool bot) or you run .order paid <id>. The adapter is thin: the external bot just publishes {"order_id":N,"payment_ref":"…"} to Redis (or writes orders.paid_at and publishes).
  • Stock drift between scan and fill is surfaced on the manifest as a shortfall; firm-on-payment reservations mean a paid order is never oversold.
  • Coordinate secrecy. Stash coordinates stay in Postgres only. Customers and the manifest see only the outgoing chest.

Commands

.order catalog | stock                       # list kit types / available stock
.order <kit:qty> [kit:qty ...]               # place an order (e.g. .order pvp:5 obby:3 food:5)
.order status <order_id>
.order cancel <order_id>                      # release reservations if not yet filling
.order paid <order_id> [ref]                  # admin/test: mark paid + enqueue the fill
.order outgoing <x> <y> <z> [label]          # admin: register a pickup chest (role=outgoing)

Fulfilment tuning (trip size, partial fills, manifest channel, .of test) lives on the OrderFiller page; scanning + the kit catalog on the StashScanner page.

Setup

The stash system reuses the proxy's existing database layer (the same one the stats databases use), so the connection settings live under database in config.json, not client.extra.

  1. Postgres + Redis on the host:
    apt install postgresql redis-server
    Point the proxy at them and turn the stash tables on (they self-provision on start — no manual psql):
    database host <host> | port <port> | username <user> | password <pw>
    database lock redis <redis://localhost:6379>     # if your redis differs from the default
    database stash on                                # provision + run the stash system
    database on                                      # bring the database layer up
    
  2. Seed the catalog from a dry-run scan (StashScanner): .ss scan.ss dump → label a kits.json.ss seed kits.json.
  3. Register outgoing chests: .order outgoing <x> <y> <z> [label].
  4. Enable fulfilment: .of on. Place a test order and .order paid <id> to drive it end-to-end.
  5. Wire payment (optional): point your shop / TicketTool bot at the orders:paid Redis topic.

Redis channels

Channel Direction Payload
orders:queue OrderService → OrderFiller {"order_id":N} (a reliable list)
orders:status OrderFiller → OrderService {"order_id":N,"status":"filling|delivered|ready|failed"}
orders:paid external bot → OrderService {"order_id":N,"payment_ref":"…"}

Clone this wiki locally