Skip to main content

@idpass/data-collect-core / EventApplierService

Class: EventApplierService

Defined in: services/EventApplierService.ts:146

Service responsible for applying events (FormSubmissions) to entities in the event sourcing system.

The EventApplierService is the core component that transforms events into entity state changes. It handles all standard entity operations (create, update, delete, add/remove members) and supports custom event appliers for domain-specific operations.

Key features:

  • Event Processing: Applies form submissions to create or modify entities.
  • Custom Event Support: Allows registration of custom event appliers.
  • Audit Trail: Maintains complete audit logs for all changes.
  • Duplicate Detection: Automatically flags potential duplicates during entity creation.
  • Cascading Operations: Handles complex operations like group member management.
  • Data Validation: Validates all form submissions before processing.

Architecture:

  • Uses the Strategy pattern for pluggable event appliers.
  • Maintains referential integrity for group-member relationships.
  • Generates audit entries for all state changes.
  • Integrates with duplicate detection algorithms.

Examples

Basic usage:

const service = new EventApplierService(
eventStore,
entityStore
);

// Submit a form to create an individual
const individual = await service.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-individual',
data: { name: 'John Doe', age: 30 },
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});

Custom event applier:

// Register a custom event applier
const customApplier: EventApplier = {
apply: async (entity, form, getEntity, saveEntity) => {
if (form.type === 'custom-verification') {
const updated = {
...entity,
data: { ...entity.data, verified: true, verifiedAt: form.timestamp }
};
return updated;
}
throw new Error(`Unsupported event type: ${form.type}`);
}
};

service.registerEventApplier('custom-verification', customApplier);

// Now can process custom events
await service.submitForm({
type: 'custom-verification',
// ... other form properties
});

Group operations:

// Create a group with members
const group = await service.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-group',
data: {
name: 'Smith Family',
members: [
{ guid: 'person-1', name: 'John Smith', type: 'individual' },
{ guid: 'person-2', name: 'Jane Smith', type: 'individual' }
]
},
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});

// Add a member to existing group
await service.submitForm({
guid: uuidv4(),
entityGuid: group.guid,
type: 'add-member',
data: {
members: [{ guid: 'person-3', name: 'Bob Smith', type: 'individual' }]
},
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});

Constructors

Constructor

new EventApplierService(eventStore, entityStore): EventApplierService

Defined in: services/EventApplierService.ts:158

Creates a new EventApplierService instance.

Parameters

eventStore

EventStore

Store for managing events and audit logs.

entityStore

EntityStore

Store for managing current entity state.

Returns

EventApplierService

Methods

registerEventApplier()

registerEventApplier(eventType, applier): void

Defined in: services/EventApplierService.ts:189

Registers a custom event applier for a specific event type.

Allows extending the system with domain-specific event processing logic. Custom appliers take precedence over built-in event handling.

Parameters

eventType

string

The event type to handle (e.g., 'custom-verification').

applier

EventApplier

The event applier implementation.

Returns

void

void.

Example

const verificationApplier: EventApplier = {
apply: async (entity, form, getEntity, saveEntity) => {
const updated = {
...entity,
data: { ...entity.data, verified: true, verifiedAt: form.timestamp }
};
await saveEntity('verify-entity', entity, updated, form.data);
return updated;
}
};

service.registerEventApplier('custom-verification', verificationApplier);

getEventApplier()

getEventApplier(eventType): EventApplier | undefined

Defined in: services/EventApplierService.ts:207

Retrieves a registered event applier for a specific event type.

Parameters

eventType

string

The event type to look up.

Returns

EventApplier | undefined

The event applier if registered, undefined otherwise.

Example

const applier = service.getEventApplier('custom-verification');
if (applier) {
// Custom applier is available
}

getEntityStore()

getEntityStore(): EntityStore

Defined in: services/EventApplierService.ts:216

Retrieves the entity store instance.

Returns

EntityStore

The entity store instance.


submitForm()

submitForm(formDataParam): Promise<EntityDoc | null>

Defined in: services/EventApplierService.ts:293

Processes a form submission to create or modify entities through the event sourcing system.

This is the main entry point for all entity operations. The method:

  1. Validates the form submission data.
  2. Saves the event to the event store.
  3. Applies the event to create/update entities.
  4. Logs audit entries for all changes.
  5. Flags potential duplicates automatically.

Supported event types:

  • create-group / update-group: Create or modify group entities.
  • create-individual / update-individual: Create or modify individual entities.
  • add-member: Add a member to a group (supports both individuals and nested groups).
  • remove-member: Remove a member from a group (cascades delete for subgroups).
  • delete-entity: Delete an entity and all its descendants.
  • resolve-duplicate: Resolve potential duplicate entities.
  • Custom events: Handled by registered event appliers.

Parameters

formDataParam

FormSubmission

The form submission containing the event data.

Returns

Promise<EntityDoc | null>

The resulting entity after applying the event, or null if deletion occurred.

Throws

When validation fails or required data is missing.

Examples

Create an individual:

const individual = await service.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
});

Create a group with members:

const group = await service.submitForm({
guid: uuidv4(),
entityGuid: uuidv4(),
type: 'create-group',
data: {
name: 'Smith Family',
members: [
{ guid: uuidv4(), name: 'John Smith', type: 'individual' },
{ guid: uuidv4(), name: 'Jane Smith', type: 'individual' }
]
},
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});

Add member to existing group:

await service.submitForm({
guid: uuidv4(),
entityGuid: existingGroupId,
type: 'add-member',
data: {
members: [{ guid: uuidv4(), name: 'Bob Smith', type: 'individual' }]
},
timestamp: new Date().toISOString(),
userId: 'user-123',
syncLevel: SyncLevel.LOCAL
});

searchEntities()

searchEntities(criteria): Promise<object[]>

Defined in: services/EventApplierService.ts:822

Searches entities using the provided criteria.

Parameters

criteria

SearchCriteria

Search criteria array with query conditions.

Returns

Promise<object[]>

Array of entity pairs matching the criteria.

Example

// Search for adults
const adults = await service.searchEntities([
{ "data.age": { $gte: 18 } },
{ "type": "individual" }
]);

// Search for groups with specific name
const smithFamilies = await service.searchEntities([
{ "data.name": { $regex: /smith/i } },
{ "type": "group" }
]);