feat(services): add bulk service move functionality across projects

- Implement service move feature for applications, compose, databases, and other services
- Add move dialog with project selection for bulk service transfer
- Create move mutation endpoints for each service type
- Enhance project management with cross-project service relocation
- Improve user experience with error handling and success notifications
This commit is contained in:
Mauricio Siu
2025-03-08 18:39:02 -06:00
parent ff8d922f2b
commit b34987530e
8 changed files with 509 additions and 3 deletions

View File

@@ -8,6 +8,7 @@ import {
apiSaveEnvironmentVariablesPostgres,
apiSaveExternalPortPostgres,
apiUpdatePostgres,
postgres as postgresTable,
} from "@/server/db/schema";
import { cancelJobs } from "@/server/utils/backup";
import {
@@ -30,6 +31,9 @@ import {
} from "@dokploy/server";
import { TRPCError } from "@trpc/server";
import { observable } from "@trpc/server/observable";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { db } from "@/server/db";
export const postgresRouter = createTRPCRouter({
create: protectedProcedure
@@ -352,4 +356,49 @@ export const postgresRouter = createTRPCRouter({
return true;
}),
move: protectedProcedure
.input(
z.object({
postgresId: z.string(),
targetProjectId: z.string(),
}),
)
.mutation(async ({ input, ctx }) => {
const postgres = await findPostgresById(input.postgresId);
if (
postgres.project.organizationId !== ctx.session.activeOrganizationId
) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You are not authorized to move this postgres",
});
}
const targetProject = await findProjectById(input.targetProjectId);
if (targetProject.organizationId !== ctx.session.activeOrganizationId) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "You are not authorized to move to this project",
});
}
// Update the postgres's projectId
const updatedPostgres = await db
.update(postgresTable)
.set({
projectId: input.targetProjectId,
})
.where(eq(postgresTable.postgresId, input.postgresId))
.returning()
.then((res) => res[0]);
if (!updatedPostgres) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Failed to move postgres",
});
}
return updatedPostgres;
}),
});