feat: add manual 'verify & fix all interactions' admin tool
New POST /api/admin/import/furni/verify re-runs the full interaction verification over items_base at any time, plus a Tools dropdown entry in the furni import admin. It corrects interaction_type, interaction_modes_count and allow_sit/lay/walk against real furniture data (furnidata flags + .nitro animation states); items without real data are skipped and existing emulator handler types are preserved.
This commit is contained in:
1 parent
0b1d3b24c2
commit
2b9a015afb
3 files changed
+151
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,18 @@
|
|||||||
|
import { withAdmin } from "@/lib/api-handler";
|
||||||
|
import { apiOk } from "@/lib/api-response";
|
||||||
|
import { PERMS } from "@/lib/permissions";
|
||||||
|
import { verifyAndFixInteractionModesCount } from "@/lib/services/furni-import";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /api/admin/import/furni/verify
|
||||||
|
*
|
||||||
|
* Re-runs the interaction verification over the ENTIRE items_base table,
|
||||||
|
* correcting interaction_type, interaction_modes_count and allow_sit/
|
||||||
|
* allow_lay/allow_walk against the real furniture data (furnidata flags +
|
||||||
|
* .nitro animation states). Only items with authoritative data are touched —
|
||||||
|
* no keyword guesses, so no false positives.
|
||||||
|
*/
|
||||||
|
export const POST = withAdmin({ permission: PERMS.ASSETS_IMPORT }, async () => {
|
||||||
|
const result = await verifyAndFixInteractionModesCount();
|
||||||
|
return apiOk(result);
|
||||||
|
});
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
export const VERIFY_INTERACTIONS_URL = "/api/admin/import/furni/verify";
|
||||||
|
|
||||||
|
export interface VerifyInteractionsResult {
|
||||||
|
fixed: number;
|
||||||
|
checked: number;
|
||||||
|
skipped: number;
|
||||||
|
errors: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdminFetcher = (
|
||||||
|
input: RequestInfo | URL,
|
||||||
|
init?: RequestInit,
|
||||||
|
) => Promise<Response>;
|
||||||
|
|
||||||
|
export async function requestVerifyInteractions(
|
||||||
|
fetcher: AdminFetcher,
|
||||||
|
): Promise<VerifyInteractionsResult> {
|
||||||
|
const response = await fetcher(VERIFY_INTERACTIONS_URL, { method: "POST" });
|
||||||
|
const payload = (await response.json()) as Record<string, unknown>;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(
|
||||||
|
typeof payload.error === "string"
|
||||||
|
? payload.error
|
||||||
|
: "Interaction verification failed",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errors = Array.isArray(payload.errors)
|
||||||
|
? payload.errors.filter(
|
||||||
|
(value): value is string => typeof value === "string",
|
||||||
|
)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
return {
|
||||||
|
fixed: Number(payload.fixed) || 0,
|
||||||
|
checked: Number(payload.checked) || 0,
|
||||||
|
skipped: Number(payload.skipped) || 0,
|
||||||
|
errors,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in new issue
Block a user