review changes

This commit is contained in:
Piyush Gupta
2025-10-09 18:55:49 +05:30
parent 4576fdfdbb
commit a090a1745c
8 changed files with 87 additions and 184 deletions
+9 -42
View File
@@ -173,9 +173,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
id: true, id: true,
superAdmin: true superAdmin: true
}).array(), }).array(),
meta: z.object({ total: z.number()
total: z.number()
})
}) })
} }
}, },
@@ -185,21 +183,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
}); });
}, },
handler: async (req) => { handler: async (req) => {
const users = await server.services.superAdmin.getUsers({ const result = await server.services.superAdmin.getUsers({
...req.query ...req.query
}); });
const count = await server.services.superAdmin.countUsers({ return result;
searchTerm: req.query.searchTerm,
adminsOnly: req.query.adminsOnly
});
return {
users,
meta: {
total: count
}
};
} }
}); });
@@ -242,9 +230,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
}) })
.array() .array()
}).array(), }).array(),
meta: z.object({ total: z.number()
total: z.number()
})
}) })
} }
}, },
@@ -254,19 +240,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
}); });
}, },
handler: async (req) => { handler: async (req) => {
const organizations = await server.services.superAdmin.getOrganizations({ const result = await server.services.superAdmin.getOrganizations({
...req.query ...req.query
}); });
const count = await server.services.superAdmin.countOrganizations({
searchTerm: req.query.searchTerm
});
return { return result;
organizations,
meta: {
total: count
}
};
} }
}); });
@@ -358,9 +336,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
isInstanceAdmin: z.boolean() isInstanceAdmin: z.boolean()
}) })
.array(), .array(),
meta: z.object({ total: z.number()
total: z.number()
})
}) })
} }
}, },
@@ -370,20 +346,11 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
}); });
}, },
handler: async (req) => { handler: async (req) => {
const identities = await server.services.superAdmin.getIdentities({ const result = await server.services.superAdmin.getIdentities({
...req.query ...req.query
}); });
const count = await server.services.superAdmin.countIdentities({ return result;
searchTerm: req.query.searchTerm
});
return {
identities,
meta: {
total: count
}
};
} }
}); });
+13 -1
View File
@@ -50,11 +50,23 @@ export const identityDALFactory = (db: TDbClient) => {
}); });
} }
const countQuery = query.clone();
if (sortBy) { if (sortBy) {
query = query.orderBy(sortBy); query = query.orderBy(sortBy);
} }
return await query.limit(limit).offset(offset).select(selectAllTableCols(TableName.Identity)); const [identities, totalResult] = await Promise.all([
query.limit(limit).offset(offset).select(selectAllTableCols(TableName.Identity)),
countQuery.countDistinct(`${TableName.Identity}.id`, { as: "count" }).first()
]);
const total = Number(totalResult?.count || 0);
return {
identities,
total
};
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Get identities by filter" }); throw new DatabaseError({ error, name: "Get identities by filter" });
} }
+40 -51
View File
@@ -43,8 +43,6 @@ export const orgDALFactory = (db: TDbClient) => {
sortBy?: keyof TOrganizations; sortBy?: keyof TOrganizations;
}) => { }) => {
try { try {
const query = db.replicaNode()(TableName.Organization);
// Build the subquery for limited organization IDs // Build the subquery for limited organization IDs
const orgSubquery = db.replicaNode().select("id").from(TableName.Organization); const orgSubquery = db.replicaNode().select("id").from(TableName.Organization);
@@ -54,37 +52,45 @@ export const orgDALFactory = (db: TDbClient) => {
}); });
} }
const countQuery = orgSubquery.clone();
if (sortBy) { if (sortBy) {
void orgSubquery.orderBy(sortBy); void orgSubquery.orderBy(sortBy);
} }
void orgSubquery.limit(limit).offset(offset); void orgSubquery.limit(limit).offset(offset);
// Main query with joins, limited to the subquery results const buildBaseQuery = (orgIdSubquery: Knex.QueryBuilder) => {
const docs = await query return db
.whereIn(`${TableName.Organization}.id`, orgSubquery) .replicaNode()(TableName.Organization)
.leftJoin(TableName.Project, `${TableName.Organization}.id`, `${TableName.Project}.orgId`) .whereIn(`${TableName.Organization}.id`, orgIdSubquery)
.leftJoin(TableName.OrgMembership, `${TableName.Organization}.id`, `${TableName.OrgMembership}.orgId`) .leftJoin(TableName.Project, `${TableName.Organization}.id`, `${TableName.Project}.orgId`)
.leftJoin(TableName.Users, `${TableName.OrgMembership}.userId`, `${TableName.Users}.id`) .leftJoin(TableName.OrgMembership, `${TableName.Organization}.id`, `${TableName.OrgMembership}.orgId`)
.leftJoin(TableName.OrgRoles, `${TableName.OrgMembership}.roleId`, `${TableName.OrgRoles}.id`) .leftJoin(TableName.Users, `${TableName.OrgMembership}.userId`, `${TableName.Users}.id`)
.where((qb) => { .leftJoin(TableName.OrgRoles, `${TableName.OrgMembership}.roleId`, `${TableName.OrgRoles}.id`)
void qb.where(`${TableName.Users}.isGhost`, false).orWhereNull(`${TableName.Users}.id`); .where((qb) => {
}) void qb.where(`${TableName.Users}.isGhost`, false).orWhereNull(`${TableName.Users}.id`);
.select(selectAllTableCols(TableName.Organization)) });
.select(db.ref("name").withSchema(TableName.Project).as("projectName")) };
.select(db.ref("id").withSchema(TableName.Project).as("projectId"))
.select(db.ref("slug").withSchema(TableName.Project).as("projectSlug")) const [docs, totalResult] = await Promise.all([
.select(db.ref("createdAt").withSchema(TableName.Project).as("projectCreatedAt")) buildBaseQuery(orgSubquery)
.select(db.ref("email").withSchema(TableName.Users).as("userEmail")) .select(selectAllTableCols(TableName.Organization))
.select(db.ref("username").withSchema(TableName.Users).as("username")) .select(db.ref("name").withSchema(TableName.Project).as("projectName"))
.select(db.ref("firstName").withSchema(TableName.Users).as("firstName")) .select(db.ref("id").withSchema(TableName.Project).as("projectId"))
.select(db.ref("lastName").withSchema(TableName.Users).as("lastName")) .select(db.ref("slug").withSchema(TableName.Project).as("projectSlug"))
.select(db.ref("id").withSchema(TableName.Users).as("userId")) .select(db.ref("createdAt").withSchema(TableName.Project).as("projectCreatedAt"))
.select(db.ref("id").withSchema(TableName.OrgMembership).as("orgMembershipId")) .select(db.ref("email").withSchema(TableName.Users).as("userEmail"))
.select(db.ref("role").withSchema(TableName.OrgMembership).as("orgMembershipRole")) .select(db.ref("username").withSchema(TableName.Users).as("username"))
.select(db.ref("roleId").withSchema(TableName.OrgMembership).as("orgMembershipRoleId")) .select(db.ref("firstName").withSchema(TableName.Users).as("firstName"))
.select(db.ref("status").withSchema(TableName.OrgMembership).as("orgMembershipStatus")) .select(db.ref("lastName").withSchema(TableName.Users).as("lastName"))
.select(db.ref("name").withSchema(TableName.OrgRoles).as("orgMembershipRoleName")); .select(db.ref("id").withSchema(TableName.Users).as("userId"))
.select(db.ref("id").withSchema(TableName.OrgMembership).as("orgMembershipId"))
.select(db.ref("role").withSchema(TableName.OrgMembership).as("orgMembershipRole"))
.select(db.ref("roleId").withSchema(TableName.OrgMembership).as("orgMembershipRoleId"))
.select(db.ref("status").withSchema(TableName.OrgMembership).as("orgMembershipStatus"))
.select(db.ref("name").withSchema(TableName.OrgRoles).as("orgMembershipRoleName")),
buildBaseQuery(countQuery).countDistinct(`${TableName.Organization}.id`, { as: "count" }).first()
]);
const formattedDocs = sqlNestRelationships({ const formattedDocs = sqlNestRelationships({
data: docs, data: docs,
@@ -132,33 +138,17 @@ export const orgDALFactory = (db: TDbClient) => {
] ]
}); });
return formattedDocs; const total = Number(totalResult?.count || 0);
return {
organizations: formattedDocs,
total
};
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Find organizations by filter" }); throw new DatabaseError({ error, name: "Find organizations by filter" });
} }
}; };
const countOrganizationsByFilter = async ({ searchTerm }: { searchTerm: string }) => {
interface CountResult {
count: string;
}
try {
const count = await db
.replicaNode()(TableName.Organization)
.where((qb) => {
if (searchTerm) {
void qb.whereILike(`${TableName.Organization}.name`, `%${searchTerm}%`);
}
})
.count("*")
.first();
return parseInt((count as unknown as CountResult).count || "0", 10);
} catch (error) {
throw new DatabaseError({ error, name: "Count organizations by filter" });
}
};
const findOrgById = async (orgId: string) => { const findOrgById = async (orgId: string) => {
try { try {
const org = (await db const org = (await db
@@ -691,7 +681,6 @@ export const orgDALFactory = (db: TDbClient) => {
findOrgBySlug, findOrgBySlug,
findAllOrgsByUserId, findAllOrgsByUserId,
findOrganizationsByFilter, findOrganizationsByFilter,
countOrganizationsByFilter,
ghostUserExists, ghostUserExists,
findOrgMembersByUsername, findOrgMembersByUsername,
findOrgMembersByRole, findOrgMembersByRole,
@@ -55,9 +55,6 @@ import {
TAdminGetUsersDTO, TAdminGetUsersDTO,
TAdminIntegrationConfig, TAdminIntegrationConfig,
TAdminSignUpDTO, TAdminSignUpDTO,
TCountIdentitiesDTO,
TCountOrganizationsDTO,
TCountUsersDTO,
TCreateOrganizationDTO, TCreateOrganizationDTO,
TGetOrganizationsDTO, TGetOrganizationsDTO,
TResendOrgInviteDTO TResendOrgInviteDTO
@@ -671,15 +668,6 @@ export const superAdminServiceFactory = ({
}); });
}; };
const countUsers = async ({ searchTerm, adminsOnly }: TCountUsersDTO) => {
const count = await userDAL.countUsersByFilter({
searchTerm,
adminsOnly
});
return count;
};
const deleteUser = async (userId: string) => { const deleteUser = async (userId: string) => {
const superAdmins = await userDAL.find({ const superAdmins = await userDAL.find({
superAdmin: true superAdmin: true
@@ -753,20 +741,12 @@ export const superAdminServiceFactory = ({
}; };
const getOrganizations = async ({ offset, limit, searchTerm }: TGetOrganizationsDTO) => { const getOrganizations = async ({ offset, limit, searchTerm }: TGetOrganizationsDTO) => {
const organizations = await orgDAL.findOrganizationsByFilter({ return orgDAL.findOrganizationsByFilter({
offset, offset,
searchTerm, searchTerm,
sortBy: "name", sortBy: "name",
limit limit
}); });
return organizations;
};
const countOrganizations = async ({ searchTerm }: TCountOrganizationsDTO) => {
const count = await orgDAL.countOrganizationsByFilter({
searchTerm
});
return count;
}; };
const createOrganization = async ( const createOrganization = async (
@@ -1034,7 +1014,7 @@ export const superAdminServiceFactory = ({
}; };
const getIdentities = async ({ offset, limit, searchTerm }: TAdminGetIdentitiesDTO) => { const getIdentities = async ({ offset, limit, searchTerm }: TAdminGetIdentitiesDTO) => {
const identities = await identityDAL.getIdentitiesByFilter({ const result = await identityDAL.getIdentitiesByFilter({
limit, limit,
offset, offset,
searchTerm, searchTerm,
@@ -1042,17 +1022,13 @@ export const superAdminServiceFactory = ({
}); });
const serverCfg = await getServerCfg(); const serverCfg = await getServerCfg();
return identities.map((identity) => ({ return {
...identity, identities: result.identities.map((identity) => ({
isInstanceAdmin: Boolean(serverCfg?.adminIdentityIds?.includes(identity.id)) ...identity,
})); isInstanceAdmin: Boolean(serverCfg?.adminIdentityIds?.includes(identity.id))
}; })),
total: result.total
const countIdentities = async ({ searchTerm }: TCountIdentitiesDTO) => { };
const count = await identityDAL.countIdentitiesByFilter({
searchTerm
});
return count;
}; };
const grantServerAdminAccessToUser = async (userId: string) => { const grantServerAdminAccessToUser = async (userId: string) => {
@@ -1161,10 +1137,8 @@ export const superAdminServiceFactory = ({
adminSignUp, adminSignUp,
bootstrapInstance, bootstrapInstance,
getUsers, getUsers,
countUsers,
deleteUser, deleteUser,
getIdentities, getIdentities,
countIdentities,
getAdminIntegrationsConfig, getAdminIntegrationsConfig,
updateRootEncryptionStrategy, updateRootEncryptionStrategy,
getConfiguredEncryptionStrategies, getConfiguredEncryptionStrategies,
@@ -1174,7 +1148,6 @@ export const superAdminServiceFactory = ({
invalidateCache, invalidateCache,
checkIfInvalidatingCache, checkIfInvalidatingCache,
getOrganizations, getOrganizations,
countOrganizations,
deleteOrganization, deleteOrganization,
deleteOrganizationMembership, deleteOrganizationMembership,
initializeAdminIntegrationConfigSync, initializeAdminIntegrationConfigSync,
@@ -34,19 +34,6 @@ export type TGetOrganizationsDTO = {
searchTerm: string; searchTerm: string;
}; };
export type TCountOrganizationsDTO = {
searchTerm: string;
};
export type TCountIdentitiesDTO = {
searchTerm: string;
};
export type TCountUsersDTO = {
searchTerm: string;
adminsOnly: boolean;
};
export type TCreateOrganizationDTO = { export type TCreateOrganizationDTO = {
name: string; name: string;
inviteAdminEmails: string[]; inviteAdminEmails: string[];
+10 -31
View File
@@ -60,45 +60,25 @@ export const userDALFactory = (db: TDbClient) => {
query = query.where("superAdmin", true); query = query.where("superAdmin", true);
} }
const countQuery = query.clone();
if (sortBy) { if (sortBy) {
query = query.orderBy(sortBy); query = query.orderBy(sortBy);
} }
return await query.limit(limit).offset(offset).select(selectAllTableCols(TableName.Users)); const [users, totalResult] = await Promise.all([
query.limit(limit).offset(offset).select(selectAllTableCols(TableName.Users)),
countQuery.count("*", { as: "count" }).first()
]);
const total = Number(totalResult?.count || 0);
return { users, total };
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "Get users by filter" }); throw new DatabaseError({ error, name: "Get users by filter" });
} }
}; };
const countUsersByFilter = async ({ searchTerm, adminsOnly }: { searchTerm: string; adminsOnly: boolean }) => {
interface CountResult {
count: string;
}
try {
const count = await db
.replicaNode()(TableName.Users)
.where("isGhost", "=", false)
.where((qb) => {
if (searchTerm) {
void qb
.whereILike("email", `%${searchTerm}%`)
.orWhereILike("firstName", `%${searchTerm}%`)
.orWhereILike("lastName", `%${searchTerm}%`)
.orWhereRaw('lower("username") like ?', `%${searchTerm}%`);
}
if (adminsOnly) {
void qb.where("superAdmin", true);
}
})
.count("*")
.first();
return parseInt((count as unknown as CountResult).count || "0", 10);
} catch (error) {
throw new DatabaseError({ error, name: "Count Users by filter" });
}
};
// USER ENCRYPTION FUNCTIONS // USER ENCRYPTION FUNCTIONS
// ------------------------- // -------------------------
const findUserEncKeyByUsername = async ({ username }: { username: string }) => { const findUserEncKeyByUsername = async ({ username }: { username: string }) => {
@@ -272,7 +252,6 @@ export const userDALFactory = (db: TDbClient) => {
findOneUserAction, findOneUserAction,
createUserAction, createUserAction,
getUsersByFilter, getUsersByFilter,
countUsersByFilter,
findAllMyAccounts, findAllMyAccounts,
findUserByEmail findUserByEmail
}; };
+3 -3
View File
@@ -54,7 +54,7 @@ export const useAdminGetOrganizations = (filters: AdminGetOrganizationsFilters)
} }
); );
return { organizations: data.organizations, totalCount: data.meta.total }; return { organizations: data.organizations, totalCount: data.total };
}, },
placeholderData: (previousData) => previousData placeholderData: (previousData) => previousData
}); });
@@ -93,7 +93,7 @@ export const useAdminGetUsers = (filters: AdminGetUsersFilters) => {
} }
); );
return { users: data.users, totalCount: data.meta.total }; return { users: data.users, totalCount: data.total };
}, },
placeholderData: (previousData) => previousData placeholderData: (previousData) => previousData
}); });
@@ -112,7 +112,7 @@ export const useAdminGetIdentities = (filters: AdminGetIdentitiesFilters) => {
} }
); );
return { identities: data.identities, totalCount: data.meta.total }; return { identities: data.identities, totalCount: data.total };
}, },
placeholderData: (previousData) => previousData placeholderData: (previousData) => previousData
}); });
+3 -7
View File
@@ -35,23 +35,19 @@ export type OrganizationWithProjects = Organization & {
}[]; }[];
}; };
type PaginatedDataMeta = {
total: number;
};
export type TGetOrganizationsResponse = { export type TGetOrganizationsResponse = {
organizations: OrganizationWithProjects[]; organizations: OrganizationWithProjects[];
meta: PaginatedDataMeta; total: number;
}; };
export type TGetIdentitiesResponse = { export type TGetIdentitiesResponse = {
identities: Identity[]; identities: Identity[];
meta: PaginatedDataMeta; total: number;
}; };
export type TGetUsersResponse = { export type TGetUsersResponse = {
users: User[]; users: User[];
meta: PaginatedDataMeta; total: number;
}; };
export type TServerConfig = { export type TServerConfig = {