Skip to main content

@idpass/data-collect-core / PostgresEventStorageAdapter

Class: PostgresEventStorageAdapter

Defined in: storage/PostgresEventStorageAdapter.ts:94

PostgreSQL implementation of the EventStorageAdapter for server-side event persistence.

This adapter provides scalable, tamper-evident event storage using PostgreSQL. It is designed for production server deployments requiring robust data persistence and efficient event sourcing operations.

Key features:

  • ACID Transactions: Full PostgreSQL transaction support for data consistency.
  • Multi-Tenant Support: Complete tenant isolation using tenant_id partitioning.
  • Immutable Event Storage: All events are stored as immutable records.
  • Audit Trail Management: Comprehensive audit logging for compliance and debugging.
  • Sync Timestamp Management: Tracks timestamps for various synchronization operations (local, remote, external).
  • Scalable Architecture: Designed for production workloads with proper indexing.

Architecture:

  • Uses PostgreSQL connection pooling for performance and scalability.
  • Stores events and audit logs as JSONB documents for flexible schema evolution.
  • Implements tenant isolation at the database level for all event-related data.
  • Provides optimized queries with proper indexing strategies for efficient retrieval.

Database Schema Overview:

  • events: Stores FormSubmission records with guid as primary key, entity_guid, timestamp, and sync_level.
  • audit_log: Stores AuditLogEntry records with id as primary key, entity_guid, event_guid, and timestamp.
  • sync_metadata: Key-value table for storing sync timestamps and other metadata, keyed by (tenant_id, key).

Examples

Basic server setup:

import { PostgresEventStorageAdapter } from '@idpass/data-collect-core';

const adapter = new PostgresEventStorageAdapter(
'postgresql://user:pass@localhost:5432/datacollect',
'tenant-123'
);

await adapter.initialize();

// Save events
const eventsToSave = [{ guid: 'event-1', entityGuid: 'entity-1', timestamp: new Date().toISOString(), type: 'create-entity', data: {} }];
await adapter.saveEvents(eventsToSave);

// Retrieve events
const allEvents = await adapter.getEvents();
console.log('All events:', allEvents);

Production connection configuration:

const adapter = new PostgresEventStorageAdapter(
'postgresql://event_user:secure_pass@db.example.com:5432/eventstore_prod?sslmode=require',
process.env.TENANT_ID
);

try {
await adapter.initialize();
console.log('Event storage initialized successfully');
} catch (error) {
console.error('Event storage initialization failed:', error);
process.exit(1);
}

Implements

Constructors

Constructor

new PostgresEventStorageAdapter(connectionString, tenantId?): PostgresEventStorageAdapter

Defined in: storage/PostgresEventStorageAdapter.ts:100

Parameters

connectionString

string

tenantId?

string

Returns

PostgresEventStorageAdapter

Constructor

new PostgresEventStorageAdapter(pool, tenantId?): PostgresEventStorageAdapter

Defined in: storage/PostgresEventStorageAdapter.ts:105

Creates a PostgresEventStorageAdapter using an existing Pool. When constructed this way, the adapter does NOT own the pool and will not close it.

Parameters

pool

Pool

tenantId?

string

Returns

PostgresEventStorageAdapter

Methods

getPool()

getPool(): Pool

Defined in: storage/PostgresEventStorageAdapter.ts:122

Returns the underlying pg Pool used by this adapter. Useful for creating transactional EDM stacks that share a single connection pool.

Returns

Pool


setDrizzleInstance()

setDrizzleInstance(db): void

Defined in: storage/PostgresEventStorageAdapter.ts:133

Replaces the internal Drizzle database instance. Used to inject a Drizzle transaction object so that all operations on this adapter participate in an external transaction.

Parameters

db

DrizzleDatabase

A Drizzle database or transaction instance.

Returns

void


closeConnection()

closeConnection(): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:144

Closes all connections in the PostgreSQL connection pool. Only closes the pool if this adapter owns it (created from a connection string). When constructed with an external Pool, the caller is responsible for pool lifecycle.

Returns

Promise<void>

A Promise that resolves when the connection is closed.

Implementation of

EventStorageAdapter.closeConnection


initialize()

initialize(): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:163

Initializes the PostgreSQL database with required tables and schemas for events and audit logs.

Creates:

  • events table with guid as primary key and various indexes for efficient querying.
  • audit_log table for storing audit trail entries.
  • sync_metadata table for tracking different synchronization timestamps.

This method is idempotent and safe to call multiple times.

Returns

Promise<void>

A Promise that resolves when the database is successfully initialized.

Throws

When database connection fails or table creation fails.

Implementation of

EventStorageAdapter.initialize


saveEvents()

saveEvents(eventList): Promise<string[]>

Defined in: storage/PostgresEventStorageAdapter.ts:233

