69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import { prisma } from '@/lib/prisma'
|
|
import { hasBrandCenterAccess } from '@/lib/brand-center-access-policy'
|
|
|
|
type BrandCenterAccessIdentity = {
|
|
role?: unknown
|
|
isSuperAdmin?: unknown
|
|
}
|
|
const EMPLOYEE_ACCESS_SELECT = {
|
|
departmentPath: true,
|
|
employmentState: true,
|
|
departmentMemberships: {
|
|
select: {
|
|
departmentPath: true,
|
|
sourceDeptId: true,
|
|
},
|
|
},
|
|
} as const
|
|
|
|
export async function resolveBrandCenterAccessForUser(
|
|
userId: string | null | undefined,
|
|
identity: BrandCenterAccessIdentity = {},
|
|
): Promise<boolean> {
|
|
if (hasBrandCenterAccess(identity)) return true
|
|
if (!userId) return false
|
|
|
|
const user = await prisma.user.findUnique({
|
|
where: { id: userId },
|
|
select: {
|
|
dingtalkUserId: true,
|
|
employeeBindings: {
|
|
where: { status: 'ACTIVE' },
|
|
take: 1,
|
|
select: {
|
|
employeeProfile: { select: EMPLOYEE_ACCESS_SELECT },
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
let employee = user?.employeeBindings[0]?.employeeProfile ?? null
|
|
if (!employee && user?.dingtalkUserId) {
|
|
employee = await prisma.performanceSurveyEmployeeProfile.findUnique({
|
|
where: { dingtalkUserId: user.dingtalkUserId },
|
|
select: EMPLOYEE_ACCESS_SELECT,
|
|
})
|
|
}
|
|
if (!employee) return false
|
|
|
|
const sourceDeptIds = employee.departmentMemberships
|
|
.map((membership) => Number(membership.sourceDeptId))
|
|
.filter((value) => Number.isInteger(value))
|
|
const organizationUnits = sourceDeptIds.length > 0
|
|
? await prisma.organizationUnit.findMany({
|
|
where: { sourceDeptId: { in: sourceDeptIds }, isActive: true },
|
|
select: { path: true },
|
|
})
|
|
: []
|
|
|
|
return hasBrandCenterAccess({
|
|
...identity,
|
|
employmentState: employee.employmentState,
|
|
departmentPaths: [
|
|
employee.departmentPath,
|
|
...employee.departmentMemberships.map((membership) => membership.departmentPath),
|
|
...organizationUnits.map((unit) => unit.path),
|
|
],
|
|
})
|
|
}
|