From 0c5ad08dcd0790d6b0037fa31b11498607756fd3 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Mon, 11 May 2026 16:10:58 +0200 Subject: [PATCH] feat(core-audit): scaffold optional package (no impls yet) Co-Authored-By: Claude Sonnet 4.6 --- apps/web-next/next.config.mjs | 1 + packages/core-audit/AGENTS.md | 28 +++++++++++++++++++ packages/core-audit/eslint.config.js | 3 +++ packages/core-audit/package.json | 40 ++++++++++++++++++++++++++++ packages/core-audit/tsconfig.json | 12 +++++++++ packages/core-audit/turbo.json | 4 +++ packages/core-audit/vitest.config.ts | 9 +++++++ pnpm-lock.yaml | 37 +++++++++++++++++++++++++ 8 files changed, 134 insertions(+) create mode 100644 packages/core-audit/AGENTS.md create mode 100644 packages/core-audit/eslint.config.js create mode 100644 packages/core-audit/package.json create mode 100644 packages/core-audit/tsconfig.json create mode 100644 packages/core-audit/turbo.json create mode 100644 packages/core-audit/vitest.config.ts diff --git a/apps/web-next/next.config.mjs b/apps/web-next/next.config.mjs index 22f8158..9050a92 100644 --- a/apps/web-next/next.config.mjs +++ b/apps/web-next/next.config.mjs @@ -6,6 +6,7 @@ const nextConfig = { "@repo/auth", "@repo/blog", "@repo/core-api", + "@repo/core-audit", "@repo/core-cms", "@repo/core-shared", "@repo/marketing-pages", diff --git a/packages/core-audit/AGENTS.md b/packages/core-audit/AGENTS.md new file mode 100644 index 0000000..052f88f --- /dev/null +++ b/packages/core-audit/AGENTS.md @@ -0,0 +1,28 @@ +# @repo/core-audit + +Optional core package providing DPA-compliant audit logging. Scaffold via `pnpm turbo gen core-package audit`. + +## Structure + +``` +src/ + audit-log.interface.ts # IAuditLog extends AuditLogProtocol + audit-logs-collection.ts # Payload collection (append-only) + noop-audit-log.ts # NoopAuditLog + payload-audit-log.ts # PayloadAuditLog (local cache impl) + stdout-json-audit-log.ts # StdoutJsonAuditLog (log-shipper sink) + multi-sink-audit-log.ts # MultiSinkAuditLog (fan-out wrapper) + trace-id-enriching-audit-log.ts # OTel correlation decorator + pseudonymize.ts # sha256-with-salt for GDPR pseudonymization + di/bind-audit.ts # bindAudit binder + integrations/api/router.ts # admin tRPC procedure + hooks/ # Payload hook factories +``` + +## Compliance posture + +- `AuditEntry` type (in `@repo/core-shared/audit`) has no `payload`/`body`/`oldValue`/`newValue` fields — type system enforces DPA "what NOT to log". +- Append-only Payload collection (`update: () => false`); erasure uses `overrideAccess: true` for the privileged path. +- `AUDIT_PSEUDONYM_SALT` env REQUIRED in production. Validated at bind time. + +See `docs/guides/audit-and-compliance.md` for the full guide. diff --git a/packages/core-audit/eslint.config.js b/packages/core-audit/eslint.config.js new file mode 100644 index 0000000..7440d8f --- /dev/null +++ b/packages/core-audit/eslint.config.js @@ -0,0 +1,3 @@ +import baseConfig from "@repo/core-eslint/base"; + +export default baseConfig; diff --git a/packages/core-audit/package.json b/packages/core-audit/package.json new file mode 100644 index 0000000..0eaac61 --- /dev/null +++ b/packages/core-audit/package.json @@ -0,0 +1,40 @@ +{ + "name": "@repo/core-audit", + "version": "0.0.1", + "private": true, + "type": "module", + "exports": { + ".": "./src/index.ts", + "./collection": "./src/audit-logs-collection.ts", + "./di": "./src/di/bind-audit.ts", + "./hooks": "./src/hooks/index.ts", + "./api": "./src/integrations/api/router.ts" + }, + "scripts": { + "build": "tsc --noEmit", + "lint": "eslint .", + "typecheck": "tsc --noEmit", + "test": "vitest run" + }, + "dependencies": { + "@repo/core-shared": "workspace:*", + "@trpc/server": "^11.0.0", + "zod": "^3.23.0" + }, + "peerDependencies": { + "payload": "^3.0.0" + }, + "peerDependenciesMeta": { + "payload": { "optional": true } + }, + "devDependencies": { + "@repo/core-eslint": "workspace:*", + "@repo/core-testing": "workspace:*", + "@repo/core-typescript": "workspace:*", + "inversify": "^6.2.0", + "payload": "^3.14.0", + "reflect-metadata": "^0.2.2", + "typescript": "^5.8.0", + "vitest": "^3.0.0" + } +} diff --git a/packages/core-audit/tsconfig.json b/packages/core-audit/tsconfig.json new file mode 100644 index 0000000..8facef5 --- /dev/null +++ b/packages/core-audit/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@repo/core-typescript/base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["**/*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/core-audit/turbo.json b/packages/core-audit/turbo.json new file mode 100644 index 0000000..dcb8fb3 --- /dev/null +++ b/packages/core-audit/turbo.json @@ -0,0 +1,4 @@ +{ + "extends": ["//"], + "tags": ["core"] +} diff --git a/packages/core-audit/vitest.config.ts b/packages/core-audit/vitest.config.ts new file mode 100644 index 0000000..2ee07c1 --- /dev/null +++ b/packages/core-audit/vitest.config.ts @@ -0,0 +1,9 @@ +import path from "node:path"; +import { mergeConfig } from "vitest/config"; +import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node"; + +export default mergeConfig(nodeVitestConfig, { + resolve: { + alias: { "@": path.resolve(__dirname, "./src") }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec3b253..06d44e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -429,6 +429,43 @@ importers: specifier: ^3.0.0 version: 3.2.4(@types/debug@4.1.13)(@types/node@22.19.17)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0) + packages/core-audit: + dependencies: + '@repo/core-shared': + specifier: workspace:* + version: link:../core-shared + '@trpc/server': + specifier: ^11.0.0 + version: 11.16.0(typescript@5.9.3) + zod: + specifier: ^3.23.0 + version: 3.25.76 + devDependencies: + '@repo/core-eslint': + specifier: workspace:* + version: link:../core-eslint + '@repo/core-testing': + specifier: workspace:* + version: link:../core-testing + '@repo/core-typescript': + specifier: workspace:* + version: link:../core-typescript + inversify: + specifier: ^6.2.0 + version: 6.2.2(reflect-metadata@0.2.2) + payload: + specifier: ^3.14.0 + version: 3.81.0(graphql@16.13.2)(typescript@5.9.3) + reflect-metadata: + specifier: ^0.2.2 + version: 0.2.2 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0) + packages/core-cms: dependencies: '@payloadcms/db-postgres':