forked from EduCraft/curriculum-project-hub
feat(filelib): 操作日志模块——防篡改哈希链、组合查询与 CSV 导出
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user