feat(sidecar): store and serve the player-vendor market index #19
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/vendor-listing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What & why
Protocol 3.0 §8 (
docs/link/v3.md) — order 5b, the sidecar side. Plugin in servuo-plugins #5; website in website #116; docs in docs #71.Ingests
vendor.listing/vendor.listing.removeinto avendorstable and servesGET /market.Small change, three decisions worth review.
1. No
vendor_itemstable — the items stay inside the blobThe obvious move is to normalize, since the website does exactly that. It would be the wrong seam here: the sidecar's job for the market is outage resilience (
PROTOCOL_2.md§12.2) — hand the website back what the shard last said — not search. Search lives in MariaDB, where the query surface, the indexes and the cliloc-resolved display names already are; a second search implementation here would be one more thing to keep in step with that one, for no reader.2. There IS a remove, unlike the other 3.0 boards
points.boardandworld.rulesethave no delete path — the shard's set of systems is fixed at startup and the ruleset is a singleton. A vendor is different: it is dismissed, it expires, or its owner switches off the in-game Vendor Search flag. That last one is a privacy control, so dropping the row promptly is the point of it, not housekeeping.3.
/marketis the only PAGED read the sidecar servesBecause it is the only board that can be a whole world's inventory.
limitclamps to 1..1000 (default 200), andtotalcomes back alongside so a caller knows when to stop rather than paging until it sees a short page — which would race a concurrent sweep.Ordering is by
serial, not by shop name. The page is a snapshot cursor for the website's reconnect backfill; a serial is stable while a shop name is renameable, so a rename mid-backfill cannot make a vendor skip or repeat a page.The route is
/market, not/vendors— axum would route the latter fine, but/vendors/:accountnext door is the per-account RPC, and two routes a prefix apart meaning "this player's shops" and "every shop on the shard" is a readability trap nobody wins.Frames are served verbatim, owner names and coordinates included. Not an oversight: the sidecar defines no audiences (
v3.md§3.2). Deciding who may see a vendor's owner or whereabouts is the website's job and is admin-configurable there.How it was tested
cargo buildandcargo clippy --all-targetsclean.Run against the real shard with the plugin from servuo-plugins #5:
GET /market, frames intact — nestedlocation, owner fields,count/total/truncated, every item'scliloc.?limit=5,?limit=27) withtotalcorrect.total=28, synthetic=true→total=27, synthetic=false. This is the delete path the plugin cannot easily be made to exercise without a game client./marketand loggedsnapshotted player-vendor market from /market {"count":27}.X-UOLink-Versionstill reports 2 — the bump to 3 is order 6, deliberately once, at theedge→maincutover.CI note:
release.ymlonly runs on merge tomain, so this PR (targetingedge) runs no CI — local verification above is the gate.Checklist
AI-assisted contributions (required)
Claude Code (Opus 5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with aCo-Authored-Bytrailer.License