first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
# plugin/plugin
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Top-level factory for the audit plugin. `createAuditPlugin(options)` Zod-validates the caller's options at the boundary, builds the resolved `AuditPluginConfig`, and returns a typed `PluginDescriptor<AuditPluginConfig>` whose `onInit` hook performs the canonical 4-step lifecycle: resolve `app`, construct `AuditLogger`, register `auditService`, install the global middleware. The descriptor's `onClose` clears the cached logger reference.
This is the only entry point operators interact with. Everything else in the package is reachable through the descriptor or the ServiceRegistry slot the descriptor installs.
## Features
- Zod-validated options via `AuditPluginOptionsSchema`; failures throw `AuditPluginError(AUDIT_PLUGIN_INVALID_INPUT)` with the `ZodError` as `cause`.
- Defaults supply `MemoryAuditAdapter` when no sink is injected (dev fallback).
- Warns when the dev-default secret key is used so production operators notice.
- `onInit` raises `AUDIT_PLUGIN_SERVICE_NOT_AVAILABLE` when `app` is missing, listing `["app"]` in `context.missing`.
- `onInit` raises `AUDIT_PLUGIN_SINK_INIT_FAILED` when `new AuditLogger(...)` throws (e.g. missing/invalid secret key).
- `onInit` is idempotent in the sense that re-invocation rebuilds the logger and re-installs the middleware (Hono `app.use("*", ...)` chaining is additive, so callers should treat the descriptor as one-shot per registry).
## Usage: Basic
```ts
import { MemoryAuditAdapter } from "@suaveplan/audit-logging";
import { createAuditPlugin } from "@suaveplan/api-plugin-audit";
const plugin = createAuditPlugin({
sink: new MemoryAuditAdapter(),
secretKey: process.env.AUDIT_SECRET_KEY,
});
// register on your PluginRegistry alongside auth, tenant, etc.
```
## Usage: Advanced
```ts
import { createAuditPlugin } from "@suaveplan/api-plugin-audit";
import { MemoryAuditAdapter } from "@suaveplan/audit-logging";
const plugin = createAuditPlugin({
sink: new MemoryAuditAdapter(),
secretKey: process.env.AUDIT_SECRET_KEY,
samplingRate: 0.1, // record 10% of requests
excludePaths: ["/health", "/metrics", "/openapi.json"],
redactBodyFields: ["password", "ssn", "card_number"],
redactHeaders: ["authorization", "cookie", "x-internal-key"],
redactQueryParams: ["token", "code", "state", "session"],
recordRequestBody: true,
enableChainIntegrity: true,
});
```
## API Reference
- `createAuditPlugin(options: AuditPluginOptions): PluginDescriptor<AuditPluginConfig>`
- Validates `options` via `AuditPluginOptionsSchema`.
- Returns a descriptor with `name: "audit"`, `version: "0.1.0"`, resolved `defaults`, `onInit`, `onClose`.
## Implementation Notes
The factory captures the resolved `config` and a small `AuditPluginState` (currently just the cached logger) in a closure shared between `onInit` and `onClose`. The dev-default secret-key warning fires every time `onInit` runs — operators see it once per boot, which is the right cadence (loud enough to notice, quiet enough not to spam). The plugin does NOT depend on `@suaveplan/api`; it depends only on `@suaveplan/api-plugin` (for `definePlugin` + the context types) plus `@suaveplan/audit-logging` (for the runtime), `@suaveplan/error` / `@suaveplan/types`, `hono`, and `zod`. This keeps the dep graph small and lets the plugin attach to any Hono-based host.