feat(server): 完成 P0+P1 后端能力(工作流、RBAC、付款归档)

P0 MVP:

- 认证:login/refresh/logout/forgot/reset + tokenVersion

- RBAC:角色到权限映射 + requirePermission

- 发票池:upload/bind/signed-url + 判重(VALID_003/VALID_005)

- 报销:create/view/submit + 单号生成

- 工作流:approve + department_manager 解析

P1 扩展:

- 动作:reject/return/withdraw(含 comment)

- transfer:任务转审 + 链路上限 3

- pay:approved -> paid + 发票归档 used_complete

- 动态审批链:approval_rules 驱动

回归脚本:

- smoke-test.sh / regression-dedup.sh / regression-workflow-actions.sh
这个提交包含在:
2026-02-07 16:43:31 +08:00
当前提交 f527633716
共修改 44 个文件,包含 11100 行新增和 0 行删除
+42
查看文件
@@ -0,0 +1,42 @@
const { sendData } = require("../utils/reply");
async function meRoutes(fastify) {
fastify.get(
"/me",
{
preHandler: fastify.authenticate,
},
async (request, reply) => {
const employee = await fastify.prisma.employee.findUnique({
where: { id: request.employee.id },
select: {
id: true,
employee_no: true,
name: true,
phone: true,
email: true,
department_id: true,
direct_manager_id: true,
status: true,
roles: { select: { role_code: true } },
},
});
const roleCodes = (employee?.roles ?? []).map((r) => r.role_code);
return sendData(reply, request, {
id: employee?.id ?? request.employee.id,
employeeNo: employee?.employee_no ?? "",
name: employee?.name ?? "",
phone: employee?.phone ?? "",
email: employee?.email ?? "",
departmentId: employee?.department_id ?? "",
directManagerId: employee?.direct_manager_id ?? null,
status: employee?.status ?? "active",
roleCodes,
});
},
);
}
module.exports = meRoutes;