mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-07-13 01:45:23 +02:00
feat: add search functionality across multiple routers with member access control
Implemented a search feature in application, compose, environment, mariadb, mongo, mysql, postgres, project, and redis routers. Each search allows filtering by various parameters and respects user permissions based on their role. The search queries utilize optimized conditions for efficient data retrieval.
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
deployPostgres,
|
||||
findBackupsByDbId,
|
||||
findEnvironmentById,
|
||||
findMemberById,
|
||||
findPostgresById,
|
||||
findProjectById,
|
||||
getMountPath,
|
||||
@@ -22,7 +23,7 @@ import {
|
||||
} from "@dokploy/server";
|
||||
import { db } from "@dokploy/server/db";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { and, desc, eq, ilike, or, sql } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import { createTRPCRouter, protectedProcedure } from "@/server/api/trpc";
|
||||
import {
|
||||
@@ -37,6 +38,7 @@ import {
|
||||
apiUpdatePostgres,
|
||||
postgres as postgresTable,
|
||||
} from "@/server/db/schema";
|
||||
import { environments, projects } from "@/server/db/schema";
|
||||
import { cancelJobs } from "@/server/utils/backup";
|
||||
|
||||
export const postgresRouter = createTRPCRouter({
|
||||
@@ -483,4 +485,101 @@ export const postgresRouter = createTRPCRouter({
|
||||
|
||||
return true;
|
||||
}),
|
||||
search: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
q: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
appName: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
projectId: z.string().optional(),
|
||||
environmentId: z.string().optional(),
|
||||
limit: z.number().min(1).max(100).default(20),
|
||||
offset: z.number().min(0).default(0),
|
||||
}),
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
const baseConditions = [
|
||||
eq(projects.organizationId, ctx.session.activeOrganizationId),
|
||||
];
|
||||
if (input.projectId) {
|
||||
baseConditions.push(eq(environments.projectId, input.projectId));
|
||||
}
|
||||
if (input.environmentId) {
|
||||
baseConditions.push(
|
||||
eq(postgresTable.environmentId, input.environmentId),
|
||||
);
|
||||
}
|
||||
if (input.q?.trim()) {
|
||||
const term = `%${input.q.trim()}%`;
|
||||
baseConditions.push(
|
||||
or(
|
||||
ilike(postgresTable.name, term),
|
||||
ilike(postgresTable.appName, term),
|
||||
ilike(postgresTable.description ?? "", term),
|
||||
)!,
|
||||
);
|
||||
}
|
||||
if (input.name?.trim()) {
|
||||
baseConditions.push(
|
||||
ilike(postgresTable.name, `%${input.name.trim()}%`),
|
||||
);
|
||||
}
|
||||
if (input.appName?.trim()) {
|
||||
baseConditions.push(
|
||||
ilike(postgresTable.appName, `%${input.appName.trim()}%`),
|
||||
);
|
||||
}
|
||||
if (input.description?.trim()) {
|
||||
baseConditions.push(
|
||||
ilike(postgresTable.description ?? "", `%${input.description.trim()}%`),
|
||||
);
|
||||
}
|
||||
if (ctx.user.role === "member") {
|
||||
const { accessedServices } = await findMemberById(
|
||||
ctx.user.id,
|
||||
ctx.session.activeOrganizationId,
|
||||
);
|
||||
if (accessedServices.length === 0) return { items: [], total: 0 };
|
||||
baseConditions.push(
|
||||
sql`${postgresTable.postgresId} IN (${sql.join(
|
||||
accessedServices.map((id) => sql`${id}`),
|
||||
sql`, `,
|
||||
)})`,
|
||||
);
|
||||
}
|
||||
const where = and(...baseConditions);
|
||||
const [items, countResult] = await Promise.all([
|
||||
db
|
||||
.select({
|
||||
postgresId: postgresTable.postgresId,
|
||||
name: postgresTable.name,
|
||||
appName: postgresTable.appName,
|
||||
description: postgresTable.description,
|
||||
environmentId: postgresTable.environmentId,
|
||||
applicationStatus: postgresTable.applicationStatus,
|
||||
createdAt: postgresTable.createdAt,
|
||||
})
|
||||
.from(postgresTable)
|
||||
.innerJoin(
|
||||
environments,
|
||||
eq(postgresTable.environmentId, environments.environmentId),
|
||||
)
|
||||
.innerJoin(projects, eq(environments.projectId, projects.projectId))
|
||||
.where(where)
|
||||
.orderBy(desc(postgresTable.createdAt))
|
||||
.limit(input.limit)
|
||||
.offset(input.offset),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(postgresTable)
|
||||
.innerJoin(
|
||||
environments,
|
||||
eq(postgresTable.environmentId, environments.environmentId),
|
||||
)
|
||||
.innerJoin(projects, eq(environments.projectId, projects.projectId))
|
||||
.where(where),
|
||||
]);
|
||||
return { items, total: countResult[0]?.count ?? 0 };
|
||||
}),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user