@groundbrick/audit-service 1.1.3 → 1.2.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/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @groundbrick/audit-service
2
+
3
+ Pluggable audit service for asynchronously recording audit events. Designed for multi-tenant applications with a provider-based architecture that allows swapping storage backends.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @groundbrick/audit-service
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { AuditService, DatabaseAuditProvider } from '@groundbrick/audit-service';
15
+
16
+ // 1. Create a provider with your database query executor
17
+ const provider = new DatabaseAuditProvider(async (query, params) => {
18
+ await db.query(query, params);
19
+ });
20
+
21
+ // 2. Get the singleton instance
22
+ const auditService = AuditService.getInstance(provider);
23
+
24
+ // 3. Log events (fire-and-forget, non-blocking)
25
+ auditService.log({
26
+ actorId: '42',
27
+ tenantId: '1',
28
+ action: 'CREATE',
29
+ entity: 'USER',
30
+ entityId: '100',
31
+ newValue: { name: 'John Doe', email: 'john@example.com' },
32
+ });
33
+ ```
34
+
35
+ ## Database Schema
36
+
37
+ The `DatabaseAuditProvider` expects an `audit_logs` table with the following structure:
38
+
39
+ ```sql
40
+ CREATE TABLE audit_logs (
41
+ id SERIAL PRIMARY KEY,
42
+ actor_id VARCHAR NOT NULL,
43
+ tenant_id VARCHAR NOT NULL,
44
+ action VARCHAR NOT NULL,
45
+ entity VARCHAR NOT NULL,
46
+ entity_id VARCHAR NOT NULL,
47
+ old_value JSONB,
48
+ new_value JSONB,
49
+ metadata JSONB,
50
+ "timestamp" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
51
+ );
52
+ ```
53
+
54
+ ## API
55
+
56
+ ### `AuditService`
57
+
58
+ Singleton service that delegates event persistence to a provider.
59
+
60
+ | Method | Description |
61
+ |---|---|
62
+ | `AuditService.getInstance(provider)` | Returns the singleton instance, initializing it with the given provider on first call. |
63
+ | `auditService.log(event)` | Logs an audit event asynchronously (fire-and-forget). Errors are caught and logged to `console.error`. |
64
+
65
+ ### `AuditEvent`
66
+
67
+ ```typescript
68
+ interface AuditEvent {
69
+ actorId: string; // Who performed the action (user ID or 'system')
70
+ tenantId: string; // Tenant/organization the action belongs to
71
+ action: AuditAction; // What happened
72
+ entity: string; // Affected entity type (e.g. 'USER', 'ORDER')
73
+ entityId: string; // ID of the affected entity
74
+ oldValue?: any | null; // Previous state (UPDATE, DELETE)
75
+ newValue?: any | null; // New state (CREATE, UPDATE)
76
+ timestamp?: Date; // Auto-generated if not provided
77
+ metadata?: Record<string, any>; // Additional context (IP, user-agent, etc.)
78
+ }
79
+ ```
80
+
81
+ ### `AuditAction`
82
+
83
+ ```typescript
84
+ type AuditAction = 'CREATE' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT';
85
+ ```
86
+
87
+ ### `IAuditProvider`
88
+
89
+ Interface for implementing custom storage backends.
90
+
91
+ ```typescript
92
+ interface IAuditProvider {
93
+ save(event: AuditEvent): Promise<void>;
94
+ }
95
+ ```
96
+
97
+ ### `DatabaseAuditProvider`
98
+
99
+ Built-in provider that persists events to a SQL database via a query executor function.
100
+
101
+ ```typescript
102
+ const provider = new DatabaseAuditProvider(
103
+ async (query: string, params: any[]) => {
104
+ await pool.query(query, params);
105
+ }
106
+ );
107
+ ```
108
+
109
+ ## Custom Provider
110
+
111
+ Implement `IAuditProvider` to use any storage backend:
112
+
113
+ ```typescript
114
+ import { IAuditProvider, AuditEvent } from '@groundbrick/audit-service';
115
+
116
+ class RedisAuditProvider implements IAuditProvider {
117
+ constructor(private redis: RedisClient) {}
118
+
119
+ async save(event: AuditEvent): Promise<void> {
120
+ await this.redis.lpush('audit:logs', JSON.stringify(event));
121
+ }
122
+ }
123
+ ```
124
+
125
+ ## License
126
+
127
+ MIT
@@ -4,14 +4,14 @@ export class DatabaseAuditProvider {
4
4
  this.executeQuery = executeQuery;
5
5
  }
6
6
  async save(event) {
7
- const { actorId, petshopId, action, entity, entityId, oldValue, newValue, metadata, } = event;
7
+ const { actorId, tenantId, action, entity, entityId, oldValue, newValue, metadata, } = event;
8
8
  const query = `
9
- INSERT INTO audit_logs (actor_id, petshop_id, action, entity, entity_id, old_value, new_value, metadata, "timestamp")
9
+ INSERT INTO audit_logs (actor_id, tenant_id, action, entity, entity_id, old_value, new_value, metadata, "timestamp")
10
10
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
11
11
  `;
12
12
  const params = [
13
13
  actorId,
14
- petshopId,
14
+ tenantId,
15
15
  action,
16
16
  entity,
17
17
  entityId,
package/dist/types.d.ts CHANGED
@@ -2,8 +2,8 @@ export type AuditAction = 'CREATE' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT';
2
2
  export interface AuditEvent {
3
3
  /** ID do usuário ou sistema que realizou a ação. */
4
4
  actorId: string;
5
- /** ID do petshop ao qual a ação está associada. */
6
- petshopId: string;
5
+ /** ID do tenant (organização/empresa) ao qual a ação está associada. */
6
+ tenantId: string;
7
7
  /** A ação que foi realizada. */
8
8
  action: AuditAction;
9
9
  /** A entidade que foi afetada. Ex: 'PET', 'APPOINTMENT', 'USER'. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,MAAM,EAAE,WAAW,CAAC;IACpB,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,wEAAwE;IACxE,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@groundbrick/audit-service",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "Serviço de auditoria plugável para registrar eventos de log de forma assíncrona.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",