neon-sprawl/docs/plans/NEO-53-implementation-plan.md

6.8 KiB

NEO-53 — Implementation plan

Story reference

Field Value
Key NEO-53
Title E3.M3: GET world item-definitions + Bruno
Linear https://linear.app/neon-sprawl/issue/NEO-53/e3m3-get-world-item-definitions-bruno
Module E3.M3 — ItemizationAndInventorySchema · Epic 3 Slice 1 (E3M3-04)
Branch NEO-53-get-world-item-definitions-bruno
Precursor NEO-52IItemDefinitionRegistry + DI (Done on main)
Pattern NEO-36GET /game/world/skill-definitions

Kickoff clarifications

Topic Question Agent recommendation Answer
JSON row fields Expose required five only vs all schema fields (optional nullables)? Required five only — prototype rows omit rarity / bindPolicy / durabilityMax; mirrors NEO-36 exposing loaded catalog fields only. User: required five only.
Route path /game/world/… vs /game/content/…? GET /game/world/item-definitions — E3M3 backlog + parallel to skill-definitions. User: world path.
Manual QA doc Add docs/manual-qa/NEO-53.md? Yes — user-visible HTTP surface; same pattern as NEO-36. User: yes.

Goal, scope, and out-of-scope

Goal: Expose a stable, read-only JSON endpoint that returns all loaded prototype item definitions for dev tooling, Bruno, manual QA, and future client/codegen, backed by IItemDefinitionRegistry without duplicating catalog truth outside the server.

In scope (from Linear + E3M3-04):

  • GET /game/world/item-definitions with versioned envelope (schemaVersion 1, items array).
  • Row fields: id, displayName, prototypeRole, stackMax, inventorySlotKind (camelCase JSON).
  • Items ordered by id ordinal, matching GetDefinitionsInIdOrder().
  • Bruno folder bruno/neon-sprawl-server/item-definitions/.
  • docs/manual-qa/NEO-53.md.
  • server/README.md section.
  • API integration tests (AAA).

Out of scope (from Linear):

  • Per-player inventory mutation (NEO-54+).
  • Optional schema fields (rarity, bindPolicy, durabilityMax) until content ships them.
  • Client HUD.

Acceptance criteria checklist

  • GET returns all six prototype defs with schemaVersion 1.
  • Bruno happy path documented and runnable against dev server.
  • Automated API tests (AAA) assert six ids, id order, and spot-check metadata.

Technical approach

  1. Route: GET /game/world/item-definitions — parameterless read; inject IItemDefinitionRegistry only (not ItemDefinitionCatalog).

  2. Response shape: Top-level schemaVersion (ItemDefinitionsListResponse.CurrentSchemaVersion = 1) plus items array. Each row maps from ItemDefRow: id, displayName, prototypeRole, stackMax, inventorySlotKind. Do not emit optional null fields on this contract.

  3. Ordering: Build list from registry.GetDefinitionsInIdOrder() (already ordinal by id). Tests assert exact id sequence:

    contract_handoff_token, field_stim_mk0, prototype_armor_shell, refined_plate_stock, scrap_metal_bulk, survey_drone_kit.

  4. Implementation: New ItemDefinitionsWorldApi + ItemDefinitionsListDtos.cs in Game/Items/ (mirror SkillDefinitionsWorldApi). Wire app.MapItemDefinitionsWorldApi() from Program.cs next to MapSkillDefinitionsWorldApi().

  5. Bruno: bruno/neon-sprawl-server/item-definitions/ with Get item definitions.bru + folder.bru. Tests: 200, JSON, schemaVersion 1, items.length === 6, ascending id order, frozen six ids present, spot-check scrap_metal_bulk (stackMax 999, prototypeRole material).

  6. Docs: docs/manual-qa/NEO-53.md (mirror NEO-36). Update server/README.md item section with GET + curl. Update E3_M3 Related implementation slices and documentation_and_implementation_alignment.md E3.M3 row when landed.

Files to add

Path Purpose
server/NeonSprawl.Server/Game/Items/ItemDefinitionsWorldApi.cs Map* extension registering GET route; maps registry → JSON.
server/NeonSprawl.Server/Game/Items/ItemDefinitionsListDtos.cs Versioned response + row DTOs for JSON serialization.
server/NeonSprawl.Server.Tests/Game/Items/ItemDefinitionsWorldApiTests.cs HTTP integration: 200, schema v1, six ids in order, spot-check rows.
bruno/neon-sprawl-server/item-definitions/Get item definitions.bru Manual / Bruno verification against dev server.
bruno/neon-sprawl-server/item-definitions/folder.bru Bruno folder metadata (match skill-definitions).
docs/manual-qa/NEO-53.md Checklist: start server, curl GET, confirm six ids + spot-check.

Files to modify

Path Rationale
server/NeonSprawl.Server/Program.cs Register MapItemDefinitionsWorldApi() alongside other game APIs.
server/README.md Document GET /game/world/item-definitions, curl example, links to plan/manual QA/Bruno.
docs/decomposition/modules/E3_M3_ItemizationAndInventorySchema.md Related implementation slices — HTTP read model bullet (NEO-53).
docs/decomposition/modules/documentation_and_implementation_alignment.md E3.M3 row — note NEO-53 HTTP projection when landed.

Tests

Test file What it covers
server/NeonSprawl.Server.Tests/Game/Items/ItemDefinitionsWorldApiTests.cs Integration: GET /game/world/item-definitions via InMemoryWebApplicationFactory; ReadFromJsonAsync; assert schemaVersion 1; items count 6; ordered id list equals frozen six (ordinal); spot-check scrap_metal_bulk (displayName, stackMax 999, prototypeRole material, inventorySlotKind bag) and prototype_armor_shell (inventorySlotKind equipment). AAA per csharp-style.

Bruno scripts complement automated tests for manual dev-server verification.

Open questions / risks

Question / risk Agent recommendation Status
Linear blockedBy NEO-52 Rebase/branch from main where NEO-52 is merged (already on main at kickoff). adopted
Optional fields later When content adds rarity / bind / durability, bump schemaVersion or extend v1 with documented null semantics in a follow-up issue. deferred

None blocking.