Remove import/repair feature and related API routes.
Local Build and Deploy / deploy (push) Successful in 1m41s
Local Build and Deploy / deploy (push) Successful in 1m41s
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
bb7d581084
commit
49d204e85c
9 files changed
+2
-1468
No files matched your search
@@ -1,11 +0,0 @@
|
||||
import { withAdmin } from "@/lib/api-handler";
|
||||
import { apiOk } from "@/lib/api-response";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { auditImportedAssets } from "@/lib/services/furni-repair";
|
||||
|
||||
// Audit is expensive (scans every imported item's files on disk).
|
||||
// Using POST keeps it out of any cache layer that might front GET.
|
||||
export const POST = withAdmin({ permission: PERMS.ASSETS_IMPORT }, async () => {
|
||||
const summary = await auditImportedAssets();
|
||||
return apiOk(summary as unknown as Record<string, unknown>);
|
||||
});
|
||||
@@ -1,135 +0,0 @@
|
||||
import { withAdmin } from "@/lib/api-handler";
|
||||
import { apiError } from "@/lib/api-response";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { repairItem } from "@/lib/services/furni-repair";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
|
||||
/**
|
||||
* SSE batch repair route.
|
||||
* Body: { classnames: string[], concurrency?: number }
|
||||
* Streams one `data: {...}` event per item.
|
||||
*/
|
||||
export const POST = withAdmin(
|
||||
{ permission: PERMS.ASSETS_IMPORT },
|
||||
async (request) => {
|
||||
const body = await request.json();
|
||||
const classnames: string[] = Array.isArray(body.classnames)
|
||||
? body.classnames
|
||||
: [];
|
||||
// Bumped default to 6 (cap 8). Since downloadFile no longer retries on
|
||||
// deterministic 404s, misses complete in ~1 request instead of ~4 × 15s.
|
||||
const concurrency = Math.min(Math.max(body.concurrency || 6, 1), 8);
|
||||
|
||||
if (classnames.length === 0) return apiError("No classnames provided", 400);
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
const stream = new ReadableStream({
|
||||
async start(controller) {
|
||||
const send = (data: unknown) => {
|
||||
try {
|
||||
controller.enqueue(
|
||||
encoder.encode(`data: ${JSON.stringify(data)}\n\n`),
|
||||
);
|
||||
} catch {
|
||||
/* stream closed */
|
||||
}
|
||||
};
|
||||
|
||||
const startTime = Date.now();
|
||||
send({ type: "repair_start", total: classnames.length });
|
||||
|
||||
let succeeded = 0;
|
||||
let failed = 0;
|
||||
let partial = 0;
|
||||
let unrepairable = 0;
|
||||
|
||||
for (let i = 0; i < classnames.length; i += concurrency) {
|
||||
const chunk = classnames.slice(i, i + concurrency);
|
||||
|
||||
const promises = chunk.map(async (classname) => {
|
||||
send({ type: "repair_progress", classname, status: "working" });
|
||||
try {
|
||||
const result = await repairItem(classname);
|
||||
if (result.unrepairable) unrepairable++;
|
||||
if (result.ok) {
|
||||
succeeded++;
|
||||
send({
|
||||
type: "repair_progress",
|
||||
classname,
|
||||
status: "done",
|
||||
nitroRepaired: result.nitroRepaired,
|
||||
iconRepaired: result.iconRepaired,
|
||||
warnings: result.warnings,
|
||||
});
|
||||
} else {
|
||||
// Counts as partial if at least one asset was fixed
|
||||
if (result.iconRepaired || result.nitroRepaired) {
|
||||
partial++;
|
||||
send({
|
||||
type: "repair_progress",
|
||||
classname,
|
||||
status: "partial",
|
||||
nitroRepaired: result.nitroRepaired,
|
||||
iconRepaired: result.iconRepaired,
|
||||
warnings: result.warnings,
|
||||
error: result.error,
|
||||
unrepairable: result.unrepairable,
|
||||
});
|
||||
} else {
|
||||
failed++;
|
||||
send({
|
||||
type: "repair_progress",
|
||||
classname,
|
||||
status: "failed",
|
||||
warnings: result.warnings,
|
||||
error:
|
||||
result.error || result.warnings[0] || "Unknown error",
|
||||
unrepairable: result.unrepairable,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
failed++;
|
||||
send({
|
||||
type: "repair_progress",
|
||||
classname,
|
||||
status: "failed",
|
||||
error: (err as Error).message,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.allSettled(promises);
|
||||
}
|
||||
|
||||
// RCON refresh so the emulator picks up any items_base changes
|
||||
try {
|
||||
await rcon.updateItems();
|
||||
await rcon.updateCatalog();
|
||||
} catch {
|
||||
/* non-fatal */
|
||||
}
|
||||
|
||||
send({
|
||||
type: "repair_complete",
|
||||
succeeded,
|
||||
partial,
|
||||
failed,
|
||||
unrepairable,
|
||||
duration: Date.now() - startTime,
|
||||
});
|
||||
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
|
||||
return new Response(stream, {
|
||||
headers: {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Cache-Control": "no-cache",
|
||||
Connection: "keep-alive",
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user