feat(generators): wire audit entry + e2e byte-identical reconstruction test
This commit is contained in:
@@ -666,16 +666,28 @@ import noRealtimeHandlerReexport from "./rules/no-realtime-handler-reexport.js";
|
||||
},
|
||||
printUiNextSteps,
|
||||
],
|
||||
audit: () => [
|
||||
() => {
|
||||
assertOptionalPackageNotPresent("core-audit");
|
||||
return "Guard passed — packages/core-audit does not exist yet.";
|
||||
},
|
||||
...emitTemplateTree("core-package/audit", "packages/core-audit"),
|
||||
() => {
|
||||
addToTranspilePackages("apps/web-next/next.config.mjs", "@repo/core-audit");
|
||||
return "Added @repo/core-audit to transpilePackages.";
|
||||
},
|
||||
printAuditNextSteps,
|
||||
],
|
||||
};
|
||||
|
||||
plop.setGenerator("core-package", {
|
||||
description: "Scaffold an optional core package (realtime, events, trpc, ui)",
|
||||
description: "Scaffold an optional core package (realtime, events, trpc, ui, audit)",
|
||||
prompts: [
|
||||
{
|
||||
type: "list",
|
||||
name: "name",
|
||||
message: "Which optional core package?",
|
||||
choices: ["realtime", "events", "trpc", "ui"],
|
||||
choices: ["realtime", "events", "trpc", "ui", "audit"],
|
||||
},
|
||||
],
|
||||
actions: (answers) => {
|
||||
@@ -1324,6 +1336,54 @@ function printRealtimeNextSteps(): string {
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function printAuditNextSteps(): string {
|
||||
return [
|
||||
"─────────────────────────────────────────────────────────────",
|
||||
"@repo/core-audit scaffolded into packages/core-audit/.",
|
||||
"",
|
||||
"Manual wiring required (compliance-critical):",
|
||||
"",
|
||||
"1. Set AUDIT_PSEUDONYM_SALT env var (production REQUIRED):",
|
||||
' export AUDIT_PSEUDONYM_SALT="$(openssl rand -hex 32)"',
|
||||
" Add to your deployment secrets manager.",
|
||||
"",
|
||||
"2. Mount the audit-logs Payload collection in packages/core-cms/src/payload.config.ts:",
|
||||
' import { auditLogsCollection } from "@repo/core-audit/collection";',
|
||||
" // collections: [..., auditLogsCollection],",
|
||||
"",
|
||||
"3. Mount the admin tRPC router in packages/core-api/src/root.ts:",
|
||||
' import { createAuditRouter } from "@repo/core-audit/api";',
|
||||
" // const { auditLog } = bindAudit(container, { payloadConfig, sinks: [\"payload\", \"stdout\"] });",
|
||||
" // routers: { ..., audit: createAuditRouter(auditLog) },",
|
||||
"",
|
||||
"4. Bind audit in apps/web-next/src/server/bind-production.ts:",
|
||||
' const { bindAudit } = await import("@repo/core-audit/di");',
|
||||
" const { auditLog } = bindAudit(sharedContainer, {",
|
||||
" payloadConfig: resolvedConfig,",
|
||||
' sinks: ["payload", "stdout"],',
|
||||
" });",
|
||||
"",
|
||||
"5. Install user-collection hooks (recommended for DPA compliance):",
|
||||
" In packages/auth/src/di/bind-production.ts, gate on ctx.auditLog:",
|
||||
" if (ctx.auditLog) {",
|
||||
' const { createAuditErasureHook, createAuditAfterReadHook } =',
|
||||
' await import("@repo/core-audit/hooks");',
|
||||
" // wire onto users collection — see docs/guides/audit-and-compliance.md",
|
||||
" }",
|
||||
"",
|
||||
"6. Set up a log shipper (Vector / Fluent Bit) to forward stdout JSON to",
|
||||
" your aggregator. See docs/guides/audit-and-compliance.md for configs.",
|
||||
"",
|
||||
"7. Verify:",
|
||||
" pnpm install",
|
||||
" pnpm lint && pnpm typecheck && pnpm test",
|
||||
" pnpm turbo boundaries",
|
||||
"",
|
||||
"See docs/guides/audit-and-compliance.md for the full guide.",
|
||||
"─────────────────────────────────────────────────────────────",
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function coreUiComponentActions(a: {
|
||||
tier: "atom" | "molecule" | "organism";
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user