70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import type { BusinessEvent } from '../../../foundation/business-events/types.ts';
|
|
import type { ProjectionConsumer, ProjectionHandleResult } from '../../../foundation/projections/types.ts';
|
|
import { getProjectionDefinition } from '../../../foundation/projections/registry.ts';
|
|
import { buildCalendarChangeFromEvent } from './builder.ts';
|
|
|
|
const definition = getProjectionDefinition('Calendar');
|
|
|
|
interface CalendarProjectionConsumerOptions {
|
|
persist?: (change: ReturnType<typeof buildCalendarChangeFromEvent>) => Promise<number>;
|
|
}
|
|
|
|
export function createCalendarProjectionConsumer(
|
|
options: CalendarProjectionConsumerOptions = {}
|
|
): ProjectionConsumer {
|
|
const persist = options.persist ?? persistCalendarChange;
|
|
|
|
return {
|
|
consumerName: definition.consumerName,
|
|
projectionName: definition.projectionName,
|
|
supportedEventTypes: definition.consumedEventTypes,
|
|
supportedVersions: definition.supportedVersions,
|
|
async handle(event: BusinessEvent): Promise<ProjectionHandleResult> {
|
|
const change = buildCalendarChangeFromEvent(event);
|
|
if (!change) {
|
|
return {
|
|
status: 'skipped',
|
|
message: 'Calendar event has no schedulable date',
|
|
sideEffectCount: 0
|
|
};
|
|
}
|
|
|
|
const sideEffectCount = await persist(change);
|
|
return {
|
|
status: 'processed',
|
|
message:
|
|
change.action === 'delete'
|
|
? 'Calendar projection activity item removed'
|
|
: 'Calendar projection item persisted',
|
|
sideEffectCount
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
export const calendarProjectionConsumer = createCalendarProjectionConsumer();
|
|
|
|
async function persistCalendarChange(
|
|
change: ReturnType<typeof buildCalendarChangeFromEvent>
|
|
): Promise<number> {
|
|
if (!change) return 0;
|
|
const { deleteCalendarProjectionForActivity, upsertCalendarProjectionItem } = await import(
|
|
'./service.ts'
|
|
);
|
|
|
|
if (change.action === 'delete') {
|
|
await deleteCalendarProjectionForActivity({
|
|
organizationId: change.organizationId,
|
|
activityId: change.activityId
|
|
});
|
|
return 1;
|
|
}
|
|
|
|
await deleteCalendarProjectionForActivity({
|
|
organizationId: change.item.organizationId,
|
|
activityId: change.item.activityId ?? change.item.entityId
|
|
});
|
|
await upsertCalendarProjectionItem(change.item);
|
|
return 1;
|
|
}
|