Trades ledger: pull individual CurrencyTrade/BarterTrade rows, not just counters #6
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?
The economy card only consumes aggregate time-series counters, but the exporter ships every individual trade:
/api/v1/exporter/actions?actionName=CurrencyTradereturned 2,730 rows live (cycle 13, day 56) with columnsBankAccount, Currency, CurrencyAmount, NumberOfItems, BoughtOrSold, ShopOwner, Buyer, Seller, WorldObjectItem, ItemUsed, Citizen, ActionLocation, Count, Time.BarterTradeexists too (empty this cycle).Target: a row-level trades surface (likely
/tradesin the SPA, cross-linked with /economy and /crafting per the wave-0 pattern) - who sold what to whom, for how much, where, when. A price-over-time series per item falls out of this almost for free.Messy bits to clean en route (filed per the pull-everything rule in AGENTS.md):
/api/v1/usersexposesName/PlayFabId/SteamIdbut no numeric id, so the join key is still missing a link.🔒 Reserved by
ward agent --driver claude— containerengineer-claude-eco-app-6on hostKAI-DESKTOP-TOWERis carrying this issue (reserved 2026-07-05T01:40:10Z). 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 agent🔓 Reservation released by
ward container reap— containereco-app(--driver claude) exited without launching the agent (smoke-test death, ward#222/#264), so the hold it took is retracted. A plainward agentretry no longer needs--force.— Claude (she/her), via
ward agent🔒 Reserved by
ward agent --driver claude— containerengineer-claude-eco-app-6on hostKAI-DESKTOP-TOWERis carrying this issue (reserved 2026-07-05T02:53:52Z). 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 - shipped a row-level trades ledger (
get_eco_tradestool +/tradesSPA page) with top buyers/sellers, per-item price-over-time, id-to-name joins, and defensive parsing; landed on main.This one felt like assembly more than invention, in the best way. The crafting atlas (#5) had already built almost exactly the machinery a row-level surface needs - streamed CSV folding, the extra-column realignment scorer, the
/api/v1/citizensid-to-name join - so most of the backend was extractingfetch_citizen_name_mapfor sharing and folding rows instead of aggregating them. The nice payoff the issue predicted (price-over-time "falls out almost for free") really did: once you have unit price per row, bucketing by in-game day is a few lines.What fought back was mostly what I couldn't verify offline. The Eco
GameActionssource isn't in this container, soBoughtOrSold32/33 stays a heuristic buy/sell decode - I sidestepped the risk by reading who-sold-to-whom straight off the Buyer/Seller columns, so a wrong enum only mislabels a secondary chip. A test fixture also caught me being sloppy: I put the fake extra column between two adjacent name columns, which the realigner genuinely can't disambiguate (that's a real property of the heuristic, not a bug), so I anchored it against a position column like the crafting test does.Confident in the parsing and aggregation - they're tested against the real cycle-13 column shape, and lint/mypy/pytest (273) + frontend vitest (35) + build all pass. Two things I can't confirm without live data, both filed in docs/trades.md: the buy/sell polarity, and whether each trade logs one row or a buy-leg+sell-leg pair (if two, row counts and gross currency volume are per-leg). Worth a glance once someone's on a live server - and the new
mods/storesshelf exporter that landed on main in parallel is a natural complement (shelf-accurate offers vs my history-derived trades).