feat(filelib): 操作日志模块——防篡改哈希链、组合查询与 CSV 导出

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 22:54:45 +08:00
parent c96ea60482
commit 26523d1b54
29 changed files with 2881 additions and 209 deletions
+17 -13
View File
@@ -158,15 +158,16 @@ describe("memberGroupService · 改名/改描述(决策6)", () => {
await expect(updateMemberGroup(svc(), ADMIN, g.id, { name: "X" })).rejects.toMatchObject({ statusCode: 404 });
});
it("改名写 group.update 审计", async () => {
it("改名写 group.update 审计(含前后值)", async () => {
const g = await createMemberGroup(svc(), ADMIN, { name: "G" });
await updateMemberGroup(svc(), ADMIN, g.id, { name: "G2" });
const actions = (await prisma.auditEntry.findMany({
const rows = await prisma.fileLibAuditLog.findMany({
where: { organizationId: DEFAULT_ORG_ID },
select: { action: true },
orderBy: { createdAt: "asc" },
})).map((e) => e.action);
expect(actions).toEqual(["group.create", "group.update"]);
orderBy: { seq: "asc" },
});
expect(rows.map((e) => e.action)).toEqual(["group.create", "group.update"]);
expect(rows[1]!.beforeValue).toMatchObject({ name: "G" });
expect(rows[1]!.afterValue).toMatchObject({ name: "G2" });
});
});
@@ -293,19 +294,22 @@ describe("memberGroupService · 搜索 breadcrumb", () => {
});
});
describe("memberGroupService · 审计(C3/决策4)", () => {
it("建组/加成员/删组写 AuditEntry(挂 silo org)", async () => {
describe("memberGroupService · 审计(ADR-0039/决策4)", () => {
it("建组/加成员/删组写 FileLibAuditLog(挂 silo org)", async () => {
const g = await createMemberGroup(svc(), ADMIN, { name: "G" });
await addMember(svc(), ADMIN, g.id, { userId: "u_alice" });
await removeMember(svc(), ADMIN, g.id, "u_alice");
await deleteMemberGroup(svc(), ADMIN, g.id);
const actions = (await prisma.auditEntry.findMany({
const rows = await prisma.fileLibAuditLog.findMany({
where: { organizationId: DEFAULT_ORG_ID },
select: { action: true },
orderBy: { createdAt: "asc" },
})).map((e) => e.action);
expect(actions).toEqual([
orderBy: { seq: "asc" },
});
expect(rows.map((e) => e.action)).toEqual([
"group.create", "group.member_add", "group.member_remove", "group.delete",
]);
// 组不在文件库树上,objectPath 用 group: 前缀 —— 与节点路径空间隔离,
// 因此组日志只对网站管理员可见(ADR-0039)。
expect(rows.every((e) => e.objectPath === `group:${g.id}`)).toBe(true);
expect(rows.every((e) => e.objectType === "GROUP")).toBe(true);
});
});