feat(studio): recover matching Nitro sources and persist import phases
This commit is contained in:
1 parent
00e33623f7
commit
13bd3695cb
45 files changed
+903
-28
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { createStore, runWithStore } from "@/lib/foundation/request-context";
|
||||
import type { IpAddress, RequestId, UserId } from "@/lib/foundation/types";
|
||||
import type { ImportJob } from "@/lib/furni/import-job";
|
||||
import { IMPORT_PHASES, type ImportJob } from "@/lib/furni/import-job";
|
||||
import { redis } from "@/lib/redis";
|
||||
import { logServerError } from "@/lib/server-log";
|
||||
import { logAudit } from "./audit";
|
||||
@@ -14,6 +14,7 @@ import { ensureDirectories, importSingleFurni } from "./furni-import";
|
||||
import { ImportJobStore } from "./furni-job-store";
|
||||
import { runSyncJobItem } from "./furni-sync-item";
|
||||
import { repairFurniture } from "./furniture-repair";
|
||||
import { recoverFurnitureNitro } from "./furniture-source-recovery";
|
||||
import { rcon } from "./rcon";
|
||||
|
||||
const LOCK = "furniture-import-worker:v1";
|
||||
@@ -120,7 +121,15 @@ async function drain() {
|
||||
break;
|
||||
}
|
||||
item.state = "running";
|
||||
await saveOwned(job);
|
||||
const onProgress = async (status: string) => {
|
||||
const phase = IMPORT_PHASES.find((value) => value === status);
|
||||
if (!phase) return;
|
||||
if (item.phase !== phase)
|
||||
item.phaseStartedAt = new Date().toISOString();
|
||||
item.phase = phase;
|
||||
await saveOwned(job);
|
||||
};
|
||||
await onProgress("validating");
|
||||
try {
|
||||
if (job.sourceId && !source)
|
||||
throw Error("Import source no longer exists");
|
||||
@@ -133,12 +142,32 @@ async function drain() {
|
||||
: undefined;
|
||||
await requireLease();
|
||||
const result = job.syncKind
|
||||
? await runSyncJobItem(item)
|
||||
? await runSyncJobItem(item, onProgress)
|
||||
: await (job.mode === "repair"
|
||||
? repairFurniture
|
||||
: importSingleFurni)({
|
||||
...item,
|
||||
repairExisting: true,
|
||||
onProgress,
|
||||
resolveMissingNitro: async (revision) => {
|
||||
const recovered = await recoverFurnitureNitro(
|
||||
{ ...item, revision },
|
||||
{
|
||||
excludeSourceId: job.sourceId,
|
||||
onAttempt: async (name) => {
|
||||
item.sourceAttempt = name;
|
||||
await onProgress("checking_sources");
|
||||
},
|
||||
},
|
||||
);
|
||||
await requireLease();
|
||||
if (!recovered) return undefined;
|
||||
const { buffer, ...provenance } = recovered;
|
||||
item.recoveredSource = provenance;
|
||||
item.sourceAttempt = undefined;
|
||||
await saveOwned(job);
|
||||
return buffer;
|
||||
},
|
||||
providedNitro,
|
||||
sourceSwfBaseUrl: source?.sourceSwfBaseUrl,
|
||||
nitroBaseUrl: source?.nitroBaseUrl,
|
||||
@@ -148,7 +177,6 @@ async function drain() {
|
||||
item.warnings = result.warnings;
|
||||
item.itemId = result.itemId;
|
||||
if (!result.ok) throw Error(result.error || "Import failed");
|
||||
item.state = "done";
|
||||
await logAudit({
|
||||
userId: job.userId,
|
||||
action: "furni_import",
|
||||
@@ -171,12 +199,14 @@ async function drain() {
|
||||
});
|
||||
if (job.translate && job.mode !== "repair")
|
||||
try {
|
||||
await onProgress("translating");
|
||||
await patchLocalizedFurniDataEntries([item], true, job.langs);
|
||||
} catch {
|
||||
item.warnings.push(
|
||||
"Translation failed; furniture imported successfully",
|
||||
);
|
||||
}
|
||||
item.state = "done";
|
||||
} catch (error) {
|
||||
if (error instanceof ImportLeaseLostError) throw error;
|
||||
await requireLease();
|
||||
|
||||
Reference in new issue
Block a user