98 lines
1.8 KiB
JavaScript
98 lines
1.8 KiB
JavaScript
const jobs = {};
|
|
const MAX_LOG_LINES = 120;
|
|
|
|
function listJobs() {
|
|
return Object.values(jobs)
|
|
.sort((a, b) => String(b.startedAt || "").localeCompare(String(a.startedAt || "")));
|
|
}
|
|
|
|
function getJob(jobId) {
|
|
return jobs[jobId] || null;
|
|
}
|
|
|
|
function canStartJob(shop) {
|
|
if (!shop) {
|
|
return false;
|
|
}
|
|
|
|
const existing = jobs[shop];
|
|
return !existing || existing.status === "done" || existing.status === "error";
|
|
}
|
|
|
|
function createJob(payload = {}) {
|
|
const id = String(payload.shop || "").trim();
|
|
if (!id) {
|
|
throw new Error("Shop is required to create a job.");
|
|
}
|
|
|
|
jobs[id] = {
|
|
id,
|
|
status: "queued",
|
|
step: "queued",
|
|
stepIndex: 0,
|
|
totalSteps: 6,
|
|
detail: null,
|
|
summary: null,
|
|
error: null,
|
|
logs: [],
|
|
liveStats: {},
|
|
payload,
|
|
startedAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
return jobs[id];
|
|
}
|
|
|
|
function updateJob(jobId, patch) {
|
|
const current = jobs[jobId];
|
|
if (!current) {
|
|
return null;
|
|
}
|
|
|
|
jobs[jobId] = {
|
|
...current,
|
|
...patch,
|
|
liveStats: {
|
|
...(current.liveStats || {}),
|
|
...(patch.liveStats || {}),
|
|
},
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
return jobs[jobId];
|
|
}
|
|
|
|
function appendJobLog(jobId, line, extraPatch = {}) {
|
|
const current = jobs[jobId];
|
|
if (!current) {
|
|
return null;
|
|
}
|
|
|
|
const nextLogs = [...(current.logs || []), {
|
|
at: new Date().toISOString(),
|
|
line,
|
|
}].slice(-MAX_LOG_LINES);
|
|
|
|
jobs[jobId] = {
|
|
...current,
|
|
...extraPatch,
|
|
liveStats: {
|
|
...(current.liveStats || {}),
|
|
...(extraPatch.liveStats || {}),
|
|
},
|
|
logs: nextLogs,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
return jobs[jobId];
|
|
}
|
|
|
|
module.exports = {
|
|
listJobs,
|
|
getJob,
|
|
canStartJob,
|
|
createJob,
|
|
updateJob,
|
|
appendJobLog,
|
|
};
|