Saves an array of FormSubmission events to the event store.

Events are saved within a transaction to ensure atomicity. If any event fails to save, the entire transaction is rolled back.

Parameters

eventList

FormSubmission[]

An array of FormSubmission objects to save.

Returns

Promise<string[]>

A Promise that resolves with an array of GUIDs of the successfully saved events.

Throws

If the database transaction fails during the save operation.

Implementation of

EventStorageAdapter.saveEvents


getEvents()

getEvents(): Promise<FormSubmission[]>

Defined in: storage/PostgresEventStorageAdapter.ts:267

Retrieves all FormSubmission events for the current tenant from the event store.

Events are mapped to ensure timestamp is a valid ISO string.

Returns

Promise<FormSubmission[]>

A Promise that resolves with an array of all FormSubmission events.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getEvents


saveAuditLog()

saveAuditLog(entries): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:307

Saves an array of AuditLogEntry entries to the audit log store.

Entries are saved within a transaction to ensure atomicity.

Parameters

entries

AuditLogEntry[]

An array of AuditLogEntry objects to save.

Returns

Promise<void>

A Promise that resolves when the audit log entries are successfully saved.

Throws

If the database transaction fails during the save operation.

Implementation of

EventStorageAdapter.saveAuditLog


getAuditLog()

getAuditLog(): Promise<AuditLogEntry[]>

Defined in: storage/PostgresEventStorageAdapter.ts:331

Retrieves all AuditLogEntry entries for the current tenant from the audit log store.

Returns

Promise<AuditLogEntry[]>

A Promise that resolves with an array of all AuditLogEntry entries.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getAuditLog


updateEventSyncLevel()

updateEventSyncLevel(id, syncLevel): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:366

Updates the syncLevel for a specific event identified by its GUID.

Parameters

id

string

The GUID of the event to update.

syncLevel

SyncLevel

The new SyncLevel to set for the event.

Returns

Promise<void>

A Promise that resolves when the event's sync level is updated.

Throws

If the database update fails.

Implementation of

EventStorageAdapter.updateEventSyncLevel


updateAuditLogSyncLevel()

updateAuditLogSyncLevel(entityGuid, syncLevel): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:378

Updates the syncLevel for audit log entries associated with a given entity GUID.

Parameters

entityGuid

string

The GUID of the entity whose associated audit log entries' sync levels need to be updated.

syncLevel

SyncLevel

The new SyncLevel to set for the audit log entries.

Returns

Promise<void>

A Promise that resolves when the update is complete.

Throws

If the database update fails.

Implementation of

EventStorageAdapter.updateAuditLogSyncLevel


getEventsSince()

getEventsSince(timestamp): Promise<FormSubmission[]>

Defined in: storage/PostgresEventStorageAdapter.ts:395

Retrieves FormSubmission events that have occurred since a specified timestamp.

Events are ordered by timestamp in ascending order (oldest first).

Parameters

timestamp

string | Date

The timestamp (ISO 8601 string or Date object) from which to retrieve events (exclusive).

Returns

Promise<FormSubmission[]>

A Promise that resolves with an array of FormSubmission events.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getEventsSince


getEventsSincePagination()

getEventsSincePagination(timestamp, limit?): Promise<{ events: FormSubmission[]; nextCursor: string | Date | null; }>

Defined in: storage/PostgresEventStorageAdapter.ts:436

Retrieves FormSubmission events that have occurred since a specified timestamp with pagination support.

Events are ordered by timestamp in ascending order (oldest first) and limited by limit.

Parameters

timestamp

string | Date

The timestamp (ISO 8601 string or Date object) from which to retrieve events (exclusive).

limit?

number = 100

The maximum number of events to retrieve in a single page. Defaults to 100.

Returns

Promise<{ events: FormSubmission[]; nextCursor: string | Date | null; }>

A Promise that resolves with an object containing an array of FormSubmission events and the nextCursor for pagination.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getEventsSincePagination


getAuditLogsSince()

getAuditLogsSince(timestamp): Promise<AuditLogEntry[]>

Defined in: storage/PostgresEventStorageAdapter.ts:503

Retrieves AuditLogEntry entries that have occurred since a specified timestamp.

Audit logs are ordered by timestamp in descending order (newest first).

Parameters

timestamp

string

The ISO 8601 timestamp string from which to retrieve audit logs (exclusive).

Returns

Promise<AuditLogEntry[]>

A Promise that resolves with an array of AuditLogEntry entries.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getAuditLogsSince


updateSyncLevelFromEvents()

updateSyncLevelFromEvents(eventList): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:539

Updates the syncLevel for a batch of FormSubmission events based on their GUIDs.

This operation is performed within a transaction for atomicity.

Parameters

eventList

