hazo_audit 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGE_LOG.md +63 -0
- package/config/hazo_audit_config.ini.sample +28 -0
- package/db_setup_postgres.sql +76 -0
- package/db_setup_sqlite.sql +72 -0
- package/dist/client/AuditViewer.js +1 -1
- package/dist/client/FieldAuditIcon.js +1 -1
- package/dist/client/FieldAuditTrail.js +1 -1
- package/dist/client/RevertConfirmDialog.js +1 -1
- package/dist/lib/config/hazo_audit_config.d.ts +99 -0
- package/dist/lib/config/hazo_audit_config.d.ts.map +1 -0
- package/dist/lib/config/hazo_audit_config.js +67 -0
- package/dist/lib/config/hazo_audit_config.js.map +1 -0
- package/dist/nextjs/index.d.ts +12 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/index.js +307 -218
- package/dist/nextjs/index.js.map +1 -1
- package/dist/server/audited_crud.js +3 -3
- package/dist/server/audited_crud.js.map +1 -1
- package/dist/server/context.js +3 -3
- package/dist/server/context.js.map +1 -1
- package/dist/server/errors.d.ts +10 -1
- package/dist/server/errors.d.ts.map +1 -1
- package/dist/server/errors.js +16 -2
- package/dist/server/errors.js.map +1 -1
- package/dist/server/intent.js +3 -3
- package/dist/server/intent.js.map +1 -1
- package/dist/server/outbox.js +2 -2
- package/dist/server/outbox.js.map +1 -1
- package/dist/server/worker.d.ts +7 -7
- package/dist/server/worker.d.ts.map +1 -1
- package/dist/server/worker.js +60 -15
- package/dist/server/worker.js.map +1 -1
- package/dist/server/wrap.js +2 -2
- package/dist/server/wrap.js.map +1 -1
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +42 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/uuid.d.ts +19 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +22 -0
- package/dist/utils/uuid.js.map +1 -0
- package/package.json +36 -21
- package/dist/client/cn.d.ts +0 -3
- package/dist/client/cn.d.ts.map +0 -1
- package/dist/client/cn.js +0 -6
- package/dist/client/cn.js.map +0 -1
package/CHANGE_LOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## 2.1.0 — 2026-05-29
|
|
4
|
+
|
|
5
|
+
### Workspace v2 migration (Wave 2)
|
|
6
|
+
|
|
7
|
+
Standardisation onto the workspace foundation packages — adopt `hazo_core`,
|
|
8
|
+
align logging / errors / correlation IDs / config / UUIDs with the rest of
|
|
9
|
+
the ecosystem. No public API removed; the previous response shapes for
|
|
10
|
+
`/audit/events`, `reveal`, and `viewer` are preserved.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`hazo_core` peer dependency (`^1.0.0`).** Required; supplies
|
|
15
|
+
`HazoError`, `withContext`, `generateRequestId`, `createLogger`,
|
|
16
|
+
`loadConfig`.
|
|
17
|
+
- **`hazo_ui` peer dependency (`^3.0.1`, optional).** Client components now
|
|
18
|
+
import `cn` from `hazo_ui` — consumers that use `<FieldAuditIcon>` etc.
|
|
19
|
+
must install it. Server-only consumers can skip it.
|
|
20
|
+
- **Workspace-standard logger** at `src/utils/logger.ts` — `get_logger()` /
|
|
21
|
+
`set_logger()` default to `createLogger('hazo_audit')`. Worker + Next.js
|
|
22
|
+
routes emit structured event names (`worker.started`,
|
|
23
|
+
`outbox.row_drained`, `outbox.row_failed`, `events.reveal.served`, etc.).
|
|
24
|
+
- **`withContext` wrapping** around every drained outbox row in the worker
|
|
25
|
+
and every Next.js handler — correlation IDs from the producing write flow
|
|
26
|
+
through every nested DB call and `fetchWithRequestId`.
|
|
27
|
+
- **`HazoError` subclasses** — `RecordNotFoundError` now extends
|
|
28
|
+
`HazoNotFoundError` (`HAZO_AUDIT_RECORD_NOT_FOUND`, httpStatus 404). Route
|
|
29
|
+
handlers use a `handleError(logger, event, error)` helper that maps
|
|
30
|
+
`HazoError.is(err)` to the right HTTP status + log level.
|
|
31
|
+
- **`src/lib/config/hazo_audit_config.ts`** — workspace-standard INI
|
|
32
|
+
loader via `hazo_core.loadConfig` for `[general]` / `[log.overrides]` /
|
|
33
|
+
`[retention]` / `[worker]` sections. Coexists with
|
|
34
|
+
`src/server/config.ts::loadAuditConfig()`, which keeps owning the
|
|
35
|
+
package-specific `[capture]` and `[overrides.*]` rules.
|
|
36
|
+
- **`config/hazo_audit_config.ini.sample`** now documents the
|
|
37
|
+
`[general]` and `[log.overrides]` sections and `HAZO_AUDIT_<SECTION>_<KEY>`
|
|
38
|
+
env-var overrides.
|
|
39
|
+
- **Root `db_setup_postgres.sql` + `db_setup_sqlite.sql`** — idempotent,
|
|
40
|
+
consumer-facing schema setup (S6). The historical `migrations/001_init.sql`
|
|
41
|
+
is preserved.
|
|
42
|
+
- **`AGENTS.md`** at root + `src/`, and `design/feature_requests/INDEX.md`
|
|
43
|
+
skeleton (S13 + S16).
|
|
44
|
+
- **`/autotest` route** in the test-app powered by
|
|
45
|
+
`hazo_ui/test-harness` — workspace-standard browser scenarios
|
|
46
|
+
(`cn` re-export, `generateRequestId`, `HazoError` subclasses,
|
|
47
|
+
`withContext` / `getCorrelationId`).
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **`crypto.randomUUID()` removed** from all server modules in favour of
|
|
52
|
+
`src/utils/uuid.ts::generateUUID()` (wraps
|
|
53
|
+
`generateRequestId().slice(4)` from `hazo_core`).
|
|
54
|
+
- **`src/client/cn.ts` deleted** — components now import `cn` from
|
|
55
|
+
`hazo_ui`. The local `clsx + tailwind-merge` duplicate is gone.
|
|
56
|
+
- **Worker logger interface** narrowed to the workspace `Logger` type and
|
|
57
|
+
defaults to `get_logger()` when the consumer doesn't pass one.
|
|
58
|
+
- **test-app/package.json** uses `"*"` for workspace-local resolution of
|
|
59
|
+
`hazo_audit`, `hazo_connect`, `hazo_core`, `hazo_ui` (previously
|
|
60
|
+
`file:..`). `next.config.js` adds `hazo_core`, `hazo_logs`, `hazo_ui` to
|
|
61
|
+
`transpilePackages`.
|
|
62
|
+
- **`engines` block removed** from package.json (workspace standard).
|
|
63
|
+
- **Workspace registration** — `hazo_audit/test-app` is now listed in the
|
|
64
|
+
root `package.json` `workspaces` array.
|
|
65
|
+
|
|
3
66
|
## 2.0.2 — 2026-05-27
|
|
4
67
|
|
|
5
68
|
### Added
|
|
@@ -4,7 +4,35 @@
|
|
|
4
4
|
; and startAuditWorker() at startup. INI is the primary source of truth for
|
|
5
5
|
; capture rules; the only TypeScript-shaped escape hatch is the `resolvers`
|
|
6
6
|
; option on wrapWithAudit().
|
|
7
|
+
;
|
|
8
|
+
; Per hazo workspace standard S7, values may also be overridden via env vars:
|
|
9
|
+
; HAZO_AUDIT_<SECTION>_<KEY>=value
|
|
10
|
+
; e.g. HAZO_AUDIT_WORKER_POLL_MS=500
|
|
11
|
+
;
|
|
12
|
+
; Per D-019, a per-environment overlay file at
|
|
13
|
+
; config/hazo_audit_config.<HAZO_ENV>.ini
|
|
14
|
+
; is layered on top of this base file when HAZO_ENV is set.
|
|
15
|
+
|
|
16
|
+
; ============================================================================
|
|
17
|
+
; [general] - Workspace-standard general configuration
|
|
18
|
+
; ============================================================================
|
|
19
|
+
[general]
|
|
20
|
+
|
|
21
|
+
; Deployment environment label. Falls back to NODE_ENV, then 'development'.
|
|
22
|
+
; env = production
|
|
7
23
|
|
|
24
|
+
; ============================================================================
|
|
25
|
+
; [log.overrides] - Per-namespace log level overrides (workspace standard)
|
|
26
|
+
; Format: <namespace> = trace|debug|info|warn|error
|
|
27
|
+
; ============================================================================
|
|
28
|
+
[log.overrides]
|
|
29
|
+
|
|
30
|
+
; hazo_audit = info
|
|
31
|
+
; hazo_audit/worker = warn
|
|
32
|
+
|
|
33
|
+
; ============================================================================
|
|
34
|
+
; [capture] - Which tables to audit
|
|
35
|
+
; ============================================================================
|
|
8
36
|
[capture]
|
|
9
37
|
; Whitelist by prefix or exact name. At least one of include_* must match for
|
|
10
38
|
; a write to be captured (after passing exclusions).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
-- hazo_audit PostgreSQL schema setup (idempotent)
|
|
2
|
+
--
|
|
3
|
+
-- Three tables:
|
|
4
|
+
-- hazo_audit_outbox : queue produced by wrapWithAudit, drained by the worker
|
|
5
|
+
-- hazo_audit_field : per-leaf field events the UI reads from
|
|
6
|
+
-- hazo_audit_intent : Layer-1 named events (e.g., 'audit_reveal')
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_outbox (
|
|
9
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
10
|
+
scope_id UUID,
|
|
11
|
+
correlation_id UUID NOT NULL,
|
|
12
|
+
table_name TEXT NOT NULL,
|
|
13
|
+
subject_kind TEXT NOT NULL,
|
|
14
|
+
subject_id TEXT NOT NULL,
|
|
15
|
+
op TEXT NOT NULL CHECK (op IN ('insert','update','delete')),
|
|
16
|
+
before_row JSONB,
|
|
17
|
+
after_row JSONB,
|
|
18
|
+
actor_kind TEXT NOT NULL,
|
|
19
|
+
actor_user_id UUID,
|
|
20
|
+
actor_label TEXT,
|
|
21
|
+
intent_event TEXT,
|
|
22
|
+
intent_payload JSONB,
|
|
23
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
24
|
+
drained_at TIMESTAMPTZ,
|
|
25
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
last_attempt_at TIMESTAMPTZ,
|
|
27
|
+
failed_at TIMESTAMPTZ,
|
|
28
|
+
failure_reason TEXT
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_outbox_drain
|
|
32
|
+
ON hazo_audit_outbox (drained_at, failed_at, attempt_count, last_attempt_at)
|
|
33
|
+
WHERE drained_at IS NULL AND failed_at IS NULL;
|
|
34
|
+
|
|
35
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_outbox_chain
|
|
36
|
+
ON hazo_audit_outbox (subject_kind, subject_id, created_at DESC)
|
|
37
|
+
WHERE drained_at IS NOT NULL;
|
|
38
|
+
|
|
39
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_field (
|
|
40
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
41
|
+
scope_id UUID,
|
|
42
|
+
correlation_id UUID NOT NULL,
|
|
43
|
+
subject_kind TEXT NOT NULL,
|
|
44
|
+
subject_id TEXT NOT NULL,
|
|
45
|
+
field_path TEXT NOT NULL,
|
|
46
|
+
op TEXT NOT NULL CHECK (op IN ('insert','update','delete')),
|
|
47
|
+
before_value JSONB,
|
|
48
|
+
after_value JSONB,
|
|
49
|
+
is_sensitive BOOLEAN NOT NULL DEFAULT FALSE,
|
|
50
|
+
actor_kind TEXT NOT NULL,
|
|
51
|
+
actor_user_id UUID,
|
|
52
|
+
actor_label TEXT,
|
|
53
|
+
occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_field_subject
|
|
57
|
+
ON hazo_audit_field (subject_kind, subject_id, field_path, occurred_at DESC);
|
|
58
|
+
|
|
59
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_intent (
|
|
60
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
61
|
+
scope_id UUID,
|
|
62
|
+
correlation_id UUID NOT NULL,
|
|
63
|
+
event_name TEXT NOT NULL,
|
|
64
|
+
payload JSONB,
|
|
65
|
+
subject_kind TEXT,
|
|
66
|
+
subject_id TEXT,
|
|
67
|
+
actor_kind TEXT NOT NULL,
|
|
68
|
+
actor_user_id UUID,
|
|
69
|
+
actor_label TEXT,
|
|
70
|
+
occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_intent_event
|
|
74
|
+
ON hazo_audit_intent (event_name, occurred_at DESC);
|
|
75
|
+
|
|
76
|
+
NOTIFY pgrst, 'reload schema';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- hazo_audit SQLite schema setup (idempotent)
|
|
2
|
+
--
|
|
3
|
+
-- Three tables:
|
|
4
|
+
-- hazo_audit_outbox : queue produced by wrapWithAudit, drained by the worker
|
|
5
|
+
-- hazo_audit_field : per-leaf field events the UI reads from
|
|
6
|
+
-- hazo_audit_intent : Layer-1 named events (e.g., 'audit_reveal')
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_outbox (
|
|
9
|
+
id TEXT PRIMARY KEY,
|
|
10
|
+
scope_id TEXT,
|
|
11
|
+
correlation_id TEXT NOT NULL,
|
|
12
|
+
table_name TEXT NOT NULL,
|
|
13
|
+
subject_kind TEXT NOT NULL,
|
|
14
|
+
subject_id TEXT NOT NULL,
|
|
15
|
+
op TEXT NOT NULL CHECK (op IN ('insert','update','delete')),
|
|
16
|
+
before_row TEXT,
|
|
17
|
+
after_row TEXT,
|
|
18
|
+
actor_kind TEXT NOT NULL,
|
|
19
|
+
actor_user_id TEXT,
|
|
20
|
+
actor_label TEXT,
|
|
21
|
+
intent_event TEXT,
|
|
22
|
+
intent_payload TEXT,
|
|
23
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
24
|
+
drained_at TEXT,
|
|
25
|
+
attempt_count INTEGER NOT NULL DEFAULT 0,
|
|
26
|
+
last_attempt_at TEXT,
|
|
27
|
+
failed_at TEXT,
|
|
28
|
+
failure_reason TEXT
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_outbox_drain
|
|
32
|
+
ON hazo_audit_outbox (drained_at, failed_at, attempt_count, last_attempt_at);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_outbox_chain
|
|
35
|
+
ON hazo_audit_outbox (subject_kind, subject_id, created_at);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_field (
|
|
38
|
+
id TEXT PRIMARY KEY,
|
|
39
|
+
scope_id TEXT,
|
|
40
|
+
correlation_id TEXT NOT NULL,
|
|
41
|
+
subject_kind TEXT NOT NULL,
|
|
42
|
+
subject_id TEXT NOT NULL,
|
|
43
|
+
field_path TEXT NOT NULL,
|
|
44
|
+
op TEXT NOT NULL CHECK (op IN ('insert','update','delete')),
|
|
45
|
+
before_value TEXT,
|
|
46
|
+
after_value TEXT,
|
|
47
|
+
is_sensitive INTEGER NOT NULL DEFAULT 0,
|
|
48
|
+
actor_kind TEXT NOT NULL,
|
|
49
|
+
actor_user_id TEXT,
|
|
50
|
+
actor_label TEXT,
|
|
51
|
+
occurred_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_field_subject
|
|
55
|
+
ON hazo_audit_field (subject_kind, subject_id, field_path, occurred_at);
|
|
56
|
+
|
|
57
|
+
CREATE TABLE IF NOT EXISTS hazo_audit_intent (
|
|
58
|
+
id TEXT PRIMARY KEY,
|
|
59
|
+
scope_id TEXT,
|
|
60
|
+
correlation_id TEXT NOT NULL,
|
|
61
|
+
event_name TEXT NOT NULL,
|
|
62
|
+
payload TEXT,
|
|
63
|
+
subject_kind TEXT,
|
|
64
|
+
subject_id TEXT,
|
|
65
|
+
actor_kind TEXT NOT NULL,
|
|
66
|
+
actor_user_id TEXT,
|
|
67
|
+
actor_label TEXT,
|
|
68
|
+
occurred_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
CREATE INDEX IF NOT EXISTS ix_hazo_audit_intent_event
|
|
72
|
+
ON hazo_audit_intent (event_name, occurred_at);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
-
import { cn } from '
|
|
4
|
+
import { cn } from 'hazo_ui';
|
|
5
5
|
export function AuditViewer({ api_base = '/api/audit', initialFilters = {}, className, }) {
|
|
6
6
|
const [filters, setFilters] = useState(initialFilters);
|
|
7
7
|
const [events, setEvents] = useState([]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { cn } from '
|
|
4
|
+
import { cn } from 'hazo_ui';
|
|
5
5
|
import { FieldAuditTrail } from './FieldAuditTrail.js';
|
|
6
6
|
/**
|
|
7
7
|
* Small clock-icon button that opens a popover with the field's audit trail.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { cn } from '
|
|
4
|
+
import { cn } from 'hazo_ui';
|
|
5
5
|
import { DEFAULT_OP_LABELS } from '../index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Renders an ordered list of field audit events for a subject (optionally
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { cn } from '
|
|
4
|
+
import { cn } from 'hazo_ui';
|
|
5
5
|
export function RevertConfirmDialog({ open, table, recordId, toTimestamp, onConfirm, onClose, className, }) {
|
|
6
6
|
const [reason, setReason] = useState('');
|
|
7
7
|
const [working, setWorking] = useState(false);
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hazo_audit standard workspace-configuration schema + loader.
|
|
3
|
+
*
|
|
4
|
+
* Wraps hazo_core's `loadConfig` with a Zod schema that mirrors the
|
|
5
|
+
* `[general]` and `[log.overrides]` sections of `config/hazo_audit_config.ini`.
|
|
6
|
+
*
|
|
7
|
+
* Capture / retention / worker / overrides sections continue to be loaded
|
|
8
|
+
* by `src/server/config.ts::loadAuditConfig()` — that's the package-specific
|
|
9
|
+
* runtime config layer and is kept separate so the workspace-standard loader
|
|
10
|
+
* stays a thin Zod wrapper.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order (per hazo_core/loadConfig):
|
|
13
|
+
* 1. <pkg>_config.ini at process.cwd()/config/ or package root
|
|
14
|
+
* 2. <pkg>_config.<HAZO_ENV>.ini overlay
|
|
15
|
+
* 3. HAZO_AUDIT_<SECTION>_<KEY> env-var overrides
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
declare const schema: z.ZodNullable<z.ZodObject<{
|
|
19
|
+
general: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
env: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
env?: string | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
env?: string | undefined;
|
|
25
|
+
}>>;
|
|
26
|
+
log: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
overrides: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
28
|
+
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
overrides?: Record<string, string> | undefined;
|
|
30
|
+
}, {
|
|
31
|
+
overrides?: Record<string, string> | undefined;
|
|
32
|
+
}>>;
|
|
33
|
+
retention: z.ZodOptional<z.ZodObject<{
|
|
34
|
+
outbox_drained_ttl_days: z.ZodOptional<z.ZodString>;
|
|
35
|
+
outbox_failed_ttl_days: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, "strip", z.ZodTypeAny, {
|
|
37
|
+
outbox_drained_ttl_days?: string | undefined;
|
|
38
|
+
outbox_failed_ttl_days?: string | undefined;
|
|
39
|
+
}, {
|
|
40
|
+
outbox_drained_ttl_days?: string | undefined;
|
|
41
|
+
outbox_failed_ttl_days?: string | undefined;
|
|
42
|
+
}>>;
|
|
43
|
+
worker: z.ZodOptional<z.ZodObject<{
|
|
44
|
+
poll_ms: z.ZodOptional<z.ZodString>;
|
|
45
|
+
max_attempts: z.ZodOptional<z.ZodString>;
|
|
46
|
+
backoff_initial_ms: z.ZodOptional<z.ZodString>;
|
|
47
|
+
reaper_interval_ms: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, "strip", z.ZodTypeAny, {
|
|
49
|
+
poll_ms?: string | undefined;
|
|
50
|
+
max_attempts?: string | undefined;
|
|
51
|
+
backoff_initial_ms?: string | undefined;
|
|
52
|
+
reaper_interval_ms?: string | undefined;
|
|
53
|
+
}, {
|
|
54
|
+
poll_ms?: string | undefined;
|
|
55
|
+
max_attempts?: string | undefined;
|
|
56
|
+
backoff_initial_ms?: string | undefined;
|
|
57
|
+
reaper_interval_ms?: string | undefined;
|
|
58
|
+
}>>;
|
|
59
|
+
}, "strip", z.ZodTypeAny, {
|
|
60
|
+
log?: {
|
|
61
|
+
overrides?: Record<string, string> | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
general?: {
|
|
64
|
+
env?: string | undefined;
|
|
65
|
+
} | undefined;
|
|
66
|
+
retention?: {
|
|
67
|
+
outbox_drained_ttl_days?: string | undefined;
|
|
68
|
+
outbox_failed_ttl_days?: string | undefined;
|
|
69
|
+
} | undefined;
|
|
70
|
+
worker?: {
|
|
71
|
+
poll_ms?: string | undefined;
|
|
72
|
+
max_attempts?: string | undefined;
|
|
73
|
+
backoff_initial_ms?: string | undefined;
|
|
74
|
+
reaper_interval_ms?: string | undefined;
|
|
75
|
+
} | undefined;
|
|
76
|
+
}, {
|
|
77
|
+
log?: {
|
|
78
|
+
overrides?: Record<string, string> | undefined;
|
|
79
|
+
} | undefined;
|
|
80
|
+
general?: {
|
|
81
|
+
env?: string | undefined;
|
|
82
|
+
} | undefined;
|
|
83
|
+
retention?: {
|
|
84
|
+
outbox_drained_ttl_days?: string | undefined;
|
|
85
|
+
outbox_failed_ttl_days?: string | undefined;
|
|
86
|
+
} | undefined;
|
|
87
|
+
worker?: {
|
|
88
|
+
poll_ms?: string | undefined;
|
|
89
|
+
max_attempts?: string | undefined;
|
|
90
|
+
backoff_initial_ms?: string | undefined;
|
|
91
|
+
reaper_interval_ms?: string | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
}>>;
|
|
94
|
+
export type AuditStandardConfig = NonNullable<z.infer<typeof schema>>;
|
|
95
|
+
export declare function getAuditConfig(): AuditStandardConfig;
|
|
96
|
+
/** Reset the in-memory cache. Mainly for tests. */
|
|
97
|
+
export declare function resetAuditConfigCache(): void;
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=hazo_audit_config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazo_audit_config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/hazo_audit_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BC,CAAC;AAEd,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC;AAItE,wBAAgB,cAAc,IAAI,mBAAmB,CAYpD;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hazo_audit standard workspace-configuration schema + loader.
|
|
3
|
+
*
|
|
4
|
+
* Wraps hazo_core's `loadConfig` with a Zod schema that mirrors the
|
|
5
|
+
* `[general]` and `[log.overrides]` sections of `config/hazo_audit_config.ini`.
|
|
6
|
+
*
|
|
7
|
+
* Capture / retention / worker / overrides sections continue to be loaded
|
|
8
|
+
* by `src/server/config.ts::loadAuditConfig()` — that's the package-specific
|
|
9
|
+
* runtime config layer and is kept separate so the workspace-standard loader
|
|
10
|
+
* stays a thin Zod wrapper.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order (per hazo_core/loadConfig):
|
|
13
|
+
* 1. <pkg>_config.ini at process.cwd()/config/ or package root
|
|
14
|
+
* 2. <pkg>_config.<HAZO_ENV>.ini overlay
|
|
15
|
+
* 3. HAZO_AUDIT_<SECTION>_<KEY> env-var overrides
|
|
16
|
+
*/
|
|
17
|
+
import { loadConfig } from 'hazo_core';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
const schema = z
|
|
20
|
+
.object({
|
|
21
|
+
general: z
|
|
22
|
+
.object({
|
|
23
|
+
env: z.string().optional(),
|
|
24
|
+
})
|
|
25
|
+
.optional(),
|
|
26
|
+
log: z
|
|
27
|
+
.object({
|
|
28
|
+
overrides: z.record(z.string(), z.string()).optional(),
|
|
29
|
+
})
|
|
30
|
+
.optional(),
|
|
31
|
+
retention: z
|
|
32
|
+
.object({
|
|
33
|
+
outbox_drained_ttl_days: z.string().optional(),
|
|
34
|
+
outbox_failed_ttl_days: z.string().optional(),
|
|
35
|
+
})
|
|
36
|
+
.optional(),
|
|
37
|
+
worker: z
|
|
38
|
+
.object({
|
|
39
|
+
poll_ms: z.string().optional(),
|
|
40
|
+
max_attempts: z.string().optional(),
|
|
41
|
+
backoff_initial_ms: z.string().optional(),
|
|
42
|
+
reaper_interval_ms: z.string().optional(),
|
|
43
|
+
})
|
|
44
|
+
.optional(),
|
|
45
|
+
})
|
|
46
|
+
.nullable();
|
|
47
|
+
let _cached = null;
|
|
48
|
+
export function getAuditConfig() {
|
|
49
|
+
if (_cached !== null)
|
|
50
|
+
return _cached;
|
|
51
|
+
try {
|
|
52
|
+
_cached =
|
|
53
|
+
loadConfig({
|
|
54
|
+
pkg: 'hazo_audit',
|
|
55
|
+
schema: schema,
|
|
56
|
+
}) ?? {};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
_cached = {};
|
|
60
|
+
}
|
|
61
|
+
return _cached;
|
|
62
|
+
}
|
|
63
|
+
/** Reset the in-memory cache. Mainly for tests. */
|
|
64
|
+
export function resetAuditConfigCache() {
|
|
65
|
+
_cached = null;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=hazo_audit_config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazo_audit_config.js","sourceRoot":"","sources":["../../../src/lib/config/hazo_audit_config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,GAAG,CAAC;KACb,MAAM,CAAC;IACN,OAAO,EAAE,CAAC;SACP,MAAM,CAAC;QACN,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC3B,CAAC;SACD,QAAQ,EAAE;IACb,GAAG,EAAE,CAAC;SACH,MAAM,CAAC;QACN,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;KACvD,CAAC;SACD,QAAQ,EAAE;IACb,SAAS,EAAE,CAAC;SACT,MAAM,CAAC;QACN,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9C,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9C,CAAC;SACD,QAAQ,EAAE;IACb,MAAM,EAAE,CAAC;SACN,MAAM,CAAC;QACN,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACzC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC1C,CAAC;SACD,QAAQ,EAAE;CACd,CAAC;KACD,QAAQ,EAAE,CAAC;AAId,IAAI,OAAO,GAA+B,IAAI,CAAC;AAE/C,MAAM,UAAU,cAAc;IAC5B,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IACrC,IAAI,CAAC;QACH,OAAO;YACL,UAAU,CAAsB;gBAC9B,GAAG,EAAE,YAAY;gBACjB,MAAM,EAAE,MAAe;aACxB,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,EAAE,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,qBAAqB;IACnC,OAAO,GAAG,IAAI,CAAC;AACjB,CAAC"}
|
package/dist/nextjs/index.d.ts
CHANGED
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* their existing auth system (typically hazo_auth's hazo_get_tenant_auth)
|
|
6
6
|
* without a hard module dep at this layer.
|
|
7
7
|
*
|
|
8
|
+
* Every handler wraps its body with hazo_core's `withContext` so the
|
|
9
|
+
* correlation ID flows through every nested log call and downstream
|
|
10
|
+
* `fetchWithRequestId` outbound request. Errors are routed through
|
|
11
|
+
* `handleError()` which is HazoError-aware: 5xx → logger.error, 4xx →
|
|
12
|
+
* logger.warn.
|
|
13
|
+
*
|
|
8
14
|
* Mounting (Next.js App Router):
|
|
9
15
|
*
|
|
10
16
|
* // app/api/audit/events/route.ts
|
|
@@ -46,6 +52,7 @@ export interface AuditRequest extends Request {
|
|
|
46
52
|
nextUrl?: URL;
|
|
47
53
|
}
|
|
48
54
|
import type { HazoConnectAdapter } from 'hazo_connect';
|
|
55
|
+
import { type Logger } from '../utils/logger.js';
|
|
49
56
|
export interface AuditAuth {
|
|
50
57
|
user_id: string;
|
|
51
58
|
scope_id: string | null;
|
|
@@ -65,6 +72,11 @@ export interface AuditEventsRoutesOptions {
|
|
|
65
72
|
/** Default page size for list. Defaults to 50, capped at 200. */
|
|
66
73
|
default_limit?: number;
|
|
67
74
|
max_limit?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Optional logger override. Defaults to `get_logger()` (hazo_core's
|
|
77
|
+
* `createLogger('hazo_audit')`).
|
|
78
|
+
*/
|
|
79
|
+
logger?: Logger;
|
|
68
80
|
}
|
|
69
81
|
type NextHandler = (req: AuditRequest, ctx?: {
|
|
70
82
|
params: Promise<Record<string, string>> | Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nextjs/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/nextjs/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C;;;;;GAKG;AACH,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAA;KAAE,CAAC;IAC/D,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AACD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAWvD,OAAO,EAA0B,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,kBAAkB,CAAC;IAClC,qEAAqE;IACrE,OAAO,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC;IAC7E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,KAAK,WAAW,GAAG,CACjB,GAAG,EAAE,YAAY,EACjB,GAAG,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,KACvE,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,WAAW,CAAC;IACjB,MAAM,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAC9B,MAAM,EAAE;QAAE,GAAG,EAAE,WAAW,CAAA;KAAE,CAAC;CAC9B;AAqED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,iBAAiB,CA4TnB"}
|