@contractspec/module.audit-trail 1.44.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.
@@ -0,0 +1,88 @@
1
+ import { AuditQueryOptions, AuditRecord, AuditStorage } from "@contractspec/lib.bus";
2
+
3
+ //#region src/storage/index.d.ts
4
+
5
+ /**
6
+ * Extended query options for audit storage.
7
+ */
8
+ interface ExtendedAuditQueryOptions extends AuditQueryOptions {
9
+ targetType?: string;
10
+ clientIp?: string;
11
+ sessionId?: string;
12
+ orderBy?: 'occurredAt' | 'recordedAt';
13
+ orderDir?: 'asc' | 'desc';
14
+ }
15
+ /**
16
+ * Audit storage adapter interface with extended capabilities.
17
+ */
18
+ interface AuditStorageAdapter extends AuditStorage {
19
+ /** Query audit records with extended options */
20
+ query(options: ExtendedAuditQueryOptions): Promise<AuditRecord[]>;
21
+ /** Count matching records */
22
+ count(options: Omit<ExtendedAuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
23
+ /** Get a single record by ID */
24
+ getById(id: string): Promise<AuditRecord | null>;
25
+ /** Get all records for a trace */
26
+ getByTraceId(traceId: string): Promise<AuditRecord[]>;
27
+ /** Delete old records (for retention) */
28
+ deleteOlderThan(date: Date): Promise<number>;
29
+ }
30
+ /**
31
+ * In-memory audit storage for development/testing.
32
+ */
33
+ declare class InMemoryAuditStorage implements AuditStorageAdapter {
34
+ private records;
35
+ store(record: AuditRecord): Promise<void>;
36
+ query(options: ExtendedAuditQueryOptions): Promise<AuditRecord[]>;
37
+ count(options: Omit<ExtendedAuditQueryOptions, 'limit' | 'offset'>): Promise<number>;
38
+ getById(id: string): Promise<AuditRecord | null>;
39
+ getByTraceId(traceId: string): Promise<AuditRecord[]>;
40
+ deleteOlderThan(date: Date): Promise<number>;
41
+ /**
42
+ * Get all records (for testing).
43
+ */
44
+ getAll(): AuditRecord[];
45
+ /**
46
+ * Clear all records (for testing).
47
+ */
48
+ clear(): void;
49
+ }
50
+ /**
51
+ * Retention policy configuration.
52
+ */
53
+ interface RetentionPolicyConfig {
54
+ /** Days to keep detailed logs */
55
+ hotRetentionDays: number;
56
+ /** Days to keep archived logs (for compliance) */
57
+ archiveRetentionDays?: number;
58
+ /** Cron expression for cleanup schedule */
59
+ cleanupSchedule?: string;
60
+ }
61
+ /**
62
+ * Retention policy manager.
63
+ */
64
+ declare class RetentionPolicy {
65
+ private readonly config;
66
+ constructor(config: RetentionPolicyConfig);
67
+ /**
68
+ * Get the cutoff date for hot storage.
69
+ */
70
+ getHotCutoff(): Date;
71
+ /**
72
+ * Get the cutoff date for archive storage.
73
+ */
74
+ getArchiveCutoff(): Date | null;
75
+ /**
76
+ * Apply retention policy to storage.
77
+ */
78
+ apply(storage: AuditStorageAdapter): Promise<{
79
+ deletedCount: number;
80
+ }>;
81
+ }
82
+ /**
83
+ * Create an in-memory audit storage.
84
+ */
85
+ declare function createInMemoryAuditStorage(): InMemoryAuditStorage;
86
+ //#endregion
87
+ export { AuditStorageAdapter, ExtendedAuditQueryOptions, InMemoryAuditStorage, RetentionPolicy, RetentionPolicyConfig, createInMemoryAuditStorage };
88
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/storage/index.ts"],"sourcesContent":[],"mappings":";;;;;;AASA;AAWiB,UAXA,yBAAA,SAAkC,iBAWd,CAAA;EAEpB,UAAA,CAAA,EAAA,MAAA;EAAoC,QAAA,CAAA,EAAA,MAAA;EAAR,SAAA,CAAA,EAAA,MAAA;EAG3B,OAAA,CAAA,EAAA,YAAA,GAAA,YAAA;EAAL,QAAA,CAAA,EAAA,KAAA,GAAA,MAAA;;;;;AAKoB,UAVhB,mBAAA,SAA4B,YAUZ,CAAA;EAET;EAAO,KAAA,CAAA,OAAA,EAVd,yBAUc,CAAA,EAVc,OAUd,CAVsB,WAUtB,EAAA,CAAA;EAZc;EAAY,KAAA,CAAA,OAAA,EAK5C,IAL4C,CAKvC,yBALuC,EAAA,OAAA,GAAA,QAAA,CAAA,CAAA,EAMpD,OANoD,CAAA,MAAA,CAAA;EAkB5C;EAGS,OAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAbC,OAaD,CAbS,WAaT,GAAA,IAAA,CAAA;EAAc;EAIb,YAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAfU,OAeV,CAfkB,WAelB,EAAA,CAAA;EAAoC;EAAR,eAAA,CAAA,IAAA,EAb3B,IAa2B,CAAA,EAbpB,OAaoB,CAAA,MAAA,CAAA;;;;;AAwEtB,cA/EhB,oBAAA,YAAgC,mBA+EhB,CAAA;EAIkB,QAAA,OAAA;EAAR,KAAA,CAAA,MAAA,EAhFjB,WAgFiB,CAAA,EAhFH,OAgFG,CAAA,IAAA,CAAA;EAIT,KAAA,CAAA,OAAA,EAhFP,yBAgFO,CAAA,EAhFqB,OAgFrB,CAhF6B,WAgF7B,EAAA,CAAA;EAAO,KAAA,CAAA,OAAA,EAdxB,IAcwB,CAdnB,yBAcmB,EAAA,OAAA,GAAA,QAAA,CAAA,CAAA,EAbhC,OAagC,CAAA,MAAA,CAAA;EASzB,OAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAjBiB,OAiBjB,CAjByB,WAiBzB,GAAA,IAAA,CAAA;EAhGiC,YAAA,CAAA,OAAA,EAAA,MAAA,CAAA,EAmFN,OAnFM,CAmFE,WAnFF,EAAA,CAAA;EAAmB,eAAA,CAAA,IAAA,EAuFlC,IAvFkC,CAAA,EAuF3B,OAvF2B,CAAA,MAAA,CAAA;EA+G/C;AAYjB;;EAMkB,MAAA,CAAA,CAAA,EAjCN,WAiCM,EAAA;EASI;;;EAU8B,KAAA,CAAA,CAAA,EAAA,IAAA;AAYpD;;;;UAjDiB,qBAAA;;;;;;;;;;;cAYJ,eAAA;;sBAC0B;;;;kBAKrB;;;;sBASI;;;;iBAUC,sBAAsB;;;;;;;iBAY7B,0BAAA,CAAA,GAA8B"}
@@ -0,0 +1,112 @@
1
+ //#region src/storage/index.ts
2
+ /**
3
+ * In-memory audit storage for development/testing.
4
+ */
5
+ var InMemoryAuditStorage = class {
6
+ records = [];
7
+ async store(record) {
8
+ this.records.push(record);
9
+ }
10
+ async query(options) {
11
+ let results = [...this.records];
12
+ if (options.eventKey) {
13
+ const pattern = options.eventKey.replace(/\*/g, ".*");
14
+ const regex = /* @__PURE__ */ new RegExp(`^${pattern}$`);
15
+ results = results.filter((r) => regex.test(r.eventKey));
16
+ }
17
+ if (options.actorId) results = results.filter((r) => r.metadata?.actorId === options.actorId);
18
+ if (options.targetId) results = results.filter((r) => r.metadata?.targetId === options.targetId);
19
+ if (options.targetType) results = results.filter((r) => r.metadata?.targetType === options.targetType);
20
+ if (options.orgId) results = results.filter((r) => r.metadata?.orgId === options.orgId);
21
+ if (options.traceId) results = results.filter((r) => r.traceId === options.traceId);
22
+ if (options.from) {
23
+ const fromDate = options.from;
24
+ results = results.filter((r) => new Date(r.occurredAt) >= fromDate);
25
+ }
26
+ if (options.to) {
27
+ const toDate = options.to;
28
+ results = results.filter((r) => new Date(r.occurredAt) <= toDate);
29
+ }
30
+ const orderBy = options.orderBy ?? "occurredAt";
31
+ const orderDir = options.orderDir ?? "desc";
32
+ results.sort((a, b) => {
33
+ const aTime = orderBy === "occurredAt" ? new Date(a.occurredAt).getTime() : a.recordedAt.getTime();
34
+ const bTime = orderBy === "occurredAt" ? new Date(b.occurredAt).getTime() : b.recordedAt.getTime();
35
+ return orderDir === "desc" ? bTime - aTime : aTime - bTime;
36
+ });
37
+ const offset = options.offset ?? 0;
38
+ const limit = options.limit ?? 100;
39
+ return results.slice(offset, offset + limit);
40
+ }
41
+ async count(options) {
42
+ return (await this.query({
43
+ ...options,
44
+ limit: Infinity
45
+ })).length;
46
+ }
47
+ async getById(id) {
48
+ return this.records.find((r) => r.id === id) ?? null;
49
+ }
50
+ async getByTraceId(traceId) {
51
+ return this.query({ traceId });
52
+ }
53
+ async deleteOlderThan(date) {
54
+ const before = this.records.length;
55
+ this.records = this.records.filter((r) => new Date(r.occurredAt) >= date);
56
+ return before - this.records.length;
57
+ }
58
+ /**
59
+ * Get all records (for testing).
60
+ */
61
+ getAll() {
62
+ return [...this.records];
63
+ }
64
+ /**
65
+ * Clear all records (for testing).
66
+ */
67
+ clear() {
68
+ this.records = [];
69
+ }
70
+ };
71
+ /**
72
+ * Retention policy manager.
73
+ */
74
+ var RetentionPolicy = class {
75
+ constructor(config) {
76
+ this.config = config;
77
+ }
78
+ /**
79
+ * Get the cutoff date for hot storage.
80
+ */
81
+ getHotCutoff() {
82
+ const cutoff = /* @__PURE__ */ new Date();
83
+ cutoff.setDate(cutoff.getDate() - this.config.hotRetentionDays);
84
+ return cutoff;
85
+ }
86
+ /**
87
+ * Get the cutoff date for archive storage.
88
+ */
89
+ getArchiveCutoff() {
90
+ if (!this.config.archiveRetentionDays) return null;
91
+ const cutoff = /* @__PURE__ */ new Date();
92
+ cutoff.setDate(cutoff.getDate() - this.config.archiveRetentionDays);
93
+ return cutoff;
94
+ }
95
+ /**
96
+ * Apply retention policy to storage.
97
+ */
98
+ async apply(storage) {
99
+ const cutoff = this.getHotCutoff();
100
+ return { deletedCount: await storage.deleteOlderThan(cutoff) };
101
+ }
102
+ };
103
+ /**
104
+ * Create an in-memory audit storage.
105
+ */
106
+ function createInMemoryAuditStorage() {
107
+ return new InMemoryAuditStorage();
108
+ }
109
+
110
+ //#endregion
111
+ export { InMemoryAuditStorage, RetentionPolicy, createInMemoryAuditStorage };
112
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["config: RetentionPolicyConfig"],"sources":["../../src/storage/index.ts"],"sourcesContent":["import type {\n AuditRecord,\n AuditQueryOptions,\n AuditStorage,\n} from '@contractspec/lib.bus';\n\n/**\n * Extended query options for audit storage.\n */\nexport interface ExtendedAuditQueryOptions extends AuditQueryOptions {\n targetType?: string;\n clientIp?: string;\n sessionId?: string;\n orderBy?: 'occurredAt' | 'recordedAt';\n orderDir?: 'asc' | 'desc';\n}\n\n/**\n * Audit storage adapter interface with extended capabilities.\n */\nexport interface AuditStorageAdapter extends AuditStorage {\n /** Query audit records with extended options */\n query(options: ExtendedAuditQueryOptions): Promise<AuditRecord[]>;\n /** Count matching records */\n count(\n options: Omit<ExtendedAuditQueryOptions, 'limit' | 'offset'>\n ): Promise<number>;\n /** Get a single record by ID */\n getById(id: string): Promise<AuditRecord | null>;\n /** Get all records for a trace */\n getByTraceId(traceId: string): Promise<AuditRecord[]>;\n /** Delete old records (for retention) */\n deleteOlderThan(date: Date): Promise<number>;\n}\n\n/**\n * In-memory audit storage for development/testing.\n */\nexport class InMemoryAuditStorage implements AuditStorageAdapter {\n private records: AuditRecord[] = [];\n\n async store(record: AuditRecord): Promise<void> {\n this.records.push(record);\n }\n\n async query(options: ExtendedAuditQueryOptions): Promise<AuditRecord[]> {\n let results = [...this.records];\n\n // Apply filters\n if (options.eventKey) {\n const pattern = options.eventKey.replace(/\\*/g, '.*');\n const regex = new RegExp(`^${pattern}$`);\n results = results.filter((r) => regex.test(r.eventKey));\n }\n\n if (options.actorId) {\n results = results.filter((r) => r.metadata?.actorId === options.actorId);\n }\n\n if (options.targetId) {\n results = results.filter(\n (r) => r.metadata?.targetId === options.targetId\n );\n }\n\n if (options.targetType) {\n results = results.filter(\n (r) => r.metadata?.targetType === options.targetType\n );\n }\n\n if (options.orgId) {\n results = results.filter((r) => r.metadata?.orgId === options.orgId);\n }\n\n if (options.traceId) {\n results = results.filter((r) => r.traceId === options.traceId);\n }\n\n if (options.from) {\n const fromDate = options.from;\n results = results.filter((r) => new Date(r.occurredAt) >= fromDate);\n }\n\n if (options.to) {\n const toDate = options.to;\n results = results.filter((r) => new Date(r.occurredAt) <= toDate);\n }\n\n // Sort\n const orderBy = options.orderBy ?? 'occurredAt';\n const orderDir = options.orderDir ?? 'desc';\n results.sort((a, b) => {\n const aTime =\n orderBy === 'occurredAt'\n ? new Date(a.occurredAt).getTime()\n : a.recordedAt.getTime();\n const bTime =\n orderBy === 'occurredAt'\n ? new Date(b.occurredAt).getTime()\n : b.recordedAt.getTime();\n return orderDir === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // Paginate\n const offset = options.offset ?? 0;\n const limit = options.limit ?? 100;\n return results.slice(offset, offset + limit);\n }\n\n async count(\n options: Omit<ExtendedAuditQueryOptions, 'limit' | 'offset'>\n ): Promise<number> {\n const results = await this.query({ ...options, limit: Infinity });\n return results.length;\n }\n\n async getById(id: string): Promise<AuditRecord | null> {\n return this.records.find((r) => r.id === id) ?? null;\n }\n\n async getByTraceId(traceId: string): Promise<AuditRecord[]> {\n return this.query({ traceId });\n }\n\n async deleteOlderThan(date: Date): Promise<number> {\n const before = this.records.length;\n this.records = this.records.filter((r) => new Date(r.occurredAt) >= date);\n return before - this.records.length;\n }\n\n /**\n * Get all records (for testing).\n */\n getAll(): AuditRecord[] {\n return [...this.records];\n }\n\n /**\n * Clear all records (for testing).\n */\n clear(): void {\n this.records = [];\n }\n}\n\n/**\n * Retention policy configuration.\n */\nexport interface RetentionPolicyConfig {\n /** Days to keep detailed logs */\n hotRetentionDays: number;\n /** Days to keep archived logs (for compliance) */\n archiveRetentionDays?: number;\n /** Cron expression for cleanup schedule */\n cleanupSchedule?: string;\n}\n\n/**\n * Retention policy manager.\n */\nexport class RetentionPolicy {\n constructor(private readonly config: RetentionPolicyConfig) {}\n\n /**\n * Get the cutoff date for hot storage.\n */\n getHotCutoff(): Date {\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - this.config.hotRetentionDays);\n return cutoff;\n }\n\n /**\n * Get the cutoff date for archive storage.\n */\n getArchiveCutoff(): Date | null {\n if (!this.config.archiveRetentionDays) return null;\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - this.config.archiveRetentionDays);\n return cutoff;\n }\n\n /**\n * Apply retention policy to storage.\n */\n async apply(storage: AuditStorageAdapter): Promise<{\n deletedCount: number;\n }> {\n const cutoff = this.getHotCutoff();\n const deletedCount = await storage.deleteOlderThan(cutoff);\n return { deletedCount };\n }\n}\n\n/**\n * Create an in-memory audit storage.\n */\nexport function createInMemoryAuditStorage(): InMemoryAuditStorage {\n return new InMemoryAuditStorage();\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@contractspec/module.audit-trail",
3
+ "version": "1.44.0",
4
+ "description": "Audit trail module for tracking and querying system events",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "publish:pkg": "bun publish --tolerate-republish --ignore-scripts --verbose",
10
+ "publish:pkg:canary": "bun publish:pkg --tag canary",
11
+ "build": "bun build:types && bun build:bundle",
12
+ "build:bundle": "tsdown",
13
+ "build:types": "tsc --noEmit",
14
+ "dev": "bun build:bundle --watch",
15
+ "clean": "rimraf dist .turbo",
16
+ "lint": "bun lint:fix",
17
+ "lint:fix": "eslint src --fix",
18
+ "lint:check": "eslint src"
19
+ },
20
+ "dependencies": {
21
+ "@contractspec/lib.schema": "1.44.0",
22
+ "@contractspec/lib.contracts": "1.44.0",
23
+ "@contractspec/lib.bus": "1.44.0",
24
+ "zod": "^4.1.13"
25
+ },
26
+ "devDependencies": {
27
+ "@contractspec/tool.typescript": "1.44.0",
28
+ "@contractspec/tool.tsdown": "1.44.0",
29
+ "typescript": "^5.9.3"
30
+ },
31
+ "exports": {
32
+ ".": "./dist/index.js",
33
+ "./audit-trail.feature": "./dist/audit-trail.feature.js",
34
+ "./contracts": "./dist/contracts/index.js",
35
+ "./entities": "./dist/entities/index.js",
36
+ "./storage": "./dist/storage/index.js",
37
+ "./*": "./*"
38
+ },
39
+ "module": "./dist/index.js",
40
+ "files": [
41
+ "dist",
42
+ "README.md"
43
+ ],
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "exports": {
47
+ ".": "./dist/index.js",
48
+ "./audit-trail.feature": "./dist/audit-trail.feature.js",
49
+ "./contracts": "./dist/contracts/index.js",
50
+ "./entities": "./dist/entities/index.js",
51
+ "./storage": "./dist/storage/index.js",
52
+ "./*": "./*"
53
+ },
54
+ "registry": "https://registry.npmjs.org/"
55
+ },
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/lssm-tech/contractspec.git",
60
+ "directory": "packages/modules/audit-trail"
61
+ },
62
+ "homepage": "https://contractspec.io"
63
+ }