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,51 @@
# context/audit-context
## Purpose
Builds the per-request `AuditContext` handle the audit middleware attaches to `c.set("audit", context)` before invoking `next()`. Handlers call `c.get("audit").log({...})` to fire explicit, semantic audit events alongside the implicit per-request audit that the middleware writes. This is the public extension point for application code — instead of importing `auditService` and threading it through every route, handlers reach into the Hono context.
The two-method surface (`log` + `getLogger`) is intentionally small so handler code stays focused on the event payload rather than the plumbing. The same underlying `AuditLogger` instance is reused across every request — there is one logger per app, not one per request — so chain-integrity links hold across handler-level and middleware-level events.
## Features
- Stable two-method surface (`log`, `getLogger`).
- Hono `ContextVariableMap` augmentation declared in `./context-augmentation.ts` so `c.get("audit")` types as `AuditContext` (not `unknown`).
- Zero per-request allocation beyond the lightweight wrapper object (no closures over the request, so the object can be cached if needed).
## Usage: Basic
```ts
// In a route handler:
app.post("/users/:id/delete", async (c) => {
const audit = c.get("audit");
await audit.log({
type: "user.deleted",
severity: "warning",
actor: { userId: c.get("user")?.id },
target: { type: "user", id: c.req.param("id") },
});
return c.json({ deleted: true });
});
```
## Usage: Advanced
```ts
// Reach the underlying logger for advanced ops:
app.get("/admin/audit-chain/verify", async (c) => {
const logger = c.get("audit").getLogger();
const events = await logger.query({ limit: 1000, order: "asc" });
const verdict = await logger.verifyChainIntegrity(events);
return c.json(verdict);
});
```
## API Reference
- `createAuditContext(deps: { logger: AuditLogger }): AuditContext`
- `log(event)` → `Promise<AuditEvent>`
- `getLogger()` → `AuditLogger`
## Implementation Notes
`AuditContext` does not carry the request, the principal, or the tenant. Handlers fill `actor.userId`, `actor.sessionId`, `tenantId`, and so on from `c.get("user")` / `c.get("tenant")` themselves. The middleware's per-request event populates those fields automatically; handler-level events stay explicit because the handler knows the semantic of the event (which user is the actor versus the target) better than the middleware does.