@venturekit-pro/audit 0.0.0-dev.20260701100017 → 0.0.1
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.
|
@@ -60,7 +60,7 @@ $$;
|
|
|
60
60
|
|
|
61
61
|
-- ─── audit_events ───────────────────────────────────────────────────
|
|
62
62
|
|
|
63
|
-
CREATE TABLE IF NOT EXISTS
|
|
63
|
+
CREATE TABLE IF NOT EXISTS vk_audit_events (
|
|
64
64
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
65
65
|
-- tenant_id is nullable so we can record platform-wide events
|
|
66
66
|
-- (e.g. cron sweeps that fan out across every tenant). Per-tenant
|
|
@@ -110,25 +110,25 @@ CREATE TABLE IF NOT EXISTS audit_events (
|
|
|
110
110
|
|
|
111
111
|
-- Main page query: "show me the last N events for this tenant".
|
|
112
112
|
CREATE INDEX IF NOT EXISTS audit_events_tenant_created_idx
|
|
113
|
-
ON
|
|
113
|
+
ON vk_audit_events (tenant_id, created_at DESC);
|
|
114
114
|
|
|
115
115
|
-- Filtered list: "show me the last N 'order.refunded' events".
|
|
116
116
|
CREATE INDEX IF NOT EXISTS audit_events_tenant_kind_idx
|
|
117
|
-
ON
|
|
117
|
+
ON vk_audit_events (tenant_id, kind, created_at DESC);
|
|
118
118
|
|
|
119
119
|
-- Per-entity history: "every event touching blog_post X".
|
|
120
120
|
CREATE INDEX IF NOT EXISTS audit_events_target_idx
|
|
121
|
-
ON
|
|
121
|
+
ON vk_audit_events (tenant_id, target_type, target_id, created_at DESC);
|
|
122
122
|
|
|
123
123
|
-- Correlation join: "every event in this workflow run".
|
|
124
124
|
CREATE INDEX IF NOT EXISTS audit_events_correlation_idx
|
|
125
|
-
ON
|
|
125
|
+
ON vk_audit_events (correlation_id, created_at DESC)
|
|
126
126
|
WHERE correlation_id IS NOT NULL;
|
|
127
127
|
|
|
128
128
|
-- Idempotency dedup. Partial because the vast majority of rows
|
|
129
129
|
-- have idempotency_key = NULL.
|
|
130
130
|
CREATE UNIQUE INDEX IF NOT EXISTS audit_events_idempotency_unique
|
|
131
|
-
ON
|
|
131
|
+
ON vk_audit_events (idempotency_key)
|
|
132
132
|
WHERE idempotency_key IS NOT NULL;
|
|
133
133
|
|
|
134
134
|
-- ─── Append-only enforcement at the storage layer ───────────────────
|
|
@@ -145,8 +145,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS audit_events_idempotency_unique
|
|
|
145
145
|
-- granted UPDATE/DELETE. Apps that grant their runtime role
|
|
146
146
|
-- `ALL PRIVILEGES` on the schema must re-revoke after this migration.
|
|
147
147
|
|
|
148
|
-
REVOKE UPDATE, DELETE ON
|
|
148
|
+
REVOKE UPDATE, DELETE ON vk_audit_events FROM PUBLIC;
|
|
149
149
|
|
|
150
150
|
-- A convenience GRANT so the app role still works for inserts and
|
|
151
151
|
-- reads when only PUBLIC's privileges were revoked.
|
|
152
|
-
GRANT SELECT, INSERT ON
|
|
152
|
+
GRANT SELECT, INSERT ON vk_audit_events TO PUBLIC;
|
package/dist/query.js
CHANGED
|
@@ -77,7 +77,7 @@ export async function listEvents(querier, args) {
|
|
|
77
77
|
conditions.push(`id < $${params.length}`);
|
|
78
78
|
}
|
|
79
79
|
params.push(limit);
|
|
80
|
-
return querier(`SELECT * FROM
|
|
80
|
+
return querier(`SELECT * FROM vk_audit_events
|
|
81
81
|
WHERE ${conditions.join(' AND ')}
|
|
82
82
|
ORDER BY created_at DESC, id DESC
|
|
83
83
|
LIMIT $${params.length}`, params);
|
|
@@ -100,7 +100,7 @@ export async function countEvents(querier, args) {
|
|
|
100
100
|
}
|
|
101
101
|
const prefixes = normalizePrefixes(args.byKindPrefix);
|
|
102
102
|
const rows = await querier(`SELECT ${buildCountSelect(prefixes)}
|
|
103
|
-
FROM
|
|
103
|
+
FROM vk_audit_events
|
|
104
104
|
WHERE ${conditions.join(' AND ')}`, params);
|
|
105
105
|
return rowToCount(rows[0], prefixes);
|
|
106
106
|
}
|
|
@@ -122,7 +122,7 @@ export async function monthlyEventCounts(querier, args) {
|
|
|
122
122
|
to_char(months.month_start, 'YYYY-MM-DD') AS "month",
|
|
123
123
|
${buildCountSelect(prefixes, 'a')}
|
|
124
124
|
FROM months
|
|
125
|
-
LEFT JOIN
|
|
125
|
+
LEFT JOIN vk_audit_events a
|
|
126
126
|
ON a.tenant_id = $1
|
|
127
127
|
AND a.created_at >= months.month_start
|
|
128
128
|
AND a.created_at < months.month_start + interval '1 month'
|
package/dist/record.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function record(querier, input) {
|
|
|
32
32
|
// node-postgres.
|
|
33
33
|
const payload = sanitizePayload(input.payload);
|
|
34
34
|
const sql = `
|
|
35
|
-
INSERT INTO
|
|
35
|
+
INSERT INTO vk_audit_events (
|
|
36
36
|
tenant_id,
|
|
37
37
|
actor_type,
|
|
38
38
|
actor_id,
|
|
@@ -81,7 +81,7 @@ export async function record(querier, input) {
|
|
|
81
81
|
isIdempotencyConstraint(err)) {
|
|
82
82
|
// Retried call with the same idempotency key — return the
|
|
83
83
|
// pre-existing row so the caller sees a stable outcome.
|
|
84
|
-
const existing = await querier(`SELECT * FROM
|
|
84
|
+
const existing = await querier(`SELECT * FROM vk_audit_events WHERE idempotency_key = $1 LIMIT 1`, [input.idempotencyKey]);
|
|
85
85
|
if (existing[0])
|
|
86
86
|
return existing[0];
|
|
87
87
|
}
|
package/dist/record.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAgB,EAChB,KAAsB;IAEtB,2DAA2D;IAC3D,0DAA0D;IAC1D,iEAAiE;IACjE,iBAAiB;IACjB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;GAmBX,CAAC;IAEF,MAAM,MAAM,GAAc;QACxB,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,KAAK,CAAC,IAAI;QAChB,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI;QACtB,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI;QAC1B,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI;QACxB,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI;QAC1B,KAAK,CAAC,MAAM,IAAI,WAAW;QAC3B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QACvB,KAAK,CAAC,aAAa,IAAI,IAAI;QAC3B,KAAK,CAAC,cAAc,IAAI,IAAI;QAC5B,KAAK,CAAC,YAAY,IAAI,IAAI;KAC3B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAe,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,0DAA0D;YAC1D,6DAA6D;YAC7D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IACE,KAAK,CAAC,cAAc;YACpB,iBAAiB,CAAC,GAAG,CAAC;YACtB,uBAAuB,CAAC,GAAG,CAAC,EAC5B,CAAC;YACD,0DAA0D;YAC1D,wDAAwD;YACxD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,OAAgB,EAChB,KAAsB;IAEtB,2DAA2D;IAC3D,0DAA0D;IAC1D,iEAAiE;IACjE,iBAAiB;IACjB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;GAmBX,CAAC;IAEF,MAAM,MAAM,GAAc;QACxB,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,KAAK,CAAC,IAAI;QAChB,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI;QACtB,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI;QAC1B,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI;QACxB,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI;QAC1B,KAAK,CAAC,MAAM,IAAI,WAAW;QAC3B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QACvB,KAAK,CAAC,aAAa,IAAI,IAAI;QAC3B,KAAK,CAAC,cAAc,IAAI,IAAI;QAC5B,KAAK,CAAC,YAAY,IAAI,IAAI;KAC3B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAe,GAAG,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,0DAA0D;YAC1D,6DAA6D;YAC7D,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IACE,KAAK,CAAC,cAAc;YACpB,iBAAiB,CAAC,GAAG,CAAC;YACtB,uBAAuB,CAAC,GAAG,CAAC,EAC5B,CAAC;YACD,0DAA0D;YAC1D,wDAAwD;YACxD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,kEAAkE,EAClE,CAAC,KAAK,CAAC,cAAc,CAAC,CACvB,CAAC;YACF,IAAI,QAAQ,CAAC,CAAC,CAAC;gBAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,uEAAuE;AAEvE,SAAS,eAAe,CAAC,OAAgB;IACvC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC5B,CAAC;IACD,8DAA8D;IAC9D,+DAA+D;IAC/D,2BAA2B;IAC3B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,GAAY;IACrC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,IAAI,GAAI,GAAyB,CAAC,IAAI,CAAC;IAC7C,OAAO,IAAI,KAAK,OAAO,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,SAAS,uBAAuB,CAAC,GAAY;IAC3C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,CAAC,GAAG,GAA+C,CAAC;IAC1D,IAAI,CAAC,CAAC,UAAU,KAAK,iCAAiC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/retention.js
CHANGED
|
@@ -32,15 +32,15 @@ export async function pruneAuditEvents(querier, options) {
|
|
|
32
32
|
// doesn't blow out a single transaction on a giant table.
|
|
33
33
|
const sql = `
|
|
34
34
|
WITH victims AS (
|
|
35
|
-
SELECT id FROM
|
|
35
|
+
SELECT id FROM vk_audit_events
|
|
36
36
|
WHERE ${conditions.join(' AND ')}
|
|
37
37
|
ORDER BY created_at ASC
|
|
38
38
|
LIMIT $${params.length}
|
|
39
39
|
)
|
|
40
|
-
DELETE FROM
|
|
40
|
+
DELETE FROM vk_audit_events
|
|
41
41
|
USING victims
|
|
42
|
-
WHERE
|
|
43
|
-
RETURNING
|
|
42
|
+
WHERE vk_audit_events.id = victims.id
|
|
43
|
+
RETURNING vk_audit_events.id
|
|
44
44
|
`;
|
|
45
45
|
const rows = await querier(sql, params);
|
|
46
46
|
return rows.length;
|
|
@@ -63,7 +63,7 @@ export async function previewPrune(querier, options) {
|
|
|
63
63
|
}
|
|
64
64
|
params.push(batchSize);
|
|
65
65
|
return querier(`SELECT id, created_at AS "createdAt", tenant_id AS "tenantId", kind
|
|
66
|
-
FROM
|
|
66
|
+
FROM vk_audit_events
|
|
67
67
|
WHERE ${conditions.join(' AND ')}
|
|
68
68
|
ORDER BY created_at ASC
|
|
69
69
|
LIMIT $${params.length}`, params);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venturekit-pro/audit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.1",
|
|
4
4
|
"description": "Append-only audit + cost-tracking log for VentureKit applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"compliance"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@venturekit/core": "0.0.
|
|
40
|
+
"@venturekit/core": "0.0.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@venturekit/data": "0.0.
|
|
43
|
+
"@venturekit/data": "0.0.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependenciesMeta": {
|
|
46
46
|
"@venturekit/data": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/node": "^25.6.0",
|
|
52
|
-
"@venturekit/data": "0.0.
|
|
52
|
+
"@venturekit/data": "0.0.1",
|
|
53
53
|
"typescript": "^5.3.0"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
@@ -60,7 +60,7 @@ $$;
|
|
|
60
60
|
|
|
61
61
|
-- ─── audit_events ───────────────────────────────────────────────────
|
|
62
62
|
|
|
63
|
-
CREATE TABLE IF NOT EXISTS
|
|
63
|
+
CREATE TABLE IF NOT EXISTS vk_audit_events (
|
|
64
64
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
65
65
|
-- tenant_id is nullable so we can record platform-wide events
|
|
66
66
|
-- (e.g. cron sweeps that fan out across every tenant). Per-tenant
|
|
@@ -110,25 +110,25 @@ CREATE TABLE IF NOT EXISTS audit_events (
|
|
|
110
110
|
|
|
111
111
|
-- Main page query: "show me the last N events for this tenant".
|
|
112
112
|
CREATE INDEX IF NOT EXISTS audit_events_tenant_created_idx
|
|
113
|
-
ON
|
|
113
|
+
ON vk_audit_events (tenant_id, created_at DESC);
|
|
114
114
|
|
|
115
115
|
-- Filtered list: "show me the last N 'order.refunded' events".
|
|
116
116
|
CREATE INDEX IF NOT EXISTS audit_events_tenant_kind_idx
|
|
117
|
-
ON
|
|
117
|
+
ON vk_audit_events (tenant_id, kind, created_at DESC);
|
|
118
118
|
|
|
119
119
|
-- Per-entity history: "every event touching blog_post X".
|
|
120
120
|
CREATE INDEX IF NOT EXISTS audit_events_target_idx
|
|
121
|
-
ON
|
|
121
|
+
ON vk_audit_events (tenant_id, target_type, target_id, created_at DESC);
|
|
122
122
|
|
|
123
123
|
-- Correlation join: "every event in this workflow run".
|
|
124
124
|
CREATE INDEX IF NOT EXISTS audit_events_correlation_idx
|
|
125
|
-
ON
|
|
125
|
+
ON vk_audit_events (correlation_id, created_at DESC)
|
|
126
126
|
WHERE correlation_id IS NOT NULL;
|
|
127
127
|
|
|
128
128
|
-- Idempotency dedup. Partial because the vast majority of rows
|
|
129
129
|
-- have idempotency_key = NULL.
|
|
130
130
|
CREATE UNIQUE INDEX IF NOT EXISTS audit_events_idempotency_unique
|
|
131
|
-
ON
|
|
131
|
+
ON vk_audit_events (idempotency_key)
|
|
132
132
|
WHERE idempotency_key IS NOT NULL;
|
|
133
133
|
|
|
134
134
|
-- ─── Append-only enforcement at the storage layer ───────────────────
|
|
@@ -145,8 +145,8 @@ CREATE UNIQUE INDEX IF NOT EXISTS audit_events_idempotency_unique
|
|
|
145
145
|
-- granted UPDATE/DELETE. Apps that grant their runtime role
|
|
146
146
|
-- `ALL PRIVILEGES` on the schema must re-revoke after this migration.
|
|
147
147
|
|
|
148
|
-
REVOKE UPDATE, DELETE ON
|
|
148
|
+
REVOKE UPDATE, DELETE ON vk_audit_events FROM PUBLIC;
|
|
149
149
|
|
|
150
150
|
-- A convenience GRANT so the app role still works for inserts and
|
|
151
151
|
-- reads when only PUBLIC's privileges were revoked.
|
|
152
|
-
GRANT SELECT, INSERT ON
|
|
152
|
+
GRANT SELECT, INSERT ON vk_audit_events TO PUBLIC;
|