Practical-usefulness slice: /uses hub + demand-side use-case pages (what's in demand, buy/sell, arbitrage, shop-check) - follow-up F from #98 #99
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?
Ship the first slice of the practical-usefulness layer: the
/useshub plus the demand-side, task-focused use-case pages. This is follow-up F (and the shared hub it needs) from the design on #98. Kai asked to start here because it depends on zero new data - every panel reads data eco-app already hydrates and the/tradepage already renders.Do NOT build anything recipe-shaped or cost/margin-based here. Those (the recipes page, cost engine, value-per-profession, and the "how to price X" page) are follow-ups A-E on #98 and are gated on the recipe exporter. This ticket is the no-dependency slice only.
1. The shared
/useshub/usesroute (App.tsx) and one homepage card inHome.tsx(data-testidin thedir-*family). This is the ONLY homepage card the whole use-case family gets - the individual use-case pages are URL-only, reached from the hub, mirroring how/itemis only reached from/items./usesis a single page that lists the use cases as cards, each linking to its page. It is NOT the recipes page (that is a separate data hub on #98).2. The demand-side use-case pages (all buildable now)
Each is a task-framed page with a hero stating the job, one primary input (an item picker where relevant, deep-linkable via
?item=<id>), then panels composed from existing typed clients. Each panel degrades on its own viafetchJsonOrNullso one dead source never blanks the page (the/preview/logistics.jsonsibling can 404 on a reset-gated shelf -fetchLogisticsalready resolves to null). ReuseformatCount/prettifyEcoNamefromlib/format.ts./uses/demand- "What's in demand right now." RankLogisticsBoard.supplyGaps(lib/logisticsApi.ts) bydemandQty, showing the item, thereasontag (no_supply/thin_supply/overpriced) with a glyph+label+color severity treatment (never color alone),buyerCount, and who needs it (buyers[]: owner, store, quantity, price). This is the Supply-gaps signal Kai likes, given its own focused page./uses/buy-sell- "Where to buy X cheapest / sell X highest." For a picked item, show the cheapest sell offers (LogisticsBoard.cheapest->PricedBoardRow.offers,cheapestprice) and the best buy offers (resale,bestprice), each row naming the store, owner, price, quantity, andsource(live / history)./uses/arbitrage- "Buy low here, sell high there." RenderLogisticsBoard.arbitrage(ArbitrageSpread): buyFrom store, sellTo store,spread/spreadPct,volume, andopportunity, ranked byopportunity./uses/shop-check- "Is my shop priced right?" Pick a store (fromlib/storesApi.ts), and for each item it lists compare itsavgUnitPriceagainst the market median (lib/marketApi.ts), flagging items priced notably above or below market. This is the one page that joins two sources - degrade to a clear note if either is unavailable.Conventions
Layout(+Herowhere it fits),react-router, and the?param=deep-link pattern the other pages use so QA can share links.pages/Trade.test.tsx/pages/Items.test.tsx), including the degraded-when-null branch.Done when
/useslists the use cases with one homepage card, the four demand-side pages render real data and each degrades independently, every page is deep-linkable and carries one heading tier, and the test + lint gates (ward exec/frontend-test/frontend-lint) are green. Updatedocs/FEATURES.mdwith the/useshub and the demand-side pages, and add a shortdocs/uses.mdwalkthrough linked from the FEATURES entry. Land onmainso the deploy picks it up - Kai is sending this to QA after it deploys, so leave each page usable and shareable standalone.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-eco-app-99on hostKAI-DESKTOP-TOWERis carrying this issue (reserved 2026-07-07T06:37:48Z). 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).
run seed context — what this run is carrying (ward#609)
coilyco-gaming/eco-app#99· branchissue-99· driverclaude· workflowdirect-mainengineer-claude-eco-app-99· wardv0.419.0· dispatched2026-07-07T06:37:48ZIssue body as seeded:
… (truncated to 2000 chars; full body is on this issue)
Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.419.0).
— Claude (she/her), via
ward agentWARD-OUTCOME: done - /uses hub + four demand-side use-case pages landed on main, all gates green.
This one went smoothly, mostly because the ground was already prepared. The issue was right that it needs zero new data: every panel I built is just a focused re-slice of the same logistics/stores/market planes /trade already renders, so the real work was reading Trade.tsx closely and carving four task-framed views out of it. The typed lib/*Api.ts clients and the fetchJsonOrNull degrade pattern did all the heavy lifting - each page degrades panel-by-panel almost for free.
What fought back a little: the container had no pnpm, so I had to enable it through corepack before ward exec frontend-install would run. And the playwright browser lives outside this container's network namespace, so I couldn't drive the preview server in a real browser - I leaned on the jsdom component tests (which do exercise routing, ranking/joining, and the degraded-when-null branch for every page) plus the production build. The one genuinely interesting page was shop-check, since it's the only one joining two planes (store avgUnitPrice vs market median) - I keyed the join on the raw item id and made it degrade to a clear note when either side is missing.
Mid-run origin/main advanced by three commits (an item-feed rewrite touching format.ts, Items/Item, index.css, FEATURES.md). The merge came out clean with no conflicts, and I re-ran the full test/lint/build on the merged tree before pushing (111 tests green) rather than trusting the pre-merge run.
Confidence is high that the pages render and degrade correctly. The one thing I could not verify is how they look against live server data - QA will be the first eyes on real supply gaps and arbitrage spreads. Possible follow-ups worth filing if QA wants them: the buy-sell and shop-check pickers are flat filter-lists rather than a proper combobox, and I re-declared the supply-gap severity map locally instead of extracting the shared one from Trade.tsx (fine for now, a candidate for a small dedup later).