Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.auction-rise.com/llms.txt

Use this file to discover all available pages before exploring further.

Background Jobs

The template provides a lightweight job tracking layer backed by a job_runs table. It handles status/progress persistence so you can integrate any job runner (Trigger.dev, Inngest, a custom API route, etc.) without vendor lock-in.

Job Status Lifecycle

pending → running → completed
                 ↘ failed
                 ↘ canceled
StatusMeaning
pendingJob has been queued but not started
runningJob runner has picked it up
completedFinished successfully
failedFinished with an error
canceledCanceled before completion

Creating a Job

Call enqueueJob() to create a tracking record and get back a job ID:
import { enqueueJob } from "@/lib/jobs/actions";

const jobId = await enqueueJob("generate-report", workspaceId, {
  reportType: "monthly",
  startDate: "2025-01-01",
});
// Then pass jobId to your job runner
The payload field accepts any JSON-serializable object.

Updating Job Status

From your job runner (API route, webhook handler, etc.), update the job as it progresses:
import { updateJobStatus } from "@/lib/jobs/actions";

// Mark as started
await updateJobStatus(jobId, { status: "running", progress: 0 });

// Update progress (0-100)
await updateJobStatus(jobId, { progress: 50 });

// Mark complete with result
await updateJobStatus(jobId, {
  status: "completed",
  progress: 100,
  result: { rowsProcessed: 1234 },
});

// Mark failed
await updateJobStatus(jobId, {
  status: "failed",
  error: "Connection timed out after 30s",
});
started_at is set automatically when status transitions to running. completed_at is set on completed or failed.

Polling Job Status

Poll from a client component or API route:
import { getJobStatus } from "@/lib/jobs/actions";

const job = await getJobStatus(jobId);
// job.status, job.progress, job.result, job.error

Canceling a Job

import { cancelJob } from "@/lib/jobs/actions";

await cancelJob(jobId);
Canceling sets the database status to canceled but does not stop a running job runner process. Your job runner should poll for canceled status and bail out gracefully.

JobRun Type

type JobRun = {
  id: string;
  type: string;
  status: "pending" | "running" | "completed" | "failed" | "canceled";
  payload: Record<string, unknown> | null;
  result: Record<string, unknown> | null;
  error: string | null;
  progress: number; // 0-100
  workspace_id: string | null;
  created_by: string;
  started_at: string | null;
  completed_at: string | null;
  created_at: string;
};

Long-running API Routes

For long-running operations in Next.js, set maxDuration in the route file to avoid the default 10s timeout:
// app/api/jobs/[jobId]/run/route.ts
export const maxDuration = 300; // 5 minutes

export async function POST(request: Request) {
  // ... run your job
}