diff --git a/packages/core-audit/src/hooks/audit-erasure-hook.ts b/packages/core-audit/src/hooks/audit-erasure-hook.ts index 8bb6025..ee9f85c 100644 --- a/packages/core-audit/src/hooks/audit-erasure-hook.ts +++ b/packages/core-audit/src/hooks/audit-erasure-hook.ts @@ -58,8 +58,10 @@ export function createReqScopedAuditErasureHook( return async ({ doc, req }) => { if (typeof doc.id !== "string" && typeof doc.id !== "number") return; const payload = req.payload; + // `slug as string`: apps with generated CollectionSlug types narrow slug + // to their registered union, which need not include "audit-logs". const hasAuditCollection = payload.config.collections?.some( - (c) => c.slug === "audit-logs", + (c) => (c.slug as string) === "audit-logs", ); if (!hasAuditCollection) return; const auditLog = new PayloadAuditLog( diff --git a/packages/core-shared/src/payload/retention-purge/retention-purge.job.ts b/packages/core-shared/src/payload/retention-purge/retention-purge.job.ts index ec57dab..b84a193 100644 --- a/packages/core-shared/src/payload/retention-purge/retention-purge.job.ts +++ b/packages/core-shared/src/payload/retention-purge/retention-purge.job.ts @@ -108,6 +108,9 @@ export function buildPurgeHandler( ); } + // Re-bind after the guard: narrowing does not flow into hoisted closures. + const targetCollection = collection; + const taskSlug = `retention-purge--${collectionSlug}`; async function applyAction( @@ -120,7 +123,7 @@ export function buildPurgeHandler( if (action === "pseudonymize") { const piiFields: Record = {}; - for (const field of collection.fields) { + for (const field of targetCollection.fields) { const f = field as { name?: string; custom?: { pii?: unknown } }; if (f.name && f.custom?.pii) { piiFields[f.name] = null;