6.3 KiB
InventoryApi document shapes
This service stores one MongoDB document per inventory item record.
Inbound JSON documents
-
CreateItemDefinitionRequest (
POST /api/inventory/item-definitions){ "itemKey": "wood", "displayName": "Wood", "stackable": true, "maxStackSize": 20, "category": "resource", "equipSlot": null } -
UpdateItemDefinitionRequest (
PUT /api/inventory/item-definitions/{itemKey}){ "displayName": "Wood", "stackable": true, "maxStackSize": 20, "category": "resource", "equipSlot": null } -
GrantInventoryItemRequest (
POST /api/inventory/by-owner/{ownerType}/{ownerId}/grant){ "itemKey": "string", "quantity": 1, "preferredSlot": 0 }preferredSlotis optional. If omitted, the service finds a valid destination slot. -
MoveInventoryItemRequest (
POST /api/inventory/by-owner/{ownerType}/{ownerId}/move){ "itemId": "uuid-string", "toSlot": 1, "quantity": 1 }quantityis optional. If omitted, move the full stack. -
TransferInventoryItemRequest (
POST /api/inventory/transfer){ "itemId": "uuid-string", "fromOwnerType": "character", "fromOwnerId": "string", "toOwnerType": "location", "toOwnerId": "string", "toSlot": 0, "quantity": 1 }toSlotandquantityare optional. If omitted, the service finds a valid destination and transfers the full stack. -
ConsumeInventoryItemRequest (
POST /api/inventory/items/{itemId}/consume){ "quantity": 1 } -
EquipInventoryItemRequest (
POST /api/inventory/items/{itemId}/equip){ "ownerId": "string", "equipmentSlot": "weapon" }Only valid for items currently owned by a character inventory.
-
UnequipInventoryItemRequest (
POST /api/inventory/items/{itemId}/unequip){ "ownerId": "string", "preferredSlot": 0 }Only valid for items currently equipped by a character.
Stored documents (MongoDB)
-
ItemDefinition
{ "itemKey": "wood", "displayName": "Wood", "stackable": true, "maxStackSize": 20, "category": "resource", "equipSlot": null, "createdUtc": "string (ISO-8601 datetime)", "updatedUtc": "string (ISO-8601 datetime)" } -
InventoryItem
{ "id": "string (UUID)", "itemKey": "wood", "quantity": 12, "ownerType": "character", "ownerId": "string (ObjectId or stable external id)", "ownerUserId": "string (ObjectId from auth token, null for public world owners)", "slot": 0, "equippedSlot": null, "createdUtc": "string (ISO-8601 datetime)", "updatedUtc": "string (ISO-8601 datetime)" }
Equipped character item example:
{
"id": "string (UUID)",
"itemKey": "pistol",
"quantity": 1,
"ownerType": "character",
"ownerId": "string (Character ObjectId)",
"ownerUserId": "string (ObjectId from auth token)",
"slot": null,
"equippedSlot": "weapon",
"createdUtc": "string (ISO-8601 datetime)",
"updatedUtc": "string (ISO-8601 datetime)"
}
Location stack example:
{
"id": "string (UUID)",
"itemKey": "wood",
"quantity": 12,
"ownerType": "location",
"ownerId": "string (Location ObjectId)",
"ownerUserId": null,
"slot": 3,
"equippedSlot": null,
"createdUtc": "string (ISO-8601 datetime)",
"updatedUtc": "string (ISO-8601 datetime)"
}
Outbound JSON documents
-
ItemDefinitionResponse
{ "itemKey": "wood", "displayName": "Wood", "stackable": true, "maxStackSize": 20, "category": "resource", "equipSlot": null, "updatedUtc": "string (ISO-8601 datetime)" } -
InventoryItemResponse
{ "id": "string (UUID)", "itemKey": "wood", "quantity": 12, "ownerType": "character", "ownerId": "string", "slot": 0, "equippedSlot": null, "updatedUtc": "string (ISO-8601 datetime)" } -
InventoryOwnerResponse (
GET /api/inventory/by-owner/{ownerType}/{ownerId}){ "ownerType": "character", "ownerId": "string", "items": [ { "id": "string (UUID)", "itemKey": "wood", "quantity": 12, "ownerType": "character", "ownerId": "string", "slot": 0, "equippedSlot": null, "updatedUtc": "string (ISO-8601 datetime)" } ] } -
TransferInventoryResponse (
POST /api/inventory/transfer){ "movedItemId": "string (UUID)", "fromOwnerType": "character", "fromOwnerId": "string", "toOwnerType": "location", "toOwnerId": "string", "fromItems": [], "toItems": [] }
Validation rules
itemKeymust map to an existing item definition before item instances can be createdownerTypemust be a supported container typeownerIdmust map to an existing owning entity where applicable- non-
SUPERcallers may only access owned character items unless explicit gameplay rules allow a world container read/write quantitymust be greater than0- non-stackable item definitions must have
maxStackSize = 1 - non-stackable items must have
quantity = 1 - equipped items must have
slot = null - unequipped bag items must have
equippedSlot = null - an item must not have both
slotandequippedSlotpopulated - slot occupancy must be unique for
(ownerType, ownerId, slot)whereslot != null - equipment occupancy must be unique for
(ownerType, ownerId, equippedSlot)whereequippedSlot != null
Recommended indexes
- unique on
itemKeyfor item definitions - index on
(ownerType, ownerId) - unique on
(ownerType, ownerId, slot)for bag slots - unique on
(ownerType, ownerId, equippedSlot)for equipped slots - index on
itemKeyfor inventory items
Behavior rules
- moving a full non-stackable item should update its owner and slot in place
- moving part of a stack should split the stack and create a new item record with a new UUID for the moved quantity
- moving into a compatible stack should merge quantities and delete or reduce the source record
- cross-owner transfer should be transactional when it mutates multiple records
- auctions should reference
itemIdvalues directly instead of copying item state into the auction document - the service does not auto-seed item definitions;
ItemDefinitionsmust be populated explicitly