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