Skip to content

Guild api updates - #121

Open
Abstrct wants to merge 2 commits into
mainfrom
guild-api-updates
Open

Guild api updates#121
Abstrct wants to merge 2 commits into
mainfrom
guild-api-updates

Conversation

@Abstrct

@Abstrct Abstrct commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Guild API updates: list query params, leaderboards, inventory, resolve, and aggregates

Extends the read API for guild dashboards and third-party clients. Every list endpoint gains a common set of query params, and new endpoints expose the indexer-maintained api_* projections, denomination metadata, object resolution, and time-bucketed stats.

List endpoints (CatalogReadController)

All /api/*/list/... and /api/*/all/page/{page} routes now accept:

Param Effect
limit Page size, clamped to 1000 (default 100)
updated_since Unix seconds; only rows with a newer updated_at
after_id Keyset cursor on (updated_at, id); replaces the page offset
since_seq Cursor on seq for a single planet's activity feed
include_total Adds total (count of the filtered relation)
include_meta Adds meta.height (source block height)
order Allowlisted sort for grid reads, e.g. val.desc
is_destroyed 0/1 filter for struct lists

Support is declared per endpoint. A param an endpoint cannot honour returns 400 <param>_unsupported rather than being silently ignored, so a client paging a feed is told when its cursor did nothing.

ApiResponseContentDto now serialises total and meta only when set, so existing consumers see an unchanged shape.

New endpoints

  • GET /api/leaderboard/{kind} for player, guild, reactor, substation, provider, with allowlisted order and limit. Amounts are served as _p strings.
  • GET /api/inventory/denom/{denom}/page/{page}, GET /api/inventory/owner/{owner_type}/{owner_id}
  • GET /api/guild-bank, GET /api/guild-bank/{guild_id}/history?bucket=1h|1d
  • GET /api/denom publishes the unit contract (base denoms, exponents, guild denoms with branded symbols, state suffixes, _p precision rule) so clients stop hardcoding conversions.
  • GET /api/resolve?q= resolves an object key, an address, or a name search across players, guilds and substations. GET /api/objects?ids= batch-fetches up to 25 keys.
  • GET /api/stat/{metric}/aggregate/range?object_type=&start_time=&end_time=&bucket= returns a per-bucket sum, average, population and sample count. Samples are change-triggered, so each bucket carries every object's last known value forward (LOCF) with a bounded scan; a naive per-bucket aggregate would describe only the objects that happened to move.
  • bucket and limit on the existing /api/stat/.../range endpoint, allowing a 30-day window when bucketed.
  • Counts: /api/player/count, /api/player/active/count?window_blocks=, /api/struct/count?is_destroyed=, /api/struct/status/counts, /api/planet/count, /api/fleet/count, /api/work/count
  • Power: /api/player/{id}/power, /api/player/power/at-risk?limit=, both sourced from view.player so the milliwatt arithmetic stays in one place.
  • Market: /api/provider/market (alpha-equivalent rate via guild bank ratio, committed capacity) and /api/agreement/owner/{owner}/market (blocks and escrow remaining).
  • /api/planet-raid/all/page/{page}, /api/planet-raid/status/{status}/page/{page}, /api/planet-activity/stats, /api/ledger/stats, /api/block
  • /api/grid/attribute-type/{type}/object-type/{object_type}/page/{page}

Existing endpoints

  • Guild roster and power stats gain _p precision columns beside the display values. Roster alpha now sums liquid, infused and defusing holdings on both scales.
  • ApiSqlQueryTrait gains queryOneStamped / queryAllStamped, which stamp meta.height from api_refresh_state for a named model or from current_block otherwise.
  • ObjectKeyTrait and ObjectTypes replace the object-key parsing that lived in StatReadManager.

Review fixes (verified against the live database)

  • guild_meta.denom is jsonb (an exponent-to-symbol map), so /api/denom now lists guild denoms from structs.guild and exposes the symbols as a scale.
  • grid.object_type is varchar, not the structs.object_type enum; the grid filter no longer casts.
  • The after_id cursor compared the tuple in the wrong direction for same-timestamp rows and is now correct for updated_at DESC, id ASC with NULLS LAST.
  • since_seq is restricted to the by-planet activity feed, since seq counts per planet.
  • LIKE wildcards in resolve?q= are escaped; the leaderboard discord join cannot duplicate rows.

Tests

New unit tests drive the managers through a mocked DBAL connection and assert on the composed SQL: cursor shape, unsupported-param rejection, allowlisted ordering, precision column naming, denom contract, object-key prefix ordering, and routing precedence for literal segments over {id} patterns.

docker exec docker-structs-guild-structs-webapp-1 sh -c 'cd /src && APP_ENV=test php bin/phpunit'

125 tests, 367 assertions, all passing. Every new manager method was also exercised against the running testnet database.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant