@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_idpartitioning. - 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: StoresFormSubmissionrecords withguidas primary key,entity_guid,timestamp, andsync_level.audit_log: StoresAuditLogEntryrecords withidas primary key,entity_guid,event_guid, andtimestamp.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
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:
eventstable withguidas primary key and various indexes for efficient querying.audit_logtable for storing audit trail entries.sync_metadatatable 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
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
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
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
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
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
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
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[]>