Files
Neon-Desk/lib/server/tasks.ts
2026-02-26 13:26:18 -05:00

60 lines
1.6 KiB
TypeScript

import { randomUUID } from 'node:crypto';
import { start } from 'workflow/api';
import type { Task, TaskStatus, TaskType } from '@/lib/types';
import { runTaskWorkflow } from '@/app/workflows/task-runner';
import {
countTasksByStatus,
createTaskRunRecord,
getTaskByIdForUser,
listRecentTasksForUser,
markTaskFailure,
setTaskWorkflowRunId
} from '@/lib/server/repos/tasks';
type EnqueueTaskInput = {
userId: string;
taskType: TaskType;
payload?: Record<string, unknown>;
priority?: number;
maxAttempts?: number;
};
export async function enqueueTask(input: EnqueueTaskInput) {
const task = await createTaskRunRecord({
id: randomUUID(),
user_id: input.userId,
task_type: input.taskType,
payload: input.payload ?? {},
priority: input.priority ?? 50,
max_attempts: input.maxAttempts ?? 3
});
try {
const run = await start(runTaskWorkflow, [task.id]);
await setTaskWorkflowRunId(task.id, run.runId);
return {
...task,
workflow_run_id: run.runId
} satisfies Task;
} catch (error) {
const reason = error instanceof Error
? error.message
: 'Failed to start workflow';
await markTaskFailure(task.id, reason);
throw error;
}
}
export async function getTaskById(taskId: string, userId: string) {
return await getTaskByIdForUser(taskId, userId);
}
export async function listRecentTasks(userId: string, limit = 20, statuses?: TaskStatus[]) {
return await listRecentTasksForUser(userId, limit, statuses);
}
export async function getTaskQueueSnapshot() {
return await countTasksByStatus();
}