feat(core-audit): scaffold optional package (no impls yet)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-11 16:10:58 +02:00
parent a3b7100d10
commit 0c5ad08dcd
8 changed files with 134 additions and 0 deletions

View File

@@ -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.

View File

@@ -0,0 +1,3 @@
import baseConfig from "@repo/core-eslint/base";
export default baseConfig;

View File

@@ -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"
}
}

View File

@@ -0,0 +1,12 @@
{
"extends": "@repo/core-typescript/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -0,0 +1,4 @@
{
"extends": ["//"],
"tags": ["core"]
}

View File

@@ -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") },
},
});