Pull Request branch dev-clone to main #1
|
|
@ -26,23 +26,24 @@ export const userFormSchema = z.object({
|
|||
address: z.string().min(1),
|
||||
phoneNumber: z.string().min(1).max(13),
|
||||
isEnabled: z.string().default("false"),
|
||||
roles: z
|
||||
.string()
|
||||
.refine(
|
||||
(data) => {
|
||||
console.log(data);
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
return Array.isArray(parsed);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
message: "Roles must be an array",
|
||||
}
|
||||
)
|
||||
.optional(),
|
||||
// roles: z
|
||||
// .string()
|
||||
// .refine(
|
||||
// (data) => {
|
||||
// console.log(data);
|
||||
// try {
|
||||
// const parsed = JSON.parse(data);
|
||||
// return Array.isArray(parsed);
|
||||
// } catch {
|
||||
// return false;
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// message: "Roles must be an array",
|
||||
// }
|
||||
// )
|
||||
// .optional(),
|
||||
roles: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
export const userUpdateSchema = userFormSchema.extend({
|
||||
|
|
@ -58,6 +59,7 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
* - includeTrashed: boolean (default: false)\
|
||||
* - withMetadata: boolean
|
||||
*/
|
||||
|
||||
.get(
|
||||
"/",
|
||||
checkPermission("users.readAll"),
|
||||
|
|
@ -73,17 +75,18 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
.optional()
|
||||
.transform((v) => v?.toLowerCase() === "true"),
|
||||
page: z.coerce.number().int().min(0).default(0),
|
||||
limit: z.coerce.number().int().min(1).max(1000).default(1),
|
||||
limit: z.coerce.number().int().min(1).max(1000).default(100),
|
||||
q: z.string().default(""),
|
||||
})
|
||||
),
|
||||
async (c) => {
|
||||
const { includeTrashed, page, limit, q } = c.req.valid("query");
|
||||
|
||||
|
||||
// Total count for pagination
|
||||
const totalCountQuery = includeTrashed
|
||||
? sql<number>`(SELECT count(*) FROM ${users})`
|
||||
: sql<number>`(SELECT count(*) FROM ${users} WHERE ${users.deletedAt} IS NULL)`;
|
||||
|
||||
|
||||
const result = await db
|
||||
.select({
|
||||
id: users.id,
|
||||
|
|
@ -95,7 +98,10 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
updatedAt: users.updatedAt,
|
||||
...(includeTrashed ? { deletedAt: users.deletedAt } : {}),
|
||||
company: respondents.companyName,
|
||||
roles: rolesSchema.name,
|
||||
role: {
|
||||
name: rolesSchema.name,
|
||||
id: rolesSchema.id,
|
||||
},
|
||||
fullCount: totalCountQuery,
|
||||
})
|
||||
.from(users)
|
||||
|
|
@ -118,8 +124,47 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
.offset(page * limit)
|
||||
.limit(limit);
|
||||
|
||||
// Group roles for each user to prevent duplication
|
||||
const userMap = new Map<string, {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string | null;
|
||||
username: string;
|
||||
isEnabled: boolean;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
deletedAt?: Date;
|
||||
company: string | null;
|
||||
roles: { id: string; name: string }[];
|
||||
}>();
|
||||
|
||||
result.forEach((item) => {
|
||||
if (!userMap.has(item.id)) {
|
||||
userMap.set(item.id, {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
email: item.email ?? null,
|
||||
username: item.username,
|
||||
isEnabled: item.isEnabled ?? false,
|
||||
createdAt: item.createdAt ?? new Date(),
|
||||
updatedAt: item.updatedAt ?? new Date(),
|
||||
deletedAt: item.deletedAt ?? undefined,
|
||||
company: item.company,
|
||||
roles: item.role ? [{ id: item.role.id, name: item.role.name }] : [],
|
||||
});
|
||||
} else {
|
||||
const existingUser = userMap.get(item.id);
|
||||
if (item.role) {
|
||||
existingUser?.roles.push({ id: item.role.id, name: item.role.name });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Return user data without duplication and roles in array form
|
||||
const groupedData = Array.from(userMap.values());
|
||||
|
||||
return c.json({
|
||||
data: result.map((d) => ({ ...d, fullCount: undefined })),
|
||||
data: groupedData.map((d) => ({ ...d, fullCount: undefined })),
|
||||
_metadata: {
|
||||
currentPage: page,
|
||||
totalPages: Math.ceil(
|
||||
|
|
@ -130,7 +175,8 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
},
|
||||
});
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
//get user by id
|
||||
.get(
|
||||
"/:id",
|
||||
|
|
@ -277,31 +323,17 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
message: "Error creating respondent: " + err.message,
|
||||
});
|
||||
});
|
||||
|
||||
// Automatically assign "user" role to the new user
|
||||
const [role] = await trx
|
||||
.select()
|
||||
.from(rolesSchema)
|
||||
.where(eq(rolesSchema.code, "user"))
|
||||
.limit(1);
|
||||
|
||||
if (!role) throw notFound();
|
||||
|
||||
await trx.insert(rolesToUsers).values({
|
||||
userId: newUser.id,
|
||||
roleId: role.id,
|
||||
});
|
||||
|
||||
// Add other roles if provided
|
||||
if (userData.roles) {
|
||||
const roles = JSON.parse(userData.roles) as string[];
|
||||
const roles = userData.roles;
|
||||
|
||||
for (let roleCode of roles) {
|
||||
for (let roleId of roles) {
|
||||
const role = (
|
||||
await trx
|
||||
.select()
|
||||
.from(rolesSchema)
|
||||
.where(eq(rolesSchema.code, roleCode))
|
||||
.where(eq(rolesSchema.id, roleId))
|
||||
.limit(1)
|
||||
)[0];
|
||||
|
||||
|
|
@ -312,7 +344,7 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
});
|
||||
} else {
|
||||
throw new HTTPException(404, {
|
||||
message: `Role ${roleCode} does not exists`,
|
||||
message: `Role ${roleId} does not exists`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -400,18 +432,18 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
|
||||
// Update roles if provided
|
||||
if (userData.roles) {
|
||||
const roles = JSON.parse(userData.roles) as string[];
|
||||
const roles = userData.roles;
|
||||
|
||||
// Remove existing roles for the user
|
||||
await trx.delete(rolesToUsers).where(eq(rolesToUsers.userId, userId));
|
||||
|
||||
// Assign new roles
|
||||
for (let roleCode of roles) {
|
||||
for (let roleId of roles) {
|
||||
const role = (
|
||||
await trx
|
||||
.select()
|
||||
.from(rolesSchema)
|
||||
.where(eq(rolesSchema.code, roleCode))
|
||||
.where(eq(rolesSchema.id, roleId))
|
||||
.limit(1)
|
||||
)[0];
|
||||
|
||||
|
|
@ -422,7 +454,7 @@ const usersRoute = new Hono<HonoEnv>()
|
|||
});
|
||||
} else {
|
||||
throw new HTTPException(404, {
|
||||
message: `Role ${roleCode} does not exist`,
|
||||
message: `Role ${roleId} does not exist`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user