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,
};