@flusys/nestjs-event-manager
v5.4.1
Published
Event manager module with calendar support and recurrence
Downloads
1,064
Maintainers
Readme
@flusys/nestjs-event-manager
Calendar event management for NestJS — recurrence patterns (DAILY, WEEKLY, BIWEEKLY, MONTHLY), participant tracking with status, and an EVENT_MANAGER_ADAPTER injection token for dependency-free cross-module integration.
Installation
npm install @flusys/nestjs-event-manager @flusys/nestjs-shared @flusys/nestjs-core1. Module Registration
forRoot (sync)
Mode 1: Single Database
import { EventManagerModule } from '@flusys/nestjs-event-manager';
EventManagerModule.forRoot({
global: true,
includeController: true,
bootstrapAppConfig: {
databaseMode: 'single',
enableCompanyFeature: false,
},
config: {
defaultColor: '#3B82F6', // optional, hex color for new events
maxRecurrenceOccurrences: 365, // optional, cap on expanded occurrences
defaultDatabaseConfig: {
type: 'mysql',
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT ?? 3306),
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
},
},
});Mode 2: Multi-Tenant
EventManagerModule.forRoot({
global: true,
includeController: true,
bootstrapAppConfig: {
databaseMode: 'multi-tenant',
enableCompanyFeature: true,
},
config: {
defaultColor: '#3B82F6',
maxRecurrenceOccurrences: 365,
tenantDefaultDatabaseConfig: {
type: 'mysql',
host: process.env.TENANT_DB_HOST,
port: Number(process.env.TENANT_DB_PORT ?? 3306),
username: process.env.TENANT_DB_USER,
password: process.env.TENANT_DB_PASSWORD,
database: process.env.TENANT_DB_NAME,
},
tenants: [
{ id: 'tenant-a', database: 'tenant_a_db' },
{ id: 'tenant-b', database: 'tenant_b_db' },
],
},
});forRootAsync (factory — recommended)
import { ConfigModule, ConfigService } from '@nestjs/config';
import { EventManagerModule, ITenantDatabaseConfig } from '@flusys/nestjs-event-manager';
// Single database
EventManagerModule.forRootAsync({
global: true,
bootstrapAppConfig: {
databaseMode: 'single',
enableCompanyFeature: true,
},
imports: [ConfigModule],
useFactory: (cfg: ConfigService) => ({
defaultColor: cfg.get('EVENT_DEFAULT_COLOR', '#3B82F6'),
maxRecurrenceOccurrences: cfg.get<number>('EVENT_MAX_RECURRENCE', 365),
defaultDatabaseConfig: {
type: 'mysql',
host: cfg.get('DB_HOST'),
port: cfg.get<number>('DB_PORT'),
username: cfg.get('DB_USER'),
password: cfg.get('DB_PASSWORD'),
database: cfg.get('DB_NAME'),
},
}),
inject: [ConfigService],
});
// Multi-tenant
EventManagerModule.forRootAsync({
global: true,
bootstrapAppConfig: {
databaseMode: 'multi-tenant',
enableCompanyFeature: true,
},
imports: [ConfigModule],
useFactory: (cfg: ConfigService) => ({
defaultColor: cfg.get('EVENT_DEFAULT_COLOR', '#3B82F6'),
maxRecurrenceOccurrences: cfg.get<number>('EVENT_MAX_RECURRENCE', 365),
tenantDefaultDatabaseConfig: {
type: 'mysql',
host: cfg.get('TENANT_DB_HOST'),
port: cfg.get<number>('TENANT_DB_PORT'),
username: cfg.get('TENANT_DB_USER'),
password: cfg.get('TENANT_DB_PASSWORD'),
database: cfg.get('TENANT_DB_NAME'),
},
tenants: cfg.get<ITenantDatabaseConfig[]>('TENANTS'),
}),
inject: [ConfigService],
});Exported services (available for injection after registration):
EventService, EventManagerHelperService, EventManagerConfigService, EventManagerDataSourceProvider, EVENT_MANAGER_ADAPTER
2. Entities
import { getEventManagerEntitiesByConfig } from '@flusys/nestjs-event-manager/entities';
TypeOrmModule.forRoot({
entities: [
...getEventManagerEntitiesByConfig(false), // match enableCompanyFeature in bootstrapAppConfig
],
});| enableCompanyFeature | Entities registered |
| ---------------------- | -------------------------------------- |
| false | Event, EventParticipant |
| true | EventWithCompany, EventParticipant |
The service resolves the correct entity variant automatically per request.
4. Cross-Module Adapter (EVENT_MANAGER_ADAPTER)
Other modules can create events without importing this package directly. The IEventManagerAdapter interface and EVENT_MANAGER_ADAPTER token are defined in @flusys/nestjs-shared.
import { IEventManagerAdapter, EVENT_MANAGER_ADAPTER } from '@flusys/nestjs-shared';
import { Optional } from '@nestjs/common';
@Injectable()
export class NotificationService {
constructor(
@Optional()
@Inject(EVENT_MANAGER_ADAPTER)
private readonly eventAdapter?: IEventManagerAdapter,
) {}
async scheduleReminder(userId: string, date: string): Promise<void> {
await this.eventAdapter?.createEvent({
title: 'Reminder',
eventDate: date,
startTime: '09:00',
endTime: '09:30',
participantIds: [userId],
organizerId: userId,
});
}
}The adapter exposes: createEvent, updateParticipantStatus, getEventsForUser, getEventById.
Using @Optional() means your module works even when EventManagerModule is not registered.
5. Programmatic Usage (singleton)
Use EventManagerHelperService (not REQUEST-scoped) for programmatic event creation from background jobs or other singleton services:
import { EventManagerHelperService } from '@flusys/nestjs-event-manager';
@Injectable()
export class OnboardingService {
constructor(
@Inject(EventManagerHelperService)
private readonly eventHelper: EventManagerHelperService,
) {}
async scheduleCall(userId: string): Promise<void> {
await this.eventHelper.createEvent({
title: 'Onboarding Call',
eventDate: '2026-05-01',
startTime: '10:00',
endTime: '10:30',
organizerId: userId,
});
}
}License
MIT © FLUSYS
