Transmission #063: Character Inventory Persistence on Create
createCharacter now actually persists data. Previously it assembled a stub response and threw it away; now it creates a real inventory row and populates it with whatever items the caller sends in.
What changed
InventoryRepository gained two new methods following the jOOQ patterns already established in the file:
createInventory(int ownerId, InternalInventoryType type, int capacity, String name)— inserts into theinventorytable and returns the hydratedInternalInventory. Character inventories are created with typeCHARACTER, a capacity of 1000, and a null name.addItems(List<InternalItem> items, int inventoryId)— transactionally assigns each item a free slot and batch-inserts intoinventory_item. Uses an in-memory set of used slots to avoid N+1 slot-lookup queries inside the loop. Shares the refactoredfindFirstOpenSlot(Set<Integer>, int)overload that the existing single-itemaddToInventorypath now delegates to.
ItemModelMapper.fromDTOToModel(Item dto) is implemented (was UnsupportedOperationException). It maps the OpenAPI Item DTO to InternalItem, using a top-of-class DEFAULT_TIMESTAMP = Instant.EPOCH constant for createdAt/updatedAt when real timestamps aren’t available. Fields absent in a minimal DTO (e.g. when converting from a CharacterItem reference) fall back to empty strings or InternalItemType.MATERIAL.
CharactersApiImpl.createCharacter now:
- Creates a CHARACTER inventory for the new owner ID.
- Converts the incoming
CharacterItemlist toInternalItemviaItemModelMapper.fromDTOToModel, constructing a minimalItemDTO from each item reference. - Calls
addItemsto seed the inventory.
Why it matters
Characters entering the game with a starting kit now have that kit durably stored in the database rather than silently discarded. This is the first write path through the character endpoint and sets the pattern for future character-creation logic.