fix: address code review findings for inventory delta feature
- Fix remaining f-string SQL injection in process_inventory (same pattern as single-item endpoints: parameterized ANY(:ids) queries) - Add null guard for item_id in backend delta remove handler - Add response status logging for inventory service HTTP calls - Fix frontend ID fallback consistency in updateInventoryLive - Replace debug print() with logger.debug() - Add comment for Decal Slot_Decal magic number Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f145e6e131
commit
973c3722bc
3 changed files with 22 additions and 18 deletions
|
|
@ -1357,16 +1357,15 @@ async def process_inventory(inventory: InventoryItem):
|
||||||
item_ids = await database.fetch_all(item_ids_query, {"character_name": inventory.character_name})
|
item_ids = await database.fetch_all(item_ids_query, {"character_name": inventory.character_name})
|
||||||
|
|
||||||
if item_ids:
|
if item_ids:
|
||||||
id_list = [str(row['id']) for row in item_ids]
|
db_ids = [row['id'] for row in item_ids]
|
||||||
id_placeholder = ','.join(id_list)
|
|
||||||
|
|
||||||
# Delete from all related tables first
|
# Delete from all related tables first
|
||||||
await database.execute(f"DELETE FROM item_raw_data WHERE item_id IN ({id_placeholder})")
|
for table in ('item_raw_data', 'item_combat_stats', 'item_requirements',
|
||||||
await database.execute(f"DELETE FROM item_combat_stats WHERE item_id IN ({id_placeholder})")
|
'item_enhancements', 'item_ratings', 'item_spells'):
|
||||||
await database.execute(f"DELETE FROM item_requirements WHERE item_id IN ({id_placeholder})")
|
await database.execute(
|
||||||
await database.execute(f"DELETE FROM item_enhancements WHERE item_id IN ({id_placeholder})")
|
sa.text(f"DELETE FROM {table} WHERE item_id = ANY(:ids)"),
|
||||||
await database.execute(f"DELETE FROM item_ratings WHERE item_id IN ({id_placeholder})")
|
{"ids": db_ids}
|
||||||
await database.execute(f"DELETE FROM item_spells WHERE item_id IN ({id_placeholder})")
|
)
|
||||||
|
|
||||||
# Finally delete from main items table
|
# Finally delete from main items table
|
||||||
await database.execute(
|
await database.execute(
|
||||||
|
|
@ -1419,7 +1418,7 @@ async def process_inventory(inventory: InventoryItem):
|
||||||
|
|
||||||
# Container/position tracking
|
# Container/position tracking
|
||||||
container_id=item_data.get('ContainerId', 0),
|
container_id=item_data.get('ContainerId', 0),
|
||||||
slot=int(item_data.get('IntValues', {}).get('231735296', item_data.get('IntValues', {}).get(231735296, -1))),
|
slot=int(item_data.get('IntValues', {}).get('231735296', item_data.get('IntValues', {}).get(231735296, -1))), # Decal Slot_Decal key
|
||||||
|
|
||||||
# Item state
|
# Item state
|
||||||
bonded=basic['bonded'],
|
bonded=basic['bonded'],
|
||||||
|
|
@ -3743,7 +3742,7 @@ async def get_available_items_by_slot(
|
||||||
# Debug: let's see how many items Barris actually has first
|
# Debug: let's see how many items Barris actually has first
|
||||||
debug_query = f"SELECT COUNT(*) as total FROM items WHERE {char_filter}"
|
debug_query = f"SELECT COUNT(*) as total FROM items WHERE {char_filter}"
|
||||||
debug_result = await database.fetch_one(debug_query, query_params)
|
debug_result = await database.fetch_one(debug_query, query_params)
|
||||||
print(f"DEBUG: Total items for query: {debug_result['total']}")
|
logger.debug(f"Total items for query: {debug_result['total']}")
|
||||||
|
|
||||||
# Main query to get items with slot information
|
# Main query to get items with slot information
|
||||||
query = f"""
|
query = f"""
|
||||||
|
|
|
||||||
15
main.py
15
main.py
|
|
@ -1987,18 +1987,23 @@ async def ws_receive_snapshots(
|
||||||
|
|
||||||
if action == "remove":
|
if action == "remove":
|
||||||
item_id = data.get("item_id")
|
item_id = data.get("item_id")
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
if item_id is not None:
|
||||||
await client.delete(
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||||
f"{INVENTORY_SERVICE_URL}/inventory/{char_name}/item/{item_id}"
|
resp = await client.delete(
|
||||||
)
|
f"{INVENTORY_SERVICE_URL}/inventory/{char_name}/item/{item_id}"
|
||||||
|
)
|
||||||
|
if resp.status_code >= 400:
|
||||||
|
logger.warning(f"Inventory service returned {resp.status_code} for delta remove item_id={item_id}")
|
||||||
elif action in ("add", "update"):
|
elif action in ("add", "update"):
|
||||||
item = data.get("item")
|
item = data.get("item")
|
||||||
if item:
|
if item:
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||||
await client.post(
|
resp = await client.post(
|
||||||
f"{INVENTORY_SERVICE_URL}/inventory/{char_name}/item",
|
f"{INVENTORY_SERVICE_URL}/inventory/{char_name}/item",
|
||||||
json=item
|
json=item
|
||||||
)
|
)
|
||||||
|
if resp.status_code >= 400:
|
||||||
|
logger.warning(f"Inventory service returned {resp.status_code} for delta {action}")
|
||||||
|
|
||||||
# Broadcast delta to all browser clients
|
# Broadcast delta to all browser clients
|
||||||
await _broadcast_to_browser_clients(data)
|
await _broadcast_to_browser_clients(data)
|
||||||
|
|
|
||||||
|
|
@ -1036,14 +1036,14 @@ function updateInventoryLive(delta) {
|
||||||
if (!grid) return;
|
if (!grid) return;
|
||||||
|
|
||||||
if (delta.action === 'remove') {
|
if (delta.action === 'remove') {
|
||||||
const itemId = delta.item_id;
|
const itemId = delta.item_id || (delta.item && (delta.item.Id || delta.item.id));
|
||||||
const existing = grid.querySelector(`[data-item-id="${itemId}"]`);
|
const existing = grid.querySelector(`[data-item-id="${itemId}"]`);
|
||||||
if (existing) existing.remove();
|
if (existing) existing.remove();
|
||||||
} else if (delta.action === 'add') {
|
} else if (delta.action === 'add') {
|
||||||
const newSlot = createInventorySlot(delta.item);
|
const newSlot = createInventorySlot(delta.item);
|
||||||
grid.appendChild(newSlot);
|
grid.appendChild(newSlot);
|
||||||
} else if (delta.action === 'update') {
|
} else if (delta.action === 'update') {
|
||||||
const itemId = delta.item.Id || delta.item.id;
|
const itemId = delta.item.Id || delta.item.id || delta.item.item_id;
|
||||||
const existing = grid.querySelector(`[data-item-id="${itemId}"]`);
|
const existing = grid.querySelector(`[data-item-id="${itemId}"]`);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
const newSlot = createInventorySlot(delta.item);
|
const newSlot = createInventorySlot(delta.item);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue