gongxiangp2/lib/work-review-review-mode.ts
2026-08-13 12:23:23 +08:00

59 lines
2.1 KiB
TypeScript

export const WORK_REVIEW_REVIEW_ROLES = {
MANAGER: 'manager',
FINAL_REVIEWER: 'final_reviewer',
} as const
export type WorkReviewReviewRole = typeof WORK_REVIEW_REVIEW_ROLES[keyof typeof WORK_REVIEW_REVIEW_ROLES]
export type WorkReviewReviewMode = 'dual' | 'single_reviewer_test'
export const WORK_REVIEW_REMINDER_INTERVAL_MS = 60 * 60_000
function clean(value: unknown) {
const text = String(value ?? '').trim()
return text || null
}
function getSingleReviewerTestConfig() {
const projectId = clean(process.env.WORK_REVIEW_SINGLE_REVIEW_TEST_PROJECT_ID)
const managerEmployeeId = clean(process.env.WORK_REVIEW_SINGLE_REVIEW_TEST_MANAGER_EMPLOYEE_ID)
const expiresAt = clean(process.env.WORK_REVIEW_SINGLE_REVIEW_TEST_EXPIRES_AT)
if (!projectId || !managerEmployeeId || !expiresAt) return null
const expiresAtMs = Date.parse(expiresAt)
if (!Number.isFinite(expiresAtMs) || Date.now() >= expiresAtMs) return null
return { projectId, managerEmployeeId }
}
export function getWorkReviewReviewMode(project: {
id: string
managerEmployeeId: string
}): WorkReviewReviewMode {
const config = getSingleReviewerTestConfig()
return config
&& project.id === config.projectId
&& project.managerEmployeeId === config.managerEmployeeId
? 'single_reviewer_test'
: 'dual'
}
export function getRequiredWorkReviewRoles(project: {
id: string
managerEmployeeId: string
}): WorkReviewReviewRole[] {
return getWorkReviewReviewMode(project) === 'single_reviewer_test'
? [WORK_REVIEW_REVIEW_ROLES.MANAGER]
: [WORK_REVIEW_REVIEW_ROLES.MANAGER, WORK_REVIEW_REVIEW_ROLES.FINAL_REVIEWER]
}
export function getPendingWorkReviewRoles(
project: { id: string; managerEmployeeId: string },
completedRoles: Iterable<string>,
) {
const completed = new Set(completedRoles)
return getRequiredWorkReviewRoles(project).filter((role) => !completed.has(role))
}
export function getWorkReviewReminderSequence(submittedAt: Date, now: Date) {
const elapsedMs = now.getTime() - submittedAt.getTime()
if (elapsedMs < WORK_REVIEW_REMINDER_INTERVAL_MS) return null
return Math.floor(elapsedMs / WORK_REVIEW_REMINDER_INTERVAL_MS)
}