feat(core-audit): PayloadAuditLog.eraseSubject (pseudonymize + delete via overrideAccess)
Replaces the Phase-2 stub with a real impl. Mode "delete" issues a bulk payload.delete with overrideAccess:true to bypass the append-only rule. Mode "pseudonymize" fetches up to 10_000 matching docs and patches each actorId to the token produced by pseudonymize(). Adds 3 eraseSubject unit tests to the existing payload-audit-log test file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { SanitizedConfig } from "payload";
|
||||
import type { AuditEntry } from "@repo/core-shared/audit";
|
||||
import type { IAuditLog } from "./audit-log.interface";
|
||||
import { pseudonymize } from "./pseudonymize";
|
||||
|
||||
type GetPayload = (args: { config: SanitizedConfig }) => Promise<{
|
||||
create: (args: { collection: string; data: Record<string, unknown> }) => Promise<unknown>;
|
||||
@@ -66,8 +67,37 @@ export class PayloadAuditLog implements IAuditLog {
|
||||
});
|
||||
}
|
||||
|
||||
async eraseSubject(_actorId: string, _mode: "pseudonymize" | "delete"): Promise<void> {
|
||||
// Implemented in Phase 3.
|
||||
throw new Error("PayloadAuditLog.eraseSubject not yet implemented (Phase 3)");
|
||||
async eraseSubject(actorId: string, mode: "pseudonymize" | "delete"): Promise<void> {
|
||||
const payload = await this.getPayload({ config: this.config });
|
||||
|
||||
if (mode === "delete") {
|
||||
await payload.delete({
|
||||
collection: "audit-logs",
|
||||
where: { actorId: { equals: actorId } },
|
||||
overrideAccess: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// mode === "pseudonymize"
|
||||
// Fetch all matching docs. Limit is 10_000 — a subject with more than
|
||||
// 10k audit entries will not have all entries pseudonymized in one call.
|
||||
// This is an accepted v1 limitation; callers may loop if needed.
|
||||
const { docs } = await payload.find({
|
||||
collection: "audit-logs",
|
||||
where: { actorId: { equals: actorId } },
|
||||
limit: 10_000,
|
||||
overrideAccess: true,
|
||||
});
|
||||
|
||||
const pseudonym = pseudonymize(actorId);
|
||||
for (const doc of docs) {
|
||||
await payload.update({
|
||||
collection: "audit-logs",
|
||||
id: doc.id,
|
||||
data: { actorId: pseudonym },
|
||||
overrideAccess: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user