Trade & store logistics: SPA /trade route (product surface for the whole set) #54
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Context
The product surface for trade & store logistics under the DiscordLink-replacement epic (#37). AGENTS.md is emphatic: product UX is the SPA (
frontend/), never a server-rendered card. This route is where the whole trade push becomes something a player actually opens, and it is the concrete embodiment of Kai's thesis that read-only trade info belongs on the website, not Discord.No-reset spine
Pure frontend plus the
/preview/*.jsondata plane the sibling backend issues expose. No server interaction beyond those endpoints, no reset. Follows the existing wave-0 SPA pattern (/economy,/crafting,/climate) - react-router page, live badges, filter-on-click,?q=deep links, graceful degraded state, vitest component tests in CI.Scope
The agent builds the SPA
/traderoute (frontend/src/pages/Trade.tsxor a small route cluster):/preview/market.json.?q=<item>deep link, cross-linked with/economyand/crafting./preview/stores.json./preview/logistics.json. This is the headline "what should I do" panel./preview/currency.json.Read the
datavizskill before building the price-history chart and any stat tiles, and register the new route on the homepage directory with a live badge.DiscordLink parity
This is the surface that makes the whole set exceed DiscordLink: one coherent, always-on web page with history, charts, logistics reasoning, and cross-links, versus DiscordLink's ephemeral DM embeds.
Acceptance
/preview/*.jsonand degrades gracefully when an endpoint is empty or 404 (some siblings may not have landed yet - the page must not hard-crash)./economyand/crafting.ward exec frontend-testandward exec frontend-lintgreen.docs/FEATURES.mdupdated for the/traderoute.Dependencies
Consumes the data planes from the market, stores, logistics, watcher, and currency siblings. Can scaffold ahead of them against the documented
/preview/*.jsoncontracts and fill panels as they land. Parent: #37. Design pass: #2.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-eco-app-54on hostKAI-DESKTOP-TOWERis carrying this issue (reserved 2026-07-05T04:03:25Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).
— Claude (she/her), via
ward agentWARD-OUTCOME: done - SPA /trade product surface landed on main (currency strip, market movers, item drill-down, store/trader directory, logistics board, watchers panel), all vitest + lint + build green.
Honest retrospective: this one went smoothly, mostly because the ground was already well-prepared. The backend
/preview/{market,stores,currency,watchers}.jsonplanes were all live and the sibling/tradesledger page was a near-perfect template for the chart, rank rows, and cross-link conventions, so a lot of this was assembling existing pieces into one coherent page rather than inventing.The one thing that fought back a little was the naming collision:
/trades(the existing row-level ledger) versus/trade(this new product surface). It took a beat to be sure I was building a distinct route, not editing the ledger. I leaned into it by cross-linking them explicitly and giving each a clear homepage card.The real design decision was graceful degradation.
/preview/logistics.jsonhas no backend yet (no logistics module exists), so I froze a documented contract inlogisticsApi.ts, made every one of the five planes fetch independently via a best-effortfetchJsonOrNull, and had each panel hide itself on a 404 rather than take the page down. A test covers the all-planes-404 case and the logistics-only-404 case, so I am fairly confident it will not hard-crash as siblings land or lag.Confidence is high on the frontend: 46 tests pass (7 new), lint and the production tsc build are clean, and every panel plus both degrade paths are exercised. The rough edge worth naming: I could not drive it against the live game server from here, so the panels are verified against fixtures, not real payloads. Two follow-ups worth filing when the backend catches up: (1) a
/preview/logistics.jsonbackend to fill the logistics board, and (2) the item drill-down's "recent trades / who is buying and selling" is currently a cross-link to/trades?q=, which could be inlined once a per-item trade slice is cheap to fetch.