import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { type NextRequest, NextResponse } from 'next/server' import { getJobStatusContract } from '@/lib/api/contracts/common' import { parseRequest } from '@/lib/api/server' import { checkHybridAuth } from '@/lib/auth/hybrid' import { getJobQueue } from '@/lib/core/async-jobs' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { createErrorResponse } from '@/app/api/workflows/utils' const logger = createLogger('TaskStatusAPI') export const GET = withRouteHandler( async (request: NextRequest, context: { params: Promise<{ jobId: string }> }) => { const parsed = await parseRequest(getJobStatusContract, request, context) if (!parsed.success) return parsed.response const { jobId: taskId } = parsed.data.params const requestId = generateRequestId() try { const authResult = await checkHybridAuth(request, { requireWorkflowId: false }) if (!authResult.success || !authResult.userId) { logger.warn(`[${requestId}] Unauthorized task status request`) return createErrorResponse(authResult.error || 'Authentication required', 401) } const authenticatedUserId = authResult.userId const jobQueue = await getJobQueue() const job = await jobQueue.getJob(taskId) if (!job) { return createErrorResponse('Task not found', 404) } const metadataToCheck = job.metadata if (metadataToCheck?.workflowId) { const { authorizeWorkflowByWorkspacePermission } = await import( '@sim/platform-authz/workflow' ) const accessCheck = await authorizeWorkflowByWorkspacePermission({ userId: authenticatedUserId, workflowId: metadataToCheck.workflowId as string, action: 'read', }) if (!accessCheck.allowed) { logger.warn(`[${requestId}] Access denied to workflow ${metadataToCheck.workflowId}`) return createErrorResponse('Access denied', 403) } if (authResult.apiKeyType === 'workspace' && authResult.workspaceId) { const { getWorkflowById } = await import('@/lib/workflows/utils') const workflow = await getWorkflowById(metadataToCheck.workflowId as string) if (!workflow?.workspaceId || workflow.workspaceId !== authResult.workspaceId) { return createErrorResponse('API key is not authorized for this workspace', 403) } } } else if (metadataToCheck?.userId && metadataToCheck.userId !== authenticatedUserId) { logger.warn(`[${requestId}] Access denied to user ${metadataToCheck.userId}`) return createErrorResponse('Access denied', 403) } else if (!metadataToCheck?.userId && !metadataToCheck?.workflowId) { logger.warn(`[${requestId}] Access denied to job ${taskId}`) return createErrorResponse('Access denied', 403) } const response: Record = { success: true, taskId, status: job.status, metadata: job.metadata, } if (job.output !== undefined) response.output = job.output if (job.error !== undefined) response.error = job.error return NextResponse.json(response) } catch (error: unknown) { const errorMessage = toError(error).message logger.error(`[${requestId}] Error fetching task status:`, error) if (errorMessage?.includes('not found')) { return createErrorResponse('Task not found', 404) } return createErrorResponse('Failed to fetch task status', 500) } } )