From 02083c1cf9ce4858977413704d9a7bab93796ec8 Mon Sep 17 00:00:00 2001 From: Aodhan Date: Tue, 8 Jul 2025 23:37:57 +0100 Subject: [PATCH] Fix --- backend/app/router.py | 89 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/backend/app/router.py b/backend/app/router.py index 065e9bc..28fd511 100644 --- a/backend/app/router.py +++ b/backend/app/router.py @@ -162,24 +162,95 @@ async def items( ): """Return items from all_items view with pagination.""" offset = (page - 1) * page_size - params = {"limit": page_size, "offset": offset} - where_clauses = ["name != '.'"] + + params: dict[str, Any] = {"limit": page_size, "offset": offset} + where_clauses: list[str] = ["a.name != '.'"] if type: - if type == 'MANNEQUIN': - where_clauses.append("type_description IN ('MANNEQUIN', 'NOTHING', 'UNKNOWN')") + if type == "MANNEQUIN": + where_clauses.append("a.type_description IN ('MANNEQUIN', 'NOTHING', 'UNKNOWN')") else: - where_clauses.append("type_description = :type") + where_clauses.append("a.type_description = :type") params["type"] = type if search: - where_clauses.append("name ILIKE :search") + where_clauses.append("a.name ILIKE :search") params["search"] = f"%{search}%" where_sql = f"WHERE {' AND '.join(where_clauses)}" if where_clauses else "" - # Calculate total count for pagination - count_q = text(f"SELECT COUNT(*) FROM all_items {where_sql}") + join_sql = "FROM all_items a LEFT JOIN armor_items ai ON ai.id = a.id" + + # Total count for pagination (exclude limit/offset) + count_params = {k: v for k, v in params.items() if k not in ("limit", "offset")} + count_q = text(f"SELECT COUNT(*) {join_sql} {where_sql}") + total_res = await session.execute(count_q, count_params) + total_count = total_res.scalar() or 0 + response.headers["X-Total-Count"] = str(total_count) + + # Main query + q = text( + f"SELECT a.id, a.name, a.icon_id, a.type_description, ai.jobs_description " + f"{join_sql} {where_sql} ORDER BY a.id LIMIT :limit OFFSET :offset" + ) + result = await session.execute(q, params) + rows = result.fetchall() + return [ + ItemSummary( + id=r.id, + name=r.name, + icon_id=r.icon_id, + type_description=r.type_description, + jobs_description=r.jobs_description, + ) + for r in rows + ] +async def items( + response: Response, + type: Optional[str] = Query(None, alias="type"), + search: Optional[str] = Query(None, description="Substring search on item name"), + page: int = Query(1, ge=1), + page_size: int = Query(40, ge=1, le=100), + session: AsyncSession = Depends(get_session), +): + """Return items from all_items view with pagination.""" + offset = (page - 1) * page_size + params: dict[str, Any] = {"limit": page_size, "offset": offset} + where_clauses: list[str] = ["a.name != '.'"] + + if type: + if type == "MANNEQUIN": + where_clauses.append("a.type_description IN ('MANNEQUIN', 'NOTHING', 'UNKNOWN')") + else: + where_clauses.append("a.type_description = :type") + params["type"] = type + + if search: + where_clauses.append("a.name ILIKE :search") + params["search"] = f"%{search}%" + + where_sql = f"WHERE {' AND '.join(where_clauses)}" if where_clauses else "" + + # Use LEFT JOIN to fetch jobs_description from armor_items table; it will be NULL for non-armor. + join_sql = "FROM all_items a LEFT JOIN armor_items ai ON ai.id = a.id" + params = {"limit": page_size, "offset": offset} + where_clauses = ["a.name != '.'"] + + if type: + if type == 'MANNEQUIN': + where_clauses.append("a.type_description IN ('MANNEQUIN', 'NOTHING', 'UNKNOWN')") + else: + where_clauses.append("a.type_description = :type") + params["type"] = type + + if search: + where_clauses.append("a.name ILIKE :search") + params["search"] = f"%{search}%" + + where_sql = f"WHERE {' AND '.join(where_clauses)}" if where_clauses else "" + + # Calculate total count for pagination + count_q = text(f"SELECT COUNT(*) {join_sql} {where_sql}") {join_sql} {where_sql}") # Use only relevant params for count query (exclude limit/offset) count_params = {k: v for k, v in params.items() if k not in ("limit", "offset")} total_res = await session.execute(count_q, count_params) @@ -196,6 +267,8 @@ async def items( return [ItemSummary(id=r.id, name=r.name, icon_id=r.icon_id, type_description=r.type_description, jobs_description=r.jobs_description) for r in rows] + + class ItemDetail(BaseModel): id: int name: str