move account filter to backend & optimize totalCount logic

This commit is contained in:
x032205
2025-11-14 21:26:10 -05:00
parent a37d27ece3
commit 19610f4fd6
6 changed files with 71 additions and 43 deletions
@@ -36,7 +36,16 @@ export const registerPamAccountRouter = async (server: FastifyZodProvider) => {
limit: z.coerce.number().min(1).max(100).default(100),
orderBy: z.nativeEnum(PamAccountOrderBy).default(PamAccountOrderBy.Name),
orderDirection: z.nativeEnum(OrderByDirection).default(OrderByDirection.ASC),
search: z.string().trim().optional()
search: z.string().trim().optional(),
filterResourceIds: z
.string()
.transform((val) =>
val
.split(",")
.map((s) => s.trim())
.filter(Boolean)
)
.optional()
}),
response: {
200: z.object({
@@ -50,7 +59,8 @@ export const registerPamAccountRouter = async (server: FastifyZodProvider) => {
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { projectId, accountPath, accountView, limit, offset, search, orderBy, orderDirection } = req.query;
const { projectId, accountPath, accountView, limit, offset, search, orderBy, orderDirection, filterResourceIds } =
req.query;
const { accounts, folders, totalCount, folderId, folderPaths } = await server.services.pamAccount.list({
actorId: req.permission.id,
@@ -64,7 +74,8 @@ export const registerPamAccountRouter = async (server: FastifyZodProvider) => {
offset,
search,
orderBy,
orderDirection
orderDirection,
filterResourceIds
});
await server.services.auditLog.createAuditLog({
@@ -22,7 +22,8 @@ export const pamAccountDALFactory = (db: TDbClient) => {
limit,
offset = 0,
orderBy = PamAccountOrderBy.Name,
orderDirection = OrderByDirection.ASC
orderDirection = OrderByDirection.ASC,
filterResourceIds
}: {
projectId: string;
folderId?: string | null;
@@ -32,6 +33,7 @@ export const pamAccountDALFactory = (db: TDbClient) => {
offset?: number;
orderBy?: PamAccountOrderBy;
orderDirection?: OrderByDirection;
filterResourceIds?: string[];
},
tx?: Knex
) => {
@@ -61,6 +63,10 @@ export const pamAccountDALFactory = (db: TDbClient) => {
});
}
if (filterResourceIds && filterResourceIds.length) {
void query.whereIn(`${TableName.PamAccount}.resourceId`, filterResourceIds);
}
const countQuery = query.clone().count("*", { as: "count" }).first();
void query.select(selectAllTableCols(TableName.PamAccount)).select(
@@ -374,14 +374,6 @@ export const pamAccountServiceFactory = ({
});
totalFolderCount = totalCount;
}
const { totalCount: totalAccountCount } = await pamAccountDAL.findByProjectIdWithResourceDetails({
projectId,
folderId,
accountView,
search: params.search
});
const totalCount = totalFolderCount + totalAccountCount;
let folders: TPamFolders[] = [];
if (canReadFolders && accountView === PamAccountView.Nested && offset < totalFolderCount) {
@@ -402,10 +394,12 @@ export const pamAccountServiceFactory = ({
let accountsWithResourceDetails: Awaited<
ReturnType<typeof pamAccountDAL.findByProjectIdWithResourceDetails>
>["accounts"] = [];
let totalAccountCount = 0;
const accountsToFetch = limit - folders.length;
if (accountsToFetch > 0) {
const accountOffset = Math.max(0, offset - totalFolderCount);
const { accounts: accountsResp } = await pamAccountDAL.findByProjectIdWithResourceDetails({
const { accounts, totalCount } = await pamAccountDAL.findByProjectIdWithResourceDetails({
projectId,
folderId,
accountView,
@@ -413,11 +407,25 @@ export const pamAccountServiceFactory = ({
limit: accountsToFetch,
search: params.search,
orderBy: params.orderBy,
orderDirection: params.orderDirection
orderDirection: params.orderDirection,
filterResourceIds: params.filterResourceIds
});
accountsWithResourceDetails = accountsResp;
accountsWithResourceDetails = accounts;
totalAccountCount = totalCount;
} else {
// if no accounts are to be fetched for the current page, we still need the total count for pagination
const { totalCount } = await pamAccountDAL.findByProjectIdWithResourceDetails({
projectId,
folderId,
accountView,
search: params.search,
filterResourceIds: params.filterResourceIds
});
totalAccountCount = totalCount;
}
const totalCount = totalFolderCount + totalAccountCount;
const decryptedAndPermittedAccounts: Array<
TPamAccounts & {
resource: Pick<TPamResources, "id" | "name" | "resourceType"> & { rotationCredentialsConfigured: boolean };
@@ -30,4 +30,5 @@ export type TListAccountsDTO = {
orderDirection?: OrderByDirection;
limit?: number;
offset?: number;
filterResourceIds?: string[];
} & TProjectPermission;