feat: harden tenant access and production operations

This commit is contained in:
xz
2026-08-24 22:02:22 +08:00
parent ffb27d845b
commit 9811469a64
18 changed files with 709 additions and 36 deletions
+4
View File
@@ -491,6 +491,10 @@ function assertSingleFrameResult(job, result) {
export async function executeGenerationJob(context, jobId, body = {}) {
const job = jobRow(context, jobId);
if (!hasPermission(context, "job:create") && !hasPermission(context, "queue:manage")) throw httpError(403, "permission_denied", "没有执行生成任务的权限");
// The local Worker and a manual run request can legitimately race. Once a
// job is complete, treating a second run request as an idempotent read keeps
// the operator action safe without executing the model twice.
if (job.status === "completed") return { job: jobPayload(job), jobs: listGenerationJobs(context), idempotent: true };
requireProjectWritable(context);
if (!["queued", "blocked", "failed", "cancelled"].includes(job.status)) throw httpError(409, "job_not_runnable", "当前任务状态不能执行", { status: job.status });
const unresolved = unresolvedDependencies(jobId);