feat(nitro-cleanup): dedupe FurnitureData and clean dangling figure entries
Add a gamedata cleanup to the Nitro Cleanup panel: a read-only preview plus an apply run that dedupes FurnitureData classnames and removes rows and figure entries that reference nothing. Three passes run in a fixed order, because cleanFigureMap has to precede cleanFigureData: dropping the part that points at a set is what makes that set unreferenced. A pass refuses to write when it would delete more than maxRemovals rows (default 500) and reports the reason, a wrong asset directory otherwise turns every row into an orphan and one call would empty the file. Passes that would act on empty input (no libraries, no sets) treat that as a missing file rather than as a reason to delete everything. Every write copies the file to a timestamped backup first, so a pass that turns out to be wrong can be undone by hand. The plan reads FurnitureData once and hands the parsed copy to both furniture passes; the file is tens of megabytes in a real deployment.
This commit is contained in:
1 parent
d176fad4da
commit
944527e078
7 files changed
+2163
-1
No files matched your search
@@ -0,0 +1,24 @@
|
||||
import { apiError, apiOk } from "@/lib/api";
|
||||
import { withAdmin } from "@/lib/api-handler";
|
||||
import { planGamedataCleanup } from "@/lib/furni/gamedata-dedupe";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
|
||||
/**
|
||||
* Read-only preview of the gamedata cleanup: duplicate FurnitureData rows,
|
||||
* FurnitureData rows whose `.nitro` is gone, and the dangling/duplicated
|
||||
* FigureMap parts plus the FigureData entries nothing points at any more.
|
||||
*
|
||||
* Nothing here writes. The apply endpoint re-derives every decision under its
|
||||
* own lock, so this response is a report for the operator rather than a plan
|
||||
* that is replayed later.
|
||||
*/
|
||||
export const GET = withAdmin({ permission: PERMS.ASSETS_IMPORT }, async () => {
|
||||
try {
|
||||
return apiOk({ plan: await planGamedataCleanup() });
|
||||
} catch (err) {
|
||||
return apiError(
|
||||
`Gamedata cleanup preview failed: ${(err as Error).message}`,
|
||||
500,
|
||||
);
|
||||
}
|
||||
});
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user