55 lines
2.1 KiB
TypeScript
55 lines
2.1 KiB
TypeScript
// Resume a cancelled/failed background job — POST /api/generate-classroom/[jobId]/resume
|
|
//
|
|
// Re-runs the job from its persisted input (the generation restarts from the
|
|
// beginning; server-side generation is atomic, so there is no partial state to
|
|
// continue from). Returns 409 when the job is not resumable.
|
|
|
|
import { type NextRequest } from 'next/server';
|
|
import { apiError, apiSuccess } from '@/lib/server/api-response';
|
|
import {
|
|
isValidClassroomJobId,
|
|
readClassroomGenerationJob,
|
|
} from '@/lib/server/classroom-job-store';
|
|
import { resumeClassroomGenerationJob } from '@/lib/server/classroom-job-runner';
|
|
import { buildRequestOrigin } from '@/lib/server/classroom-storage';
|
|
import { createLogger } from '@/lib/logger';
|
|
import {
|
|
authorizeClassroomJobRequest,
|
|
classroomJobAccessError,
|
|
} from '@/lib/server/authz/classroom-job-access';
|
|
|
|
const log = createLogger('ClassroomJobResume API');
|
|
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
export async function POST(req: NextRequest, context: { params: Promise<{ jobId: string }> }) {
|
|
try {
|
|
const { jobId } = await context.params;
|
|
if (!isValidClassroomJobId(jobId)) {
|
|
return apiError('INVALID_REQUEST', 400, 'Invalid classroom generation job id');
|
|
}
|
|
const job = await readClassroomGenerationJob(jobId);
|
|
if (!job) {
|
|
return apiError('INVALID_REQUEST', 404, 'Classroom generation job not found');
|
|
}
|
|
const access = await authorizeClassroomJobRequest(req, job, 'resume');
|
|
if (!access.allowed) return classroomJobAccessError(access);
|
|
if (job.status === 'running' || job.status === 'queued') {
|
|
return apiError('INVALID_REQUEST', 409, 'Job is already active');
|
|
}
|
|
const resumed = await resumeClassroomGenerationJob(jobId, buildRequestOrigin(req));
|
|
if (!resumed) {
|
|
return apiError('INVALID_REQUEST', 409, 'Job cannot be resumed (no persisted input)');
|
|
}
|
|
return apiSuccess({ jobId, status: 'queued' });
|
|
} catch (error) {
|
|
log.error('Classroom job resume failed:', error);
|
|
return apiError(
|
|
'INTERNAL_ERROR',
|
|
500,
|
|
'Failed to resume classroom generation job',
|
|
error instanceof Error ? error.message : String(error),
|
|
);
|
|
}
|
|
}
|