@idpass/data-collect-core / EntityDataManager
Class: EntityDataManager
Defined in: components/EntityDataManager.ts:140
Primary API interface for the ID PASS DataCollect library.
The EntityDataManager orchestrates all data operations including:
- Form submission and event processing
- Entity creation, modification, and querying
- Data synchronization with remote servers and external systems
- Audit trail management and duplicate detection
This class implements the Command Query Responsibility Segregation (CQRS) pattern, where all changes go through events (FormSubmissions) and queries access the current state through the EntityStore.
Examples
Basic usage:
import { EntityDataManager, EntityType, SyncLevel } from 'idpass-data-collect';
// Initialize the manager (typically done once)
const manager = new EntityDataManager(
eventStore,
entityStore,
eventApplierService,
externalSyncManager,
internalSyncManager
);
// Create a new individual
const individual = await manager.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-individual',
data: { name: 'John Doe', age: 30 },
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});
// Create a household group
const group = await manager.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-group',
data: { name: 'Smith Family' },
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});
// Add individual to group
await manager.submitForm({
guid: uuidv4(),
entityGuid: group.guid,
type: 'add-member',
data: { members: [{ guid: individual.guid, name: individual.data.name }] },
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});
Offline-first usage:
// Works completely offline
const offlineManager = new EntityDataManager(
eventStore,
entityStore,
eventApplierService
// No sync managers - offline only
);
// All operations work locally
const entity = await offlineManager.submitForm(formData);
const allEntities = await offlineManager.getAllEntities();
With synchronization:
// Sync with remote server
if (manager.hasInternalSyncManager()) {
await manager.sync();
}
// Check sync status
if (manager.isSyncing()) {
console.log('Sync in progress...');
}
Constructors
Constructor
new EntityDataManager(
eventStore,entityStore,eventApplierService,externalSyncManager?,internalSyncManager?,authManager?):EntityDataManager
Defined in: components/EntityDataManager.ts:153
Creates a new EntityDataManager instance.
Parameters
eventStore
Store for managing events/form submissions.
entityStore
Store for managing current entity state.
eventApplierService
Service for applying events to entities.
externalSyncManager?
Optional manager for external system sync.
internalSyncManager?
Optional manager for server sync.
authManager?
Optional manager for authentication.
Returns
EntityDataManager
Methods
isSyncing()
isSyncing():
boolean
Defined in: components/EntityDataManager.ts:167
Checks if a synchronization operation is currently in progress.
Returns
boolean
True if sync is active, false otherwise.
submitForm()
submitForm(
formData):Promise<EntityDoc|null>
Defined in: components/EntityDataManager.ts:207
Submits a form to create or modify entities through the event sourcing system.
All modifications go through events (FormSubmissions) which are applied to create the new state.
Parameters
formData
The form submission containing the event data.
Returns
Promise<EntityDoc | null>
The resulting entity after applying the event, or null if creation failed.
Example
// Create a new individual
const individual = await manager.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-individual',
data: { name: 'John Doe', age: 30, email: 'john@example.com' },
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});
// Update an existing individual
const updated = await manager.submitForm({
guid: uuidv4(),
entityGuid: individual.guid,
type: 'update-individual',
data: { age: 31 }, // Only changed fields
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});
getAllEvents()
getAllEvents(
options):Promise<FormSubmission[]>
Defined in: components/EntityDataManager.ts:233
Retrieves all events (form submissions) from the event store.
Provides access to the complete audit trail of all changes made to entities. Events are returned in chronological order.
Parameters
options
ReadAuditOptions = {}
Returns
Promise<FormSubmission[]>
Array of all form submissions/events.
Example
const events = await manager.getAllEvents();
// Filter events by type
const createEvents = events.filter(e => e.type.startsWith('create-'));
// Filter events by user
const userEvents = events.filter(e => e.userId === 'user-123');
// Filter events by entity
const entityEvents = events.filter(e => e.entityGuid === 'entity-456');
getAllEntities()
getAllEntities(
options):Promise<object[]>
Defined in: components/EntityDataManager.ts:267
Retrieves all entities from the entity store.
Returns EntityPairs containing both the initial state (when first loaded/synced) and the current modified state. This enables change tracking and conflict resolution.
Parameters
options
ReadAuditOptions = {}
Returns
Promise<object[]>
Array of entity pairs with initial and current state.
Example
const entities = await manager.getAllEntities();
// Find entities that have been modified locally
const modifiedEntities = entities.filter(pair =>
pair.initial.version !== pair.modified.version
);
// Get only individuals
const individuals = entities.filter(pair =>
pair.modified.type === EntityType.Individual
);
// Get only groups
const groups = entities.filter(pair =>
pair.modified.type === EntityType.Group
);
getEntity()
getEntity(
id,options):Promise<{initial:EntityDoc;modified:EntityDoc; }>
Defined in: components/EntityDataManager.ts:304
Retrieves a specific entity by its internal database ID.
Parameters
id
string
Internal database ID of the entity.
options
ReadAuditOptions = {}
Returns
Promise<{ initial: EntityDoc; modified: EntityDoc; }>
Entity pair with initial and current state.
Throws
When entity is not found.
Example
try {
const entityPair = await manager.getEntity('entity-123');
console.log('Original state:', entityPair.initial);
console.log('Current state:', entityPair.modified);
// Check if entity has been modified
const hasChanges = entityPair.initial.version !== entityPair.modified.version;
if (entityPair.modified.type === EntityType.Group) {
const group = entityPair.modified as GroupDoc;
console.log('Group members:', group.memberIds);
}
} catch (error) {
if (error instanceof AppError && error.code === 'ENTITY_NOT_FOUND') {
console.log('Entity does not exist');
}
}
getMembers()
getMembers(
groupId):Promise<object[]>
Defined in: components/EntityDataManager.ts:434
Retrieves all members of a specific group.
Parameters
groupId
string
Internal database ID of the group.
Returns
Promise<object[]>
Array of entity pairs for all group members.
Throws
When group is not found or entity is not a group.
Example
try {
const members = await manager.getMembers('group-123');
console.log(`Group has ${members.length} members`);
members.forEach(member => {
console.log(`Member: ${member.modified.data.name}`);
});
} catch (error) {
if (error instanceof AppError && error.code === 'INVALID_GROUP') {
console.log('Group not found or invalid');
}
}
hasUnsyncedEvents()
hasUnsyncedEvents():
Promise<boolean>
Defined in: components/EntityDataManager.ts:459
Checks if there are any unsynced events waiting to be synchronized.
Only available when an InternalSyncManager is configured.
Returns
Promise<boolean>
True if there are unsynced events, false otherwise.
Example
if (await manager.hasUnsyncedEvents()) {
console.log('There are changes waiting to sync');
await manager.syncWithSyncServer();
}
getUnsyncedEventsCount()
getUnsyncedEventsCount():
Promise<number>
Defined in: components/EntityDataManager.ts:483
Gets the count of unsynced events waiting to be synchronized.
Only available when an InternalSyncManager is configured.
Returns
Promise<number>
Number of unsynced events.
Example
const count = await manager.getUnsyncedEventsCount();
console.log(`${count} events waiting to sync`);
if (count > 100) {
console.log('Large number of changes - consider syncing soon');
}
syncWithSyncServer()
syncWithSyncServer():
Promise<void>
Defined in: components/EntityDataManager.ts:511
Synchronizes local data with the remote sync server.
Performs a full bidirectional sync: pushes local changes to server and pulls remote changes to local storage.
Only available when an InternalSyncManager is configured.
Returns
Promise<void>
Throws
When sync fails or authentication is required.
Example
try {
console.log('Starting sync...');
await manager.syncWithSyncServer();
console.log('Sync completed successfully');
} catch (error) {
console.error('Sync failed:', error.message);
}
searchEntities()
searchEntities(
criteria,options):Promise<object[]>
Defined in: components/EntityDataManager.ts:540
Searches entities using specified criteria.
Parameters
criteria
Search criteria array with query conditions.
options
ReadAuditOptions = {}
Returns
Promise<object[]>
Array of entity pairs matching the criteria.
Example
// Search for adults
const adults = await manager.searchEntities([
{ "data.age": { $gte: 18 } },
{ "type": "individual" }
]);
// Search for groups with specific name
const smithFamilies = await manager.searchEntities([
{ "data.name": { $regex: /smith/i } },
{ "type": "group" }
]);
// TODO: Document the exact query syntax supported
getAuditTrailByEntityGuid()
getAuditTrailByEntityGuid(
entityGuid,options):Promise<AuditLogEntry[]>
Defined in: components/EntityDataManager.ts:572
Retrieves the complete audit trail for a specific entity.
Parameters
entityGuid
string
Global unique identifier of the entity.
options
ReadAuditOptions = {}
Returns
Promise<AuditLogEntry[]>
Array of audit log entries in chronological order.
Throws
When audit trail retrieval fails.
Example
try {
const auditTrail = await manager.getAuditTrailByEntityGuid('entity-123');
console.log(`Found ${auditTrail.length} audit entries`);
auditTrail.forEach(entry => {
console.log(`${entry.timestamp}: ${entry.action} by ${entry.userId}`);
});
} catch (error) {
if (error instanceof AppError && error.code === 'AUDIT_TRAIL_ERROR') {
console.error('Failed to retrieve audit trail');
}
}
getEventsSince()
getEventsSince(
timestamp):Promise<FormSubmission[]>
Defined in: components/EntityDataManager.ts:629
Retrieves events created since a specific timestamp.
Useful for incremental sync operations and change tracking.
Parameters
timestamp
string
ISO timestamp to filter events from.
Returns
Promise<FormSubmission[]>
Array of events created after the specified timestamp.
Example
const lastSync = '2024-01-01T00:00:00Z';
const recentEvents = await manager.getEventsSince(lastSync);
console.log(`${recentEvents.length} events since last sync`);
recentEvents.forEach(event => {
console.log(`${event.timestamp}: ${event.type} on ${event.entityGuid}`);
});
getEventsSincePagination()
getEventsSincePagination(
timestamp,limit):Promise<{events:FormSubmission[];nextCursor:string|Date|null; }>
Defined in: components/EntityDataManager.ts:654
Retrieves events since a timestamp with pagination support.
Parameters
timestamp
string
ISO timestamp to filter events from.
limit
number
Maximum number of events to return (default: 10).
Returns
Promise<{ events: FormSubmission[]; nextCursor: string | Date | null; }>
Object with events array and cursor for next page.
Example
let cursor = '2024-01-01T00:00:00Z';
let allEvents: FormSubmission[] = [];
do {
const result = await manager.getEventsSincePagination(cursor, 50);
allEvents.push(...result.events);
cursor = result.nextCursor;
} while (cursor);
console.log(`Retrieved ${allEvents.length} events total`);
closeConnection()
closeConnection():
Promise<void>
Defined in: components/EntityDataManager.ts:674
Closes all database connections and cleans up resources.
Should be called when the EntityDataManager is no longer needed to properly release database connections and prevent memory leaks.
Returns
Promise<void>
Example
// At application shutdown
await manager.closeConnection();
console.log('Database connections closed');
clearStore()
clearStore():
Promise<void>
Defined in: components/EntityDataManager.ts:694
Clears all data from both entity and event stores.
⚠️ WARNING: This permanently deletes all data! Only use for testing or when intentionally resetting the system.
Returns
Promise<void>
Example
// For testing only
if (process.env.NODE_ENV === 'test') {
await manager.clearStore();
console.log('Test data cleared');
}
saveAuditLogs()
saveAuditLogs(
auditLogs):Promise<void>
Defined in: components/EntityDataManager.ts:722
Saves multiple audit log entries to the event store.
Parameters
auditLogs
Array of audit log entries to save.
Returns
Promise<void>
Example
const auditLogs: AuditLogEntry[] = [
{
guid: 'audit-1',
timestamp: '2024-01-01T12:00:00Z',
userId: 'user-123',
action: 'create-individual',
eventGuid: 'event-456',
entityGuid: 'person-789',
changes: { name: 'John Doe' },
signature: 'sha256:abc123'
}
];
await manager.saveAuditLogs(auditLogs);
getAuditLogsSince()
getAuditLogsSince(
since):Promise<AuditLogEntry[]>
Defined in: components/EntityDataManager.ts:740
Retrieves audit logs created since a specific timestamp.
Parameters
since
string
ISO timestamp to filter audit logs from.
Returns
Promise<AuditLogEntry[]>
Array of audit log entries created after the specified timestamp.
Example
const lastAuditSync = '2024-01-01T00:00:00Z';
const recentAudits = await manager.getAuditLogsSince(lastAuditSync);
console.log(`${recentAudits.length} audit entries since last sync`);
getPotentialDuplicates()
getPotentialDuplicates():
Promise<object[]>
Defined in: components/EntityDataManager.ts:769
Retrieves all potential duplicate entity pairs detected by the system.
Returns
Promise<object[]>
Array of entity GUID pairs that are potential duplicates.
Example
const duplicates = await manager.getPotentialDuplicates();
if (duplicates.length > 0) {
console.log(`Found ${duplicates.length} potential duplicate pairs`);
for (const pair of duplicates) {
const entity1 = await manager.getEntity(pair.entityGuid);
const entity2 = await manager.getEntity(pair.duplicateGuid);
console.log('Potential duplicate:');
console.log('Entity 1:', entity1.modified.data);
console.log('Entity 2:', entity2.modified.data);
// TODO: Implement duplicate resolution workflow
}
}
syncWithExternalSystem()
syncWithExternalSystem(
credentials?):Promise<void>
Defined in: components/EntityDataManager.ts:796
Synchronizes data with external systems (e.g., OpenSPP, custom APIs).
Parameters
credentials?
Optional credentials for external system authentication.
Returns
Promise<void>
Throws
When external sync fails or credentials are invalid.
Example
// Sync with OpenSPP system
try {
await manager.syncWithExternalSystem({
username: 'sync_user',
password: 'sync_password'
});
console.log('External sync completed');
} catch (error) {
console.error('External sync failed:', error.message);
}
// Sync without credentials (if configured in adapter)
await manager.syncWithExternalSystem();
login()
login(
credentials,type?):Promise<void>
Defined in: components/EntityDataManager.ts:850
Logs in the user via the configured AuthManager.
Parameters
credentials
The credentials for login.
PasswordCredentials | TokenCredentials | null
type?
string
Optional. The type of authentication provider to use.
Returns
Promise<void>
A Promise that resolves when the login operation is complete.
Throws
If AuthManager is not configured or login fails.
initializeAuthManager()
initializeAuthManager():
Promise<void>
Defined in: components/EntityDataManager.ts:862
Initializes the AuthManager.
Returns
Promise<void>
A Promise that resolves when the AuthManager is initialized.
Throws
If AuthManager is not configured.
logout()
logout():
Promise<void>
Defined in: components/EntityDataManager.ts:874
Logs out the user via the configured AuthManager.
Returns
Promise<void>
A Promise that resolves when the logout operation is complete.
Throws
If AuthManager is not configured or logout fails.
validateToken()
validateToken(
type,token):Promise<boolean>
Defined in: components/EntityDataManager.ts:888
Validates an authentication token via the configured AuthManager.
Parameters
type
string
The type of authentication provider.
token
string
The token string to validate.
Returns
Promise<boolean>
A Promise that resolves to true if the token is valid, false otherwise.
Throws
If AuthManager is not configured.
isAuthenticated()
isAuthenticated():
Promise<boolean>
Defined in: components/EntityDataManager.ts:901
Checks if the user is authenticated via the configured AuthManager.
Returns
Promise<boolean>
A Promise that resolves to true if authenticated, false otherwise.
Throws
If AuthManager is not configured.
handleCallback()
handleCallback(
type):Promise<void>
Defined in: components/EntityDataManager.ts:915
Handles the authentication callback via the configured AuthManager.
Parameters
type
string
The type of authentication provider.
Returns
Promise<void>
A Promise that resolves when the callback is handled.
Throws
If AuthManager is not configured.