Implement native XML GMI in PRK.Client
## Outcome Add a native XML/presenter-based GMI to `PRK.Client`, opened with `/gmi` and backed by a versioned JSON API in `PRK.ClientWebEngine`. The initial release covers standard player buy, sell, and own-listing management only. Existing server-rendered market views remain available to the original AO client. ## Initial scope - Browse/search/filter/page market items and obtain only the pricing/item presentation data needed by the buy flow. - Create buy listings. - List eligible character inventory and create sell listings. - List, inspect, collect, and cancel the current character's listings. - Open through `/gmi`; PlayfieldEngine remains authoritative for terminal proximity. - Exclude work orders, market history, and all GM/admin functionality from the native API and UI. ## Constraints - Keep the existing server-rendered `/market/*` experience working. - Do not duplicate MarketEngine business rules in `PRK.Client`; validation, authorization, proximity enforcement, pricing, matching, escrow, and deduplication remain server-owned. - Treat the HTTP API as a strict public security boundary. Define dedicated allowlisted API DTOs and map fields explicitly; never serialize InterComms responses, EF entities, or internal market models directly. - API responses must expose no player-visible information beyond what the equivalent authenticated server-rendered views already reveal. In particular, regular players must not receive GM-only pricing provenance/sample counts, other characters' identity/account data, internal template/instance identifiers unless required for an existing action, correlation IDs, dedup internals, escrow state, or implementation diagnostics. - Derive character/account/GM context from the validated active character id and zone cookie, never from client-supplied identity fields. Never persist or log session credentials. - Reuse shared typed API contracts and the client's XML layout, presenter, window lifecycle, item presentation, tooltip, confirmation, chat-command, and session teardown patterns. - Preserve idempotency for mutations and reject stale responses across closing, zoning, reconnecting, and logout. - Keep the NativeAOT client compatible through trim-safe JSON serialization. ## Acceptance criteria - `/gmi` opens the native market window during an in-play session; unauthorized or out-of-range access produces an actionable error from the existing PlayfieldEngine validation path. - The native UI supports item search/browse, buy creation, eligible inventory selection and sell creation, and listing/collect/cancel flows with loading, empty, success, and error states. - `/api/v1/market` exposes only dedicated explicitly mapped contracts for those flows. An endpoint/contract audit and automated serialization tests prove that excluded internal and GM-only fields are absent. - Malformed input, auth failures, timeouts, conflicts, and server failures return stable, non-diagnostic JSON errors without stack traces or internal transport details. - The Razor GMI remains functional through shared application services/facades rather than duplicated business logic. - Successful mutations refresh relevant state, duplicate submissions are prevented, and obsolete-session responses cannot update the current UI. - API, client state/presenter, build, market regression, local-stack proximity, and Razor regression validation pass. ## Validation status Implementation, focused client tests, API contract/security tests, ClientWebEngine build, and production client build pass. `compose.dev.yml` now builds and runs MarketEngine and ClientWebEngine with MSSQL/RabbitMQ; MarketEngine applies migrations, builds its category index, and exposes metrics on 9093, while ClientWebEngine exposes the API on 8080 and returns the expected JSON 401 without credentials. Closed at the user's request. Final authenticated in-client proximity and buy/sell/collect/cancel verification was not recorded; the remaining validation checklist item is left unchecked. The legacy net8 MarketEngine test suite cannot start in this environment because `Microsoft.AspNetCore.App 8.0` is not installed. Full client tests ran 2,378 passing with 68 install-data tests failing only because `PRK_INSTALL_ROOT`/`PRK_DATAROOT` are unset. ## Pull request - [#2522 — WIP: feature: Add native GMI client](https://git.project-rk.com/prk/engines/pulls/2522)
Checklist
7 of 8 complete- Define versioned, allowlisted market API contracts for buy, sell, and own-listing flows; explicitly map only fields already visible in equivalent player Razor views.
- Expose authenticated `/api/v1/market` buy, sell, search, inventory, listing, collect, and cancel endpoints over shared web-engine services, with validation, safe error mapping, and idempotency.
- Add a session-scoped, trim-safe PRK.Client market API client that supplies active zone credentials and cancels obsolete requests.
- Implement the native XML GMI window and presenter/state flow for item search, buy creation, inventory-backed sell creation, and own listing collect/cancel.
- Add `/gmi` to the existing client chat-command flow, open the in-play market window, and clear/cancel state safely on close, zoning, reconnect, and logout.
- Add API contract/auth/error and native presenter/state tests, including negative serialization assertions for internal, GM-only, identity, correlation, escrow, and diagnostic fields.
- Add MarketEngine and ClientWebEngine services to `compose.dev.yml` with shared infrastructure, game-data mounts, local web/API exposure, and validated Compose configuration.
- Verify ClientWebEngine, PRK.Client, and market tests, then exercise the full native GMI flow against the local stack near a terminal while regression-checking Razor views.
- Area
- Project Rubi-Ka
- Project
- engines
- Kind
- Feature
- Priority
- High
- Task ID
tsk_ns9pgxkp8x- Updated