npm package: @imexs/audit-trail
Description: Enterprise-grade Audit Trail Plugin for Node.js with TypeScript - Performance Monitoring, System Integration Audit, Data Accountability & User Activity Tracking with Advanced Security Features
Author: IMEXS
Latest version: 1.0.3

# audit-trail

> Enterprise-grade Audit Trail Plugin for Node.js + TypeScript with Advanced Security Features

[![npm version](https://img.shields.io/npm/v/@imexs/audit-trail.svg)](https://www.npmjs.com/package/@imexs/audit-trail)
[![npm downloads](https://img.shields.io/npm/dm/@imexs/audit-trail.svg)](https://www.npmjs.com/package/@imexs/audit-trail)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16-green.svg)](https://nodejs.org/)
[![Security](https://img.shields.io/badge/Security-AES--256--GCM-red.svg)](#security-features)
[![GDPR](https://img.shields.io/badge/GDPR-Compliant-success.svg)](#compliance)

## Features

### Core Logging
- ***User Activity Tracking*** - Monitor user actions (CREATE, UPDATE, DELETE, READ)
- ***System Integration Audit*** - Log external API calls and third-party services
- ***Data Accountability*** - Track data access for GDPR/compliance
- ***Performance Monitoring*** - Track response times, memory, CPU usage

### Security (Enterprise-Grade)
- ***AES-256-GCM Encryption*** - Data encryption at rest
- ***RBAC*** - Role-based access control (4 roles, 6 permissions)
- ***Rate Limiting*** - DoS protection (per user & IP)
- ***Input Validation*** - SQL injection & XSS prevention
- ***Integrity Checking*** - HMAC-based tamper detection
- ***IP Whitelisting*** - Restrict admin operations

### Production-Ready
- ***Retry Mechanism*** - Exponential backoff for failed operations
- ***Circuit Breaker*** - Prevent cascading failures
- ***Batch Logging*** - Queue-based batch insert (100x faster)
- ***Health Checks*** - Kubernetes liveness/readiness probes
- ***Metrics*** - Prometheus-compatible metrics export
- ***Graceful Shutdown*** - Zero data loss on shutdown

### Developer Experience
- ***Zero Configuration*** - Auto-creates tables on first run
- ***TypeScript*** - Full type definitions
- ***Express Middleware*** - Auto-log HTTP requests (Express 4.x & 5.x compatible)
- ***Axios Interceptor*** - Auto-log API calls

## Installation

```bash
npm install @imexs/audit-trail
```

### Peer Dependencies

```bash
npm install knex pg uuid

# For Express users (v4.x or v5.x)
npm install express

# For Axios users
npm install axios
```

**Note:** This package supports both Express 4.x and Express 5.1.0+

## Quick Start

### Setup in Your Project

#### 1. Setup Environment

Create `.env`:

```env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=audit_trail_db
DB_USER=postgres
DB_PASSWORD=your_password
APP_NAME=example-app

# Security
AUDIT_ENCRYPTION_KEY=  # openssl rand -hex 32
AUDIT_HASH_SALT=       # openssl rand -hex 32
AUDIT_INTEGRITY_KEY=   # openssl rand -hex 32

# Rate Limiting
AUDIT_RATE_LIMIT_POINTS=100
AUDIT_RATE_LIMIT_DURATION=60

# Batch Logging
AUDIT_BATCH_SIZE=100
AUDIT_FLUSH_INTERVAL=5000
```

#### 2. Initialize

```javascript
const auditTrail = require('@imexs/audit-trail');

// Tables auto-created on first use
auditTrail.ConfigManager.getInstance(
  appName: process.env.APP_NAME || 'example-app',
  enabled: process.env.AUDIT_ENABLED || true,
  database: {
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    database: process.env.DB_NAME,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    ssl: process.env.DB_SSL || false
  },
  maskedFields: ['password', 'token', 'credit_card', 'cvv', 'pin'],
  autoFlush: true,
  flushInterval: 5000
);
```

#### 3. Start Logging

```javascript
const express = require('express');
const app = express();

// This function will log all API requests.
app.use(auditTrail.createHttpLogger({
  captureBody: true,
  captureHeaders: true,
  excludePaths: [
    '/health',
    '/api/audit'  // Skip all endpoint /api/audit/*
  ], 
  userId: 'SYSTEM' // You can change it to your own or from JWT token
}));
```

### User Activity
#### You can put this function anywhere if you want to record user activity.

```javascript
// CREATE
await auditTrail.setUserActivity({
  user_id: req.userId,
  action: 'CREATE',
  entity: 'order',
  platform: 'web',
  service_name: 'orders',
  entity_id: 'ORD123',
  after: { total: 100 }
});

// UPDATE
await auditTrail.setUserActivity({
  user_id: req.userId,
  action: 'UPDATE',
  entity: 'product',
  platform: 'mobile',
  service_name: 'inventory',
  before: { price: 99 },
  after: { price: 79 }
});

// DELETE
await auditTrail.setUserActivity({
  user_id: req.userId,
  action: 'DELETE',
  entity: 'product',
  platform: 'web',
  service_name: 'inventory',
  entity_id: 'ORD123'
});

// READ
await auditTrail.setUserActivity({
  user_id: req.userId,
  action: 'READ',
  entity: 'product',
  platform: 'web',
  service_name: 'inventory',
  entity_id: 'ORD123'
});
```

### System Integration

```javascript
await auditTrail.setSystemIntegration({
  integration_name: 'SAP',
  endpoint: '/api/sap/push-to-sap',
  method: 'POST',
  user_id: 'SYSTEM',
  platform: 'api',
  service_name: 'confirm-storage',
  entity_id: 'ORD123',
  before: { price: 99 },
  after: { price: 79 }
});
```

### Data Accountability

```javascript
await auditTrail.setDataAccountability({
  user_id: 'SYSTEM',
  action: 'READ',
  entity: 'product',
  platform: 'web',
  service_name: 'inventory',
  entity_id: 'ORD123'
});
```

## Security Features

### Encryption

```javascript
const { getEncryptionInstance } = require('@imexs/audit-trail');
const encryption = getEncryptionInstance();

const encrypted = encryption.encrypt('sensitive data');
const decrypted = encryption.decrypt(encrypted.encrypted, encrypted.iv, encrypted.authTag);
```

### Rate Limiting
- Membatasi jumlah request yang bisa dilakukan user/IP dalam waktu tertentu.
- Mencegah DoS Attack, Melindungi Database, Fair Usage

```javascript
const { getUserRateLimiter } = require('@imexs/audit-trail');
const limiter = getUserRateLimiter();

await limiter.checkLimit(req.userId);
```

### RBAC (Role-Based Access Control)
- Mencegah akses ke API yang tidak diizinkan
- Mengatur siapa boleh akses apa berdasarkan role.

```javascript
const { AuditAuthorizationMiddleware, AuditPermission } = require('@imexs/audit-trail');

app.get('/api/audit/logs',
  AuditAuthorizationMiddleware.checkPermission(AuditPermission.READ_ALL),
  async (req, res) => {
    const logs = await auditTrail.query({});
    res.json(logs);
  }
);
```

## Other Features

### Health Checks

```javascript
const { getHealthCheck } = require('@imexs/audit-trail');
const health = getHealthCheck();

app.get('/health/live', async (req, res) => {
  res.json(await health.liveness());
});

app.get('/health/ready', async (req, res) => {
  const status = await health.readiness();
  res.status(status.ready ? 200 : 503).json(status);
});
```

### Metrics

```javascript
const { getMetrics } = require('@imexs/audit-trail');
const metrics = getMetrics();

app.get('/metrics', (req, res) => {
  res.set('Content-Type', 'text/plain');
  res.send(metrics.toPrometheus());
});
```

### Graceful Shutdown

```javascript
const { initializeGracefulShutdown } = require('@imexs/audit-trail');

initializeGracefulShutdown();
// Automatic cleanup on SIGTERM/SIGINT
```

### Other Get Data
- You can use this function or you can create your own query to get audit-trail data.

```javascript
// Performance API Metrics (with pagination & keyword search)
const filters = {
    date: new Date(req.body.date),
    time: req.body.time || null,           // Optional: HH:mm format (24h Jakarta time)
    platform: req.body.platform || null,   // Optional: Filter by platform
    status: req.body.status || null,       // Optional: Filter by status (Success/Failed)
    keyword: req.body.keyword || null,     // Optional: Search in service_name, endpoint
    limit: req.body.limit || 100,          // Optional: Pagination limit (default: 100)
    offset: req.body.offset || 0           // Optional: Pagination offset (default: 0)
};

const result = await auditTrail.PerformanceApi().getPerformanceApiMetrics(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }

// Performance Server Metrics (with pagination & keyword search)
const filters = {
    date: new Date(req.body.date),
    time: req.body.time || null,           // Optional: HH:mm format (24h Jakarta time)
    platform: req.body.platform || null,   // Optional: Filter by platform
    status: req.body.status || null,       // Optional: Filter by status (Success/Failed)
    keyword: req.body.keyword || null,     // Optional: Search in service_name, action, endpoint
    limit: req.body.limit || 100,          // Optional: Pagination limit (default: 100)
    offset: req.body.offset || 0           // Optional: Pagination offset (default: 0)
};

const result = await auditTrail.PerformanceApi().getPerformanceServerMetrics(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }

// Performance User Activity (with pagination & keyword search)
const filters = {
    date: new Date(req.body.date),
    time: req.body.time || null,           // Optional: HH:mm format (24h Jakarta time)
    platform: req.body.platform || null,   // Optional: Filter by platform
    status: req.body.status || null,       // Optional: Filter by status (Success/Failed)
    keyword: req.body.keyword || null,     // Optional: Search in service_name, action
    limit: req.body.limit || 100,          // Optional: Pagination limit (default: 100)
    offset: req.body.offset || 0           // Optional: Pagination offset (default: 0)
};

const result = await auditTrail.PerformanceApi().getPerformanceUserActivity(filters);
// Response: { data: [...], pagination: { total, limit, offset, totalPages, currentPage } }

// Get All Logs
const filters = {
  actor_user_id: req.query.user_id,
  action: req.query.action,
  entity: req.query.entity,
  endpoint: req.query.endpoint,
  platform: req.query.platform,
  service_name: req.query.service,
  request_status: req.query.status,
  severity: req.query.severity,
  start_date: req.query.start_date ? new Date(req.query.start_date) : undefined,
  end_date: req.query.end_date ? new Date(req.query.end_date) : undefined,
  min_response_time: req.query.min_response_time ? parseInt(req.query.min_response_time) : undefined,
  max_response_time: req.query.max_response_time ? parseInt(req.query.max_response_time) : undefined
};

const options = {
  limit: parseInt(req.query.limit) || 100,
  offset: parseInt(req.query.offset) || 0,
  orderBy: req.query.order_by || 'timestamp',
  orderDirection: req.query.order_dir || 'desc'
};

const result = await auditTrailApi.getAllLogs(filters, options);

// Get performance summary
const filters = {
  start_date: req.query.start_date ? new Date(req.query.start_date) : undefined,
  end_date: req.query.end_date ? new Date(req.query.end_date) : undefined
};

const result = await auditTrailApi.getEndpointStats(filters);

// Get health metrics
const filters = {
  date: new Date(req.body.date),
  shift: req.body.shift || undefined, // Optional: 'morning' or 'night'
  start_time: req.body.start_time || undefined, // Optional: HH:mm format
  end_time: req.body.end_time || undefined // Optional: HH:mm format
};

const result = await auditTrailApi.HealthApi().getSummaryHealth(filters);

// Get system load summary
const filters = {
  date: new Date(req.body.date),
  time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};

const result = await auditTrailApi.getSummarySystemLoad(filters);

// Get top 5 slowest APIs
const filters = {
  date: new Date(req.body.date),
  time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};

const result = await auditTrailApi.getTop5SlowApi(filters);

// Get CPU usage summary (POST)
const filters = {
  date: new Date(req.body.date),
  time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};

const result = await auditTrailApi.getSummaryCpuUsage(filters);

// Get Memory usage summary (POST)
const filters = {
  date: new Date(req.body.date),
  time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};

const result = await auditTrailApi.getSummaryMemoryUsage(filters);

// Get active users with top 3 (POST)
const filters = {
  date: new Date(req.body.date),
  time: req.body.time || undefined // Optional: HH:mm format (24h Jakarta time)
};

const result = await auditTrailApi.getActiveUsers(filters);

```

## Compliance

- ***GDPR*** - Data protection & privacy
- ***SOC 2*** - Security controls & audit trails
- ***HIPAA*** - Healthcare data security
- ***PCI DSS*** - Payment data security
- ***ISO 27001*** - Information security management

## API Reference

### Core Functions

- \`setUserActivity(input)\` - Log user actions
- \`setSystemIntegration(input)\` - Log API calls
- \`setDataAccountability(input)\` - Log data access
- \`setPerformance(input)\` - Log performance metrics

### Security Functions

- \`getEncryptionInstance()\` - Get encryption service
- \`getUserRateLimiter()\` - Get rate limiter
- \`getIntegrityChecker()\` - Get integrity checker
- \`AuditInputValidator\` - Input validation utilities

### Other Functions

- \`getRetryPolicy()\` - Get retry mechanism
- \`getCircuitBreaker()\` - Get circuit breaker
- \`getBatchLogger()\` - Get batch logger
- \`getHealthCheck()\` - Get health check service
- \`getMetrics()\` - Get metrics collector
- \`initializeGracefulShutdown()\` - Setup graceful shutdown

## Contributing

Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md)

## License

MIT © IMEXS

## Links

- [npm Package](https://www.npmjs.com/package/audit-trail)
- [GitHub](https://github.com/imexs/audit-trail)
- [Changelog](CHANGELOG.md)

---

***Made with ❤️ by IMEXS***