npm package: @groundbrick/audit-service
Description: Serviço de auditoria plugável para registrar eventos de log de forma assíncrona.
Author: GroundBrick
Latest version: 1.2.0

# @groundbrick/audit-service

Pluggable audit service for asynchronously recording audit events. Designed for multi-tenant applications with a provider-based architecture that allows swapping storage backends.

## Installation

```bash
npm install @groundbrick/audit-service
```

## Quick Start

```typescript
import { AuditService, DatabaseAuditProvider } from '@groundbrick/audit-service';

// 1. Create a provider with your database query executor
const provider = new DatabaseAuditProvider(async (query, params) => {
  await db.query(query, params);
});

// 2. Get the singleton instance
const auditService = AuditService.getInstance(provider);

// 3. Log events (fire-and-forget, non-blocking)
auditService.log({
  actorId: '42',
  tenantId: '1',
  action: 'CREATE',
  entity: 'USER',
  entityId: '100',
  newValue: { name: 'John Doe', email: 'john@example.com' },
});
```

## Database Schema

The `DatabaseAuditProvider` expects an `audit_logs` table with the following structure:

```sql
CREATE TABLE audit_logs (
  id SERIAL PRIMARY KEY,
  actor_id VARCHAR NOT NULL,
  tenant_id VARCHAR NOT NULL,
  action VARCHAR NOT NULL,
  entity VARCHAR NOT NULL,
  entity_id VARCHAR NOT NULL,
  old_value JSONB,
  new_value JSONB,
  metadata JSONB,
  "timestamp" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```

## API

### `AuditService`

Singleton service that delegates event persistence to a provider.

| Method | Description |
|---|---|
| `AuditService.getInstance(provider)` | Returns the singleton instance, initializing it with the given provider on first call. |
| `auditService.log(event)` | Logs an audit event asynchronously (fire-and-forget). Errors are caught and logged to `console.error`. |

### `AuditEvent`

```typescript
interface AuditEvent {
  actorId: string;                // Who performed the action (user ID or 'system')
  tenantId: string;               // Tenant/organization the action belongs to
  action: AuditAction;            // What happened
  entity: string;                 // Affected entity type (e.g. 'USER', 'ORDER')
  entityId: string;               // ID of the affected entity
  oldValue?: any | null;          // Previous state (UPDATE, DELETE)
  newValue?: any | null;          // New state (CREATE, UPDATE)
  timestamp?: Date;               // Auto-generated if not provided
  metadata?: Record<string, any>; // Additional context (IP, user-agent, etc.)
}
```

### `AuditAction`

```typescript
type AuditAction = 'CREATE' | 'UPDATE' | 'DELETE' | 'LOGIN' | 'LOGOUT';
```

### `IAuditProvider`

Interface for implementing custom storage backends.

```typescript
interface IAuditProvider {
  save(event: AuditEvent): Promise<void>;
}
```

### `DatabaseAuditProvider`

Built-in provider that persists events to a SQL database via a query executor function.

```typescript
const provider = new DatabaseAuditProvider(
  async (query: string, params: any[]) => {
    await pool.query(query, params);
  }
);
```

## Custom Provider

Implement `IAuditProvider` to use any storage backend:

```typescript
import { IAuditProvider, AuditEvent } from '@groundbrick/audit-service';

class RedisAuditProvider implements IAuditProvider {
  constructor(private redis: RedisClient) {}

  async save(event: AuditEvent): Promise<void> {
    await this.redis.lpush('audit:logs', JSON.stringify(event));
  }
}
```

## License

MIT