Tracevaultv0.1
Open source · MIT · Node.js + TypeScript

Custom audit events, consistently persisted.

A lightweight audit event library for Node.js and TypeScript. You define the events. Tracevault validates, masks, and stores them reliably in PostgreSQL.

npm install tracevault pg
emit.ts
import { createTracevault } from "tracevault"

const audit = createTracevault({
  driver: "postgres",
  connectionString: process.env.DATABASE_URL!,
  maskFields: ["password", "token"],
})

await audit.emit({
  event: "product.price.updated",
  actor:  { id: "user_123",    type: "user" },
  target: { id: "product_456", type: "product" },
  data:   { oldPrice: 120, newPrice: 150, currency: "UYU" },
  meta:   { source: "admin-panel" },
})
What you get

Enough structure to query. No more.

Tracevault handles the boring-but-crucial parts of audit logging so you can focus on what each event actually means in your domain.

01

Custom events first

You name the events. You own the shape of data and meta. No prescribed catalog, no compliance taxonomy you didn't ask for.

02

Structured by design

A small, stable persisted shape: event, actor, target, data, meta, occurredAt. Enough structure to query. No more.

03

PostgreSQL persistence

A JSONB-first schema with sensible indexes. Sync for durability, async for throughput. Zero runtime deps beyond pg.

04

Optional diff helper

emitDiff computes a shallow field diff between before and after, and stores { before, after, diff } as a normal event.

How it works

Four moving parts. That's the whole thing.

Tracevault is intentionally small. Create a client, emit events, let it persist them, query later with the tool you already use.

  1. 01

    Create the client

    Wire the PostgreSQL driver once at boot. Configure masking and default mode.

  2. 02

    Emit custom events

    Call emit() anywhere a business fact happens. You own the event name and payload.

  3. 03

    Persist them reliably

    Strict validation, recursive masking, sync or async writes against a JSONB table.

  4. 04

    Inspect with your own tools

    No lock-in. Query audit_logs with pg, drizzle, knex, prisma or raw SQL.

Examples

The whole public API, in three snippets.

No decorators. No magic. No ORM coupling. Just functions you call when something worth remembering happens.

Create the client

Wire the PostgreSQL driver once, at boot. maskFields is applied recursively to data, meta, before and after.

audit.ts
import { createTracevault } from "tracevault"

const audit = createTracevault({
  driver: "postgres",
  connectionString: process.env.DATABASE_URL!,
  tableName: "audit_logs",
  maskFields: ["password", "token", "pin"],
  defaultMode: "sync",
  environment: process.env.NODE_ENV,
})

Emit a custom event

Only event is required. actor, target, data, meta, correlationId and requestId are optional — use what makes sense.

login.ts
await audit.emit({
  event: "auth.login.succeeded",
  actor:  { id: "user_123", type: "user" },
  meta:   { ip: "127.0.0.1", userAgent: "curl/8" },
  correlationId: "req_abc",
})

Emit an object change

emitDiff is sugar around emit. It computes a shallow field diff and persists { before, after, diff } as the event payload.

update.ts
await audit.emitDiff({
  event: "product.updated",
  actor:  { id: "user_123",    type: "user" },
  target: { id: "product_456", type: "product" },
  before: { name: "Café", price: 120 },
  after:  { name: "Café", price: 150 },
})

// Persisted data:
// {
//   "before": { "name": "Café", "price": 120 },
//   "after":  { "name": "Café", "price": 150 },
//   "diff":   { "price": { "before": 120, "after": 150 } }
// }
Philosophy

A library, not a framework.

Most audit tools push a worldview. Tracevault stays out of your way and gives you a reliable place to land events you already know how to name.

  • 01

    Does not impose an event catalog.

  • 02

    Does not require an ORM.

  • 03

    Does not try to be a framework.

  • 04

    Stays minimal, typed, and predictable.

Tracevault does not define your event catalog. It gives you a consistent, reliable way to store your custom audit events.