Recognize imported furniture by normalized classname and local IDs
This commit is contained in:
1 parent
9dc6b8a261
commit
a78d8256e0
7 files changed
+254
-46
No files matched your search
@@ -4,6 +4,11 @@ import { eq, sql } from "drizzle-orm";
|
||||
import { withAdmin } from "@/lib/api-handler";
|
||||
import { apiError, apiOk } from "@/lib/api-response";
|
||||
import { db, ItemsBase } from "@/lib/db";
|
||||
import { normalizeClassname } from "@/lib/furni/classname";
|
||||
import {
|
||||
indexLocalFurniture,
|
||||
localFurnitureStatus,
|
||||
} from "@/lib/furni/local-presence";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { logAudit } from "@/lib/services/audit";
|
||||
import { getCloneList } from "@/lib/services/clone-import";
|
||||
@@ -298,6 +303,11 @@ export const GET = withAdmin(
|
||||
const page = parseInt(request.nextUrl.searchParams.get("page") || "1", 10);
|
||||
|
||||
// ── Browse a custom clone source (retro hotel furnidata) ────────
|
||||
const localRows = await db
|
||||
.select({ id: ItemsBase.id, itemName: ItemsBase.itemName })
|
||||
.from(ItemsBase);
|
||||
const localIndex = indexLocalFurniture(localRows);
|
||||
const importedSet = new Set(localIndex.keys());
|
||||
const sourceId = request.nextUrl.searchParams.get("source");
|
||||
if (sourceId) {
|
||||
const source = await getSource(sourceId);
|
||||
@@ -325,7 +335,7 @@ export const GET = withAdmin(
|
||||
...(fd.roomitemtypes?.furnitype ?? []),
|
||||
...(fd.wallitemtypes?.furnitype ?? []),
|
||||
]) {
|
||||
if (e.classname) furniDataSet.add(e.classname);
|
||||
if (e.classname) furniDataSet.add(normalizeClassname(e.classname));
|
||||
}
|
||||
} catch {
|
||||
/* best effort */
|
||||
@@ -345,7 +355,13 @@ export const GET = withAdmin(
|
||||
}
|
||||
|
||||
const enriched = items.map((item) => {
|
||||
const imported = item.present;
|
||||
const presence = localFurnitureStatus(
|
||||
item.classname,
|
||||
localIndex,
|
||||
furniDataSet,
|
||||
catalogIdSet,
|
||||
);
|
||||
const imported = presence.alreadyImported;
|
||||
let nitroExists = false;
|
||||
if (imported) {
|
||||
const starIdx = item.classname.indexOf("*");
|
||||
@@ -357,7 +373,17 @@ export const GET = withAdmin(
|
||||
/*turbopackIgnore: true*/ nitroDir,
|
||||
`${base}.nitro`,
|
||||
);
|
||||
nitroExists = existsSync(/*turbopackIgnore: true*/ p);
|
||||
nitroExists =
|
||||
existsSync(/*turbopackIgnore: true*/ p) ||
|
||||
(localIndex.get(normalizeClassname(item.classname)) ?? []).some(
|
||||
(row) =>
|
||||
existsSync(
|
||||
path.join(
|
||||
/*turbopackIgnore: true*/ nitroDir,
|
||||
`${row.itemName.split("*")[0]}.nitro`,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return {
|
||||
id: item.id,
|
||||
@@ -367,10 +393,9 @@ export const GET = withAdmin(
|
||||
description: item.description,
|
||||
revision: 0,
|
||||
category: String(item.category ?? ""),
|
||||
alreadyImported: imported,
|
||||
...presence,
|
||||
nitroExists,
|
||||
hasFurnidata: imported ? furniDataSet.has(item.classname) : undefined,
|
||||
hasCatalogEntry: imported ? catalogIdSet.has(item.id) : undefined,
|
||||
|
||||
iconUrl: sourceIconBase
|
||||
? `${sourceIconBase}/${encodeURIComponent(item.classname)}_icon.png`
|
||||
: undefined,
|
||||
@@ -389,16 +414,6 @@ export const GET = withAdmin(
|
||||
});
|
||||
}
|
||||
|
||||
// Pull every imported classname once so we can both (a) sort non-imported
|
||||
// items to the top *before* pagination and (b) skip the per-page lookup
|
||||
// below. Single-column indexed query — fast even at 10k+ rows.
|
||||
const allImported = await db
|
||||
.select({ itemName: ItemsBase.itemName })
|
||||
.from(ItemsBase);
|
||||
const importedSet = new Set(
|
||||
allImported.map((e) => e.itemName).filter((n): n is string => !!n),
|
||||
);
|
||||
|
||||
// Bulk-load FurnitureData and catalog references for status checks
|
||||
const furniDataSet = new Set<string>();
|
||||
const catalogIdSet = new Set<number>();
|
||||
@@ -411,7 +426,7 @@ export const GET = withAdmin(
|
||||
...(fd.roomitemtypes?.furnitype ?? []),
|
||||
...(fd.wallitemtypes?.furnitype ?? []),
|
||||
]) {
|
||||
if (e.classname) furniDataSet.add(e.classname);
|
||||
if (e.classname) furniDataSet.add(normalizeClassname(e.classname));
|
||||
}
|
||||
} catch {
|
||||
/* best effort */
|
||||
@@ -438,7 +453,13 @@ export const GET = withAdmin(
|
||||
});
|
||||
|
||||
const enriched = result.items.map((item) => {
|
||||
const imported = importedSet.has(item.classname);
|
||||
const presence = localFurnitureStatus(
|
||||
item.classname,
|
||||
localIndex,
|
||||
furniDataSet,
|
||||
catalogIdSet,
|
||||
);
|
||||
const imported = presence.alreadyImported;
|
||||
let nitroExists = false;
|
||||
if (imported) {
|
||||
const starIdx = item.classname.indexOf("*");
|
||||
@@ -450,14 +471,22 @@ export const GET = withAdmin(
|
||||
/*turbopackIgnore: true*/ nitroDir,
|
||||
`${base}.nitro`,
|
||||
);
|
||||
nitroExists = existsSync(/*turbopackIgnore: true*/ p);
|
||||
nitroExists =
|
||||
existsSync(/*turbopackIgnore: true*/ p) ||
|
||||
(localIndex.get(normalizeClassname(item.classname)) ?? []).some(
|
||||
(row) =>
|
||||
existsSync(
|
||||
path.join(
|
||||
/*turbopackIgnore: true*/ nitroDir,
|
||||
`${row.itemName.split("*")[0]}.nitro`,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
alreadyImported: imported,
|
||||
...presence,
|
||||
nitroExists,
|
||||
hasFurnidata: imported ? furniDataSet.has(item.classname) : undefined,
|
||||
hasCatalogEntry: imported ? catalogIdSet.has(item.id) : undefined,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user