# services/audit-service ## Purpose Constructs the `AuditService` adapter the plugin registers in `ServiceRegistry` under the `auditService` slot. The adapter wraps a constructed `AuditLogger` from `@suaveplan/audit-logging` so downstream code depends on the stable interface declared in `../types/types.ts` instead of binding to whatever the universal library exposes today. If the library renames or removes a method later, only this adapter file changes. The wrapper is intentionally thin — every method delegates to the underlying logger one-for-one — but it gives the plugin a clean seam to add cross-cutting behaviour (tenancy enforcement, OTel correlation, idempotency) without touching every call site. ## Features - 1:1 proxy over `AuditLogger.log / query / verifyChainIntegrity / exportGDPRData / applyRetentionPolicy`. - `getLogger()` escape hatch for callers that need direct access (the underlying logger exposes operations not in the stable surface, e.g. event-bus introspection). - Constructor takes a plain `{ logger }` dependency bundle — easy to swap or stub at test time. ## Usage: Basic ```ts import { AuditLogger, MemoryAuditAdapter } from "@suaveplan/audit-logging"; import { createAuditService } from "@suaveplan/api-plugin-audit/services/audit-service"; const logger = new AuditLogger({ storage: new MemoryAuditAdapter(), secretKey: process.env.AUDIT_SECRET_KEY!, }); const auditService = createAuditService({ logger }); await auditService.log({ type: "user.created", severity: "info", actor: { userId: "u1" }, }); ``` ## Usage: Advanced ```ts import { AuditLogger, MemoryAuditAdapter, type AuditEvent, } from "@suaveplan/audit-logging"; import { createAuditService } from "@suaveplan/api-plugin-audit/services/audit-service"; const auditService = createAuditService({ logger: new AuditLogger({ storage: new MemoryAuditAdapter(), secretKey: process.env.AUDIT_SECRET_KEY!, enableChainIntegrity: true, }), }); const events: AuditEvent[] = await auditService.query({ userId: "u1", limit: 50, order: "desc", }); const verdict = await auditService.verifyChainIntegrity(events); if (!verdict.valid) { console.error("chain broken at", verdict.brokenAt, verdict.reason); } ``` ## API Reference - `createAuditService(deps: { logger: AuditLogger }): AuditService` - Returns an object satisfying the `AuditService` interface from `../types/types.ts`. - Methods: `getLogger()`, `log(event)`, `query(opts)`, `verifyChainIntegrity(events)`, `exportGDPRData(userId, signal?)`, `applyRetentionPolicy(signal?)`. ## Implementation Notes Every method returns the underlying `Promise` directly — no wrapping, no try/catch — because the plugin's middleware path handles sink failures explicitly via `audit.sink_failures_total`. Consumers that call `auditService.log(...)` from a handler get the raw `AuditError` from `@suaveplan/audit-logging` and can branch on its codes. This separation keeps the middleware (which must never throw into the request response) and the handler-level helper (which can surface failures) consistent.