Fix catalog items missing due to page_id VARCHAR mismatch.
Local Build and Deploy / deploy (push) Successful in 56s
Local Build and Deploy / deploy (push) Successful in 56s
Use raw SQL for counts/loads/creates/moves so Habbo DBs with VARCHAR page_id and no AUTO_INCREMENT still show and persist furni. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
33a8a19820
commit
7bc0845932
6 files changed
+139
-79
No files matched your search
@@ -135,8 +135,11 @@ export async function loadCatalogItemsData(
|
||||
): Promise<CatalogItemsData> {
|
||||
// Load items via raw query to work around pageId Int vs VARCHAR mismatch
|
||||
const pageIdStr = String(pageId);
|
||||
// CAST: live Habbo DBs often store page_id as VARCHAR while Prisma maps Int.
|
||||
const rawItems = await prisma.$queryRaw<Array<Record<string, unknown>>>`
|
||||
SELECT * FROM catalog_items WHERE page_id = ${pageIdStr} ORDER BY id ASC
|
||||
SELECT * FROM catalog_items
|
||||
WHERE CAST(page_id AS CHAR) = ${pageIdStr}
|
||||
ORDER BY order_number ASC, id ASC
|
||||
`;
|
||||
const items: RawItem[] = rawItems.map((r: Record<string, unknown>) => ({
|
||||
id: Number(r.id),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Prisma } from "@/generated/prisma/client";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
export type { NestedTreeNode, TreeNode } from "@/types/catalog";
|
||||
@@ -9,27 +10,43 @@ function toInt(value: unknown, fallback = 0): number {
|
||||
return Number.isFinite(n) ? n : fallback;
|
||||
}
|
||||
|
||||
async function safeItemCounts(
|
||||
/**
|
||||
* Count catalog_items per page via raw SQL.
|
||||
* Real Habbo DBs often store page_id as VARCHAR; Prisma Int groupBy fails or returns 0.
|
||||
*/
|
||||
export async function getCatalogItemCounts(
|
||||
pageIds?: number[],
|
||||
): Promise<Map<number, number>> {
|
||||
const map = new Map<number, number>();
|
||||
try {
|
||||
if (pageIds && pageIds.length === 0) return map;
|
||||
const itemCounts = pageIds
|
||||
? await prisma.catalogItems.groupBy({
|
||||
by: ["pageId"],
|
||||
where: { pageId: { in: pageIds } },
|
||||
_count: true,
|
||||
})
|
||||
: await prisma.catalogItems.groupBy({
|
||||
by: ["pageId"],
|
||||
_count: true,
|
||||
});
|
||||
for (const c of itemCounts) {
|
||||
map.set(toInt(c.pageId), c._count);
|
||||
|
||||
if (pageIds) {
|
||||
const idStrs = pageIds.map(String);
|
||||
const rows = await prisma.$queryRaw<
|
||||
Array<{ page_id: string | number; cnt: number | bigint }>
|
||||
>`
|
||||
SELECT page_id, COUNT(*) as cnt
|
||||
FROM catalog_items
|
||||
WHERE CAST(page_id AS CHAR) IN (${Prisma.join(idStrs)})
|
||||
GROUP BY page_id
|
||||
`;
|
||||
for (const r of rows) {
|
||||
map.set(toInt(r.page_id), toInt(r.cnt));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
const rows = await prisma.$queryRaw<
|
||||
Array<{ page_id: string | number; cnt: number | bigint }>
|
||||
>`
|
||||
SELECT page_id, COUNT(*) as cnt FROM catalog_items GROUP BY page_id
|
||||
`;
|
||||
for (const r of rows) {
|
||||
map.set(toInt(r.page_id), toInt(r.cnt));
|
||||
}
|
||||
} catch {
|
||||
// Some DBs store page_id as VARCHAR — ignore counts rather than failing the tree.
|
||||
// Best-effort — never break the tree for count failures.
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@@ -41,7 +58,7 @@ export async function getTreeFlat(): Promise<TreeNode[]> {
|
||||
const allPages = await prisma.catalogPages.findMany({
|
||||
orderBy: { orderNum: "asc" },
|
||||
});
|
||||
const itemCountMap = await safeItemCounts();
|
||||
const itemCountMap = await getCatalogItemCounts();
|
||||
|
||||
const childCountMap = new Map<number, number>();
|
||||
for (const p of allPages) {
|
||||
@@ -261,5 +278,4 @@ export async function getAncestors(
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
/** Safe item-count helper exported for the tree API route. */
|
||||
export { safeItemCounts, toInt };
|
||||
export { toInt };
|
||||
Reference in new issue
Block a user