FormSubmission[]

An array of FormSubmission objects, each containing the GUID and the new syncLevel.

Returns

Promise<void>

A Promise that resolves when all specified events' sync levels are updated.

Throws

If the database transaction fails during the update operation.

Implementation of

EventStorageAdapter.updateSyncLevelFromEvents


getLastRemoteSyncTimestamp()

getLastRemoteSyncTimestamp(): Promise<string>

Defined in: storage/PostgresEventStorageAdapter.ts:556

Retrieves the timestamp of the last successful remote synchronization.

Returns

Promise<string>

A Promise that resolves with the timestamp string, or an empty string if no timestamp exists.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getLastRemoteSyncTimestamp


setLastRemoteSyncTimestamp()

setLastRemoteSyncTimestamp(timestamp): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:569

Sets the timestamp of the last successful remote synchronization.

Uses an UPSERT to insert or update the timestamp in the sync_metadata table.

Parameters

timestamp

string

The timestamp string to save.

Returns

Promise<void>

A Promise that resolves when the timestamp is successfully saved.

Throws

If the database operation fails.

Implementation of

EventStorageAdapter.setLastRemoteSyncTimestamp


getLastLocalSyncTimestamp()

getLastLocalSyncTimestamp(): Promise<string>

Defined in: storage/PostgresEventStorageAdapter.ts:579

Retrieves the timestamp of the last successful local synchronization.

Returns

Promise<string>

A Promise that resolves with the timestamp string, or an empty string if no timestamp exists.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getLastLocalSyncTimestamp


setLastLocalSyncTimestamp()

setLastLocalSyncTimestamp(timestamp): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:592

Sets the timestamp of the last successful local synchronization.

Uses an UPSERT to insert or update the timestamp in the sync_metadata table.

Parameters

timestamp

string

The timestamp string to save.

Returns

Promise<void>

A Promise that resolves when the timestamp is successfully saved.

Throws

If the database operation fails.

Implementation of

EventStorageAdapter.setLastLocalSyncTimestamp


getLastPullExternalSyncTimestamp()

getLastPullExternalSyncTimestamp(): Promise<string>

Defined in: storage/PostgresEventStorageAdapter.ts:602

Retrieves the timestamp of the last successful external pull synchronization.

Returns

Promise<string>

A Promise that resolves with the timestamp string, or an empty string if no timestamp exists.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getLastPullExternalSyncTimestamp


setLastPullExternalSyncTimestamp()

setLastPullExternalSyncTimestamp(timestamp): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:615

Sets the timestamp of the last successful external pull synchronization.

Uses an UPSERT to insert or update the timestamp in the sync_metadata table.

Parameters

timestamp

string

The timestamp string to save.

Returns

Promise<void>

A Promise that resolves when the timestamp is successfully saved.

Throws

If the database operation fails.

Implementation of

EventStorageAdapter.setLastPullExternalSyncTimestamp


getLastPushExternalSyncTimestamp()

getLastPushExternalSyncTimestamp(): Promise<string>

Defined in: storage/PostgresEventStorageAdapter.ts:625

Retrieves the timestamp of the last successful external push synchronization.

Returns

Promise<string>

A Promise that resolves with the timestamp string, or an empty string if no timestamp exists.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getLastPushExternalSyncTimestamp


setLastPushExternalSyncTimestamp()

setLastPushExternalSyncTimestamp(timestamp): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:638

Sets the timestamp of the last successful external push synchronization.

Uses an UPSERT to insert or update the timestamp in the sync_metadata table.

Parameters

timestamp

string

The timestamp string to save.

Returns

Promise<void>

A Promise that resolves when the timestamp is successfully saved.

Throws

If the database operation fails.

Implementation of

EventStorageAdapter.setLastPushExternalSyncTimestamp


getLastScopeHash()

getLastScopeHash(): Promise<string | null>

Defined in: storage/PostgresEventStorageAdapter.ts:647

Scope hash tracking is a client-only concern; the server is stateless on client scope state.

Returns

Promise<string | null>

Throws

Always throws; this method is not supported on the server-side adapter.

Implementation of

EventStorageAdapter.getLastScopeHash


setLastScopeHash()

setLastScopeHash(_hash): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:658

Scope hash tracking is a client-only concern; the server is stateless on client scope state.

Parameters

_hash

string

Returns

Promise<void>

Throws

Always throws; this method is not supported on the server-side adapter.

Implementation of

EventStorageAdapter.setLastScopeHash


getLastScope()

getLastScope(): Promise<EffectiveScopeBody | null>

Defined in: storage/PostgresEventStorageAdapter.ts:669

Effective-scope-body persistence is a client-only concern; the server is stateless on client scope state.

Returns

Promise<EffectiveScopeBody | null>

Throws

