feat: implement deployment jobs API and enhance queue management

Added a new endpoint to fetch deployment jobs for a server, integrating with the Inngest API to retrieve job details. Updated the queue management system to support centralized job retrieval for cloud environments, improving the deployment monitoring experience. Enhanced the UI to include action buttons for job cancellation and improved error handling for job fetching.
This commit is contained in:
Mauricio Siu
2026-03-03 01:04:26 -06:00
parent 1014d4674c
commit 08c9113405
7 changed files with 472 additions and 26 deletions

View File

@@ -10,7 +10,9 @@ import {
findDeploymentById,
findMemberById,
findServerById,
IS_CLOUD,
removeDeployment,
resolveServicePath,
updateDeploymentStatus,
} from "@dokploy/server";
import { db } from "@dokploy/server/db";
@@ -23,8 +25,13 @@ import {
apiFindAllByServer,
apiFindAllByType,
deployments,
server,
} from "@/server/db/schema";
import { myQueue } from "@/server/queues/queueSetup";
import {
fetchDeployApiJobs,
type QueueJobRow,
} from "@/server/utils/deploy";
import { createTRPCRouter, protectedProcedure } from "../trpc";
export const deploymentRouter = createTRPCRouter({
@@ -83,26 +90,51 @@ export const deploymentRouter = createTRPCRouter({
return findAllDeploymentsCentralized(orgId, accessedServices);
}),
queueList: protectedProcedure.query(async () => {
const jobs = await myQueue.getJobs();
const rows = await Promise.all(
jobs.map(async (job) => {
const state = await job.getState();
console.log(job.data);
return {
id: job.id,
name: job.name ?? undefined,
data: job.data as Record<string, unknown>,
timestamp: job.timestamp,
processedOn: job.processedOn,
finishedOn: job.finishedOn,
failedReason: job.failedReason ?? undefined,
state,
};
}),
queueList: protectedProcedure.query(async ({ ctx }) => {
const orgId = ctx.session.activeOrganizationId;
let rows: QueueJobRow[];
if (IS_CLOUD) {
const servers = await db.query.server.findMany({
where: eq(server.organizationId, orgId),
columns: { serverId: true },
});
rows = [];
for (const { serverId } of servers) {
const serverRows = await fetchDeployApiJobs(serverId);
rows.push(...serverRows);
}
rows.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
} else {
const jobs = await myQueue.getJobs();
const jobRows = await Promise.all(
jobs.map(async (job) => {
const state = await job.getState();
return {
id: String(job.id),
name: job.name ?? undefined,
data: job.data as Record<string, unknown>,
timestamp: job.timestamp,
processedOn: job.processedOn,
finishedOn: job.finishedOn,
failedReason: job.failedReason ?? undefined,
state,
};
}),
);
jobRows.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
rows = jobRows;
}
return Promise.all(
rows.map(async (row) => ({
...row,
servicePath: await resolveServicePath(
orgId,
(row.data ?? {}) as Record<string, unknown>,
),
})),
);
rows.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
return rows;
}),
allByType: protectedProcedure
@@ -115,10 +147,8 @@ export const deploymentRouter = createTRPCRouter({
rollback: true,
},
});
return deploymentsList;
}),
killProcess: protectedProcedure
.input(
z.object({