feat(plan): listPlanUsers with role/permission filter
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import { describe, it, expect, beforeAll, afterAll, beforeEach } from "vitest";
|
||||
import prisma from "../config/database";
|
||||
import { resolveCell, resolveGrid } from "../services/plan.service";
|
||||
import {
|
||||
resolveCell,
|
||||
resolveGrid,
|
||||
listPlanUsers,
|
||||
} from "../services/plan.service";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test fixtures
|
||||
@@ -170,3 +174,16 @@ describe("plan.service.resolveGrid", () => {
|
||||
expect(cells[adminUserId]["2099-06-03"]?.note).toBe(`${N}A`);
|
||||
});
|
||||
});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// listPlanUsers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
describe("plan.service.listPlanUsers", () => {
|
||||
it("returns at least the admin user", async () => {
|
||||
const users = await listPlanUsers();
|
||||
const found = users.find((u) => u.id === adminUserId);
|
||||
expect(found).toBeDefined();
|
||||
expect(found?.has_attendance_record).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -195,3 +195,53 @@ export async function resolveGrid(
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface PlanUser {
|
||||
id: number;
|
||||
full_name: string;
|
||||
username: string;
|
||||
role_name: string | null;
|
||||
is_active: boolean;
|
||||
has_attendance_record: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return users that should appear as columns in the plan grid:
|
||||
* everyone with the `attendance.record` permission, ordered by
|
||||
* role/team name then full_name. Admins are included by default.
|
||||
*
|
||||
* The `users` model uses the relation field name `roles` (NOT `role`)
|
||||
* for the foreign key to `roles.id`. The roles-to-permissions join
|
||||
* table is `role_permissions`, which has a relation `permissions`.
|
||||
*/
|
||||
export async function listPlanUsers(): Promise<PlanUser[]> {
|
||||
const rows = await prisma.users.findMany({
|
||||
where: {
|
||||
is_active: true,
|
||||
roles: {
|
||||
role_permissions: {
|
||||
some: { permissions: { name: "attendance.record" } },
|
||||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
roles: {
|
||||
select: { name: true },
|
||||
},
|
||||
},
|
||||
orderBy: [
|
||||
{ roles: { name: "asc" } },
|
||||
{ last_name: "asc" },
|
||||
{ first_name: "asc" },
|
||||
],
|
||||
});
|
||||
|
||||
return rows.map((u) => ({
|
||||
id: u.id,
|
||||
full_name: `${u.first_name} ${u.last_name}`.trim(),
|
||||
username: u.username,
|
||||
role_name: u.roles?.name ?? null,
|
||||
is_active: u.is_active ?? true,
|
||||
has_attendance_record: true,
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user