Always throws; this method is not supported on the server-side adapter.

Implementation of

EventStorageAdapter.getLastScope


setLastScope()

setLastScope(_scope): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:680

Effective-scope-body persistence is a client-only concern; the server is stateless on client scope state.

Parameters

_scope

EffectiveScopeBody

Returns

Promise<void>

Throws

Always throws; this method is not supported on the server-side adapter.

Implementation of

EventStorageAdapter.setLastScope


deleteEventsForEntity()

deleteEventsForEntity(_entityGuid): Promise<number>

Defined in: storage/PostgresEventStorageAdapter.ts:693

Per-entity event deletion is a client-only data-minimization operation used during scope-purge. The server retains the full audit trail and MUST NOT support this method.

Parameters

_entityGuid

string

Returns

Promise<number>

Throws

Always throws; this method is not supported on the server-side adapter.

Implementation of

EventStorageAdapter.deleteEventsForEntity


isEventExisted()

isEventExisted(guid): Promise<boolean>

Defined in: storage/PostgresEventStorageAdapter.ts:706

Checks if an event with the given GUID exists in the event store for the current tenant.

Parameters

guid

string

The GUID of the event to check.

Returns

Promise<boolean>

A Promise that resolves to true if the event exists, false otherwise.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.isEventExisted


getAuditTrailByEntityGuid()

getAuditTrailByEntityGuid(entityGuid): Promise<AuditLogEntry[]>

Defined in: storage/PostgresEventStorageAdapter.ts:724

Retrieves the audit trail for a specific entity, identified by its entityGuid.

Audit log entries are ordered by timestamp in descending order (newest first).

Parameters

entityGuid

string

The GUID of the entity to retrieve the audit trail for.

Returns

Promise<AuditLogEntry[]>

A Promise that resolves with an array of AuditLogEntry entries.

Throws

If the database query fails.

Implementation of

EventStorageAdapter.getAuditTrailByEntityGuid


clearStore()

clearStore(): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:758

Clears all events, audit logs, and sync metadata for the current tenant from the store.

Returns

Promise<void>

A Promise that resolves when all data is cleared.

Throws

If the database deletion fails.

Implementation of

EventStorageAdapter.clearStore


persistHashAnchor()

persistHashAnchor(hash): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:770

Persists the latest hash anchor for tamper detection on restart.

Parameters

hash

string

The hash string to persist.

Returns

Promise<void>

A Promise that resolves when the hash is persisted.

Implementation of

EventStorageAdapter.persistHashAnchor


getPersistedHashAnchor()

getPersistedHashAnchor(): Promise<string | null>

Defined in: storage/PostgresEventStorageAdapter.ts:779

Retrieves the previously persisted hash anchor, or null if none exists.

Returns

Promise<string | null>

The persisted hash string, or null if no anchor has been saved.

Implementation of

EventStorageAdapter.getPersistedHashAnchor


getMetadataValue()

getMetadataValue(key): Promise<string | null>

Defined in: storage/PostgresEventStorageAdapter.ts:793

Generic key-value metadata accessor scoped to this adapter's tenant.

Reads from sync_metadata (tenant_id, key) → value. Returns null when the key is absent (do not return empty-string sentinel — empty string is a legitimate stored value).

Parameters

key

string

The metadata key (tenant scope is implicit).

Returns

Promise<string | null>

The stored value, or null if the key does not exist.

Implementation of

EventStorageAdapter.getMetadataValue


setMetadataValue()

setMetadataValue(key, value): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:808

Persist (upsert) a metadata value under key for this adapter's tenant.

Parameters

key

string

The metadata key.

value

string

The value to store.

Returns

Promise<void>

Implementation of

EventStorageAdapter.setMetadataValue


deleteMetadataValue()

deleteMetadataValue(key): Promise<void>

Defined in: storage/PostgresEventStorageAdapter.ts:831

Delete the metadata row for key (tenant-scoped). No-op if absent.

Parameters

key

string

The metadata key to remove.

Returns

Promise<void>

Implementation of

EventStorageAdapter.deleteMetadataValue


listMetadataKeys()

listMetadataKeys(prefix): Promise<string[]>

Defined in: storage/PostgresEventStorageAdapter.ts:848

List metadata keys whose name starts with prefix (tenant-scoped).

Uses SQL LIKE prefix% with the prefix passed verbatim — callers should not include % themselves. LIKE metacharacters (%, _, \) in the caller-supplied prefix are escaped so a prefix like "cr:%" matches the literal "cr:%" rather than treating % as a wildcard. Returns keys in insertion-order-agnostic order (no sort applied).

Parameters

prefix

string

Key prefix to filter on (e.g. "cr:").

Returns

Promise<string[]>

Implementation of

EventStorageAdapter.listMetadataKeys