About edifice-nestjs-core
- Licence : Copyright Edifice
- Funder(s) : Edifice
- Developer(s) : Edifice
@edifice.io/edifice-nestjs-core
Core NestJS modules and utilities for Edifice applications.
📦 Installation
pnpm add @edifice.io/edifice-nestjs-core
🚀 Features
This package provides essential building blocks for building Edifice backend applications with NestJS:
Modules
- AppRegistry: Application registry service
- Config: Centralized configuration management
- Database: MikroORM integration with PostgreSQL support
- Event: Event emitter for data
- Health: Health check endpoints (readiness, liveness)
- I18n: Internationalization service for multi-language support
- Logger: Structured logging with Pino (access logs, request logs)
- NATS: NATS messaging client integration
- Permission: Authorization guards and decorators (ADMC, permission-based)
- Session: Session management middleware and decorators
- Timeline: Timeline notification service
AppRegistry (Application Registration)
The AppRegistryService is included automatically via the CoreModule.
It registers your application with the Edifice App Registry at startup.
This process scans all controllers for @RequirePermission decorators, collects all declared workflow permissions, and sends them to the registry along with application metadata.
How it works:
- On application bootstrap,
AppRegistryService.registerApp()is called. - It extracts all permissions from your controllers using reflection.
- It sends an
AppRegistrationRequestDTOto the registry via NATS. - The registration is retried every 10 seconds until successful.
Where and when:
- Registration happens automatically during the bootstrap phase (see
createApp()inbootstrap.utils.ts). - You do not need to call it manually; it is triggered by the core module (
CoreModule).
Why:
- This ensures your app and its permissions are discoverable and manageable by the Edifice platform.
- It enables centralized permission management and workflow integration.
Example:
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
@Module({
imports: [CoreModule], // AppRegistryService is included automatically
})
export class AppModule {}
@Controller()
export class ResourceController {
@Get()
@RequirePermission('ACCESS')
async findAll() {
// This permission will be registered automatically
}
}
Config (Centralized Application Configuration)
The ConfigModule is automatically included when you import CoreModule in your application.
It provides centralized configuration management for your Edifice backend, using NestJS's ConfigModule and supporting environment variables.
Features:
- Loads configuration from environment variables.
- Exposes configuration via NestJS
ConfigServicefor dependency injection. - Provides helpers for logging, database, Swagger, and other modules to read their settings.
How it works:
- On application startup, the configuration is loaded from environment variables and injected globally.
- All modules (database, logger, NATS, etc.) read their settings from
ConfigService. - You can override configuration by setting environment variables.
Where and when:
- The configuration system is initialized automatically at application startup by
CoreModule. - No manual setup is needed; just set the required environment variables.
Configuration:
- Set your main configuration using environment variables.
- See
src/config/EnvVars.mdfor a full list of supported variables and their defaults.
Example environment variables:
APP_NAME=my-edifice-app
APP_DISPLAY_NAME=My Edifice App
APP_PREFIX=/api
APP_ICON=https://example.com/icon.png
HOST=0.0.0.0
PORT=3002
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
DATABASE_USER=user
DATABASE_PASSWORD=pass
DATABASE_SCHEMA=public
DATABASE_DEBUG=true
DATABASE_SSL=false
NATS_URL=nats://localhost:4222
NATS_USER=natsuser
NATS_PASSWORD=natspass
NATS_DEBUG=false
LOG_LEVEL=info
LOG_KEEP_RAW_FIELDS=false
SWAGGER_SERVER_URL=https://api.example.com
HEAP_MEMORY=300
RSS_MEMORY=300
Example:
import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { ConfigService } from '@nestjs/config';
@Module({
imports: [CoreModule], // ConfigModule is included automatically
})
export class AppModule {
constructor(private readonly configService: ConfigService) {
const appName = this.configService.get<string>('app.name');
console.log(`App name: ${appName}`);
}
}
Note:
You do not need to configure the configuration system manually; it is ready to use when you import CoreModule.
All modules and services can access configuration via dependency injection of ConfigService.
Additional configuration:
You can also provide additional configuration like so
import { Module } from '@nestjs/common';
import { configuration as CoreConfig } from '@edifice.io/edifice-nestjs-core';
import AppConfig from './config/configuration'; // Your app's configuration object
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
CoreModule,
// Use config defined in core + app config
// (warn: does not override core config fields)
ConfigModule.forRoot({
isGlobal: true,
load: [CoreConfig, AppConfig],
}),
],
})
export class AppModule {}
Database (MikroORM Integration)
The DatabaseModule provides seamless integration with MikroORM and PostgreSQL for your Edifice backend application.
Features:
- Automatic database connection and configuration using NestJS
ConfigModule. - Runs pending migrations automatically at startup (if enabled in configuration).
- Provides helpers to execute SQL scripts and manage schema evolution.
How to use:
- Import
DatabaseModulein your main application module (already included inCoreModule). - Configure your database connection via environment variables (
DATABASE_URL,DATABASE_USER, etc.). - Place your migration scripts in the
sql/directory, following the naming convention:NN-description.sqlfor migration scripts (e.g.,01-init.sql)NN-rollback.sqlfor rollback scripts (e.g.,01-rollback.sql)
- Implement migration classes in
./src/migrations/, each using the helper to execute the corresponding SQL files.
Example:
- Implement migration classes in
./src/migrations/, each using the helper to execute the corresponding SQL files.
SQL migration script (sql/01-init.sql):
-- Create a demo table
CREATE TABLE demo_table (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);
SQL rollback script (sql/01-rollback.sql):
-- Drop the demo table
DROP TABLE IF EXISTS demo_table;
Migration class (src/migrations/Migration01.ts):
import { Migration } from '@mikro-orm/migrations';
import { executeScript } from '@edifice.io/edifice-nestjs-core';
export class Migration01 extends Migration {
async up(): Promise<void> {
await executeScript(this, '01-init.sql');
}
async down(): Promise<void> {
await executeScript(this, '01-rollback.sql');
}
}
Entity definition (src/entities/demo.entity.ts):
import { Entity, PrimaryKey, Property } from '@mikro-orm/core';
@Entity()
export class Demo {
@PrimaryKey()
id!: number;
@Property()
name!: string;
}
Service using EntityRepository (src/demo/demo.service.ts):
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@mikro-orm/nestjs';
import { EntityRepository } from '@mikro-orm/postgresql';
import { Demo } from '../entities/demo.entity';
@Injectable()
export class DemoService {
constructor(
@InjectRepository(Demo)
private readonly demoRepository: EntityRepository<Demo>,
) {}
async createDemo(name: string): Promise<Demo> {
const demo = this.demoRepository.create({ name });
await this.demoRepository.persistAndFlush(demo);
return demo;
}
async findAll(): Promise<Demo[]> {
return this.demoRepository.findAll();
}
}
Demo module (src/demo/demo.module.ts):
import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { DemoService } from './demo.service';
import { Demo } from '../entities/demo.entity';
import { MikroOrmModule } from '@mikro-orm/nestjs';
@Module({
imports: [CoreModule, MikroOrmModule.forFeature([Demo])],
providers: [DemoService],
exports: [DemoService],
})
export class DemoModule {}
Note:
- Database connection parameters and migration behavior are controlled via environment variables.
- The module ensures your database schema is up-to-date and provides utilities for advanced migration workflows.
Event (User Event Tracking)
The EventModule provides services for tracking and recording user events (such as access and creation) in your Edifice backend application.
Features:
- Publishes user events (ACCESS, CREATE) to the Edifice event system via NATS.
- Automatically extracts user/session information from requests.
- Skips access events for mobile webview requests.
- Centralizes event logging for analytics and auditing.
How to use:
- Import
CoreModulein your main application module (already includesEventModule). - Inject
EventServiceinto your controllers or services. - Call
createAccessEvent(request, resourceType)orcreateCreateEvent(request, resourceType)to record events.
Example:
import { Controller, Get, Post, Req, Injectable } from '@nestjs/common';
import { EventService, CoreModule } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';
@Module({
imports: [CoreModule],
})
export class AppModule {}
@Controller()
export class ResourceController {
constructor(private readonly eventService: EventService) {}
@Get('/')
async onResourceAccess(@Req() request: FastifyRequest) {
await this.eventService.createAccessEvent(request);
}
@Post('/')
async onResourceCreate(@Req() request: FastifyRequest) {
await this.eventService.createCreateEvent(request, 'RESOURCE_TYPE');
}
}
Configuration:
- The module uses
ConfigServiceto get the application name (app.name). - Events are sent via the NATS client (
EntNatsServiceClient), which is configured automatically by the core module.
Note:
- You do not need to configure the event system manually; it is ready to use when you import
CoreModule. - Events are useful for analytics, auditing, and workflow triggers.
Health (Readiness & Liveness Checks)
The HealthModule is automatically included when you import CoreModule in your application.
It provides endpoints and services for readiness and liveness checks, integrating with NestJS Terminus.
Features:
- Exposes a
/healthendpoint for readiness and liveness checks. - Checks database connectivity (MikroORM), memory usage, and NATS connection.
- Customizable thresholds for memory usage via configuration.
- Integrates with monitoring and orchestration systems (Kubernetes, Docker, etc.).
How it works:
- The
HealthControlleraggregates checks for database, memory, and NATS. - Health indicators are injected and run automatically.
- The
/healthendpoint is public and can be used for probes.
Where and when:
- The health system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- Memory thresholds and other health parameters are set using environment variables:
HEAP_MEMORY=300 RSS_MEMORY=300 - You can adjust these values to fit your deployment requirements.
Example:
import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
@Module({
imports: [CoreModule], // HealthModule is included automatically
})
export class AppModule {}
Note:
You do not need to configure health endpoints manually; they are ready to use when you import CoreModule.
Health checks are essential for cloud-native deployments and automated monitoring.
I18n (Internationalization Service)
The I18nModule is automatically included when you import CoreModule in your application.
It provides services for registering and fetching translations, enabling multi-language support for your Edifice backend.
Features:
- Registers translation files for your application at startup.
- Fetches translations dynamically based on request headers (language detection).
- Integrates with the Edifice ENT client for centralized translation management.
- Supports custom translation files per language (e.g.,
assets/i18n/fr.json). - Used by other modules such as notifications to provide localized content.
How it works:
- The
I18nServiceis initialized and injected by the core module. - On application startup, translation files in
assets/i18n/are registered automatically. - You can fetch translations for the current request or application using provided service methods.
- The notification system (
TimelineServiceand custom notification services) usesI18nServiceto localize notification content.
Where and when:
- The i18n system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- The application name (
APP_NAME) must be set using environment variables. - Place your translation files in the
assets/i18n/directory (e.g.,fr.json,en.json).
Example:
import { Module, Controller, Get, Req } from '@nestjs/common';
import { CoreModule, I18nService } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';
@Module({
imports: [CoreModule], // I18nModule is included automatically
})
export class AppModule {}
@Injectable()
export class MyService {
constructor(private readonly i18nService: I18nService) {}
async getTranslations(@Req() request: FastifyRequest) {
return await this.i18nService.fetchCurrentAppTranslationsForRequest(
request,
);
}
}
Note:
By default,FrontendControllerexposes an/i18nroute that serves translations for your application.
You do not need to create a custom controller or route for i18n; it is already handled by the core module.
Logger (Structured Logging)
The LoggerModule is automatically included when you import CoreModule in your application.
It provides structured logging using Pino, including access logs and request logs for your Edifice backend.
Features:
- Structured JSON logging for all requests and application events.
- Request-scoped logger (
RequestLogger) for contextual logs (user, path, method). - Access logger (
AccessLogger) for logging authentication and access events. - Integrates with NestJS and supports log levels, child loggers, and custom fields.
How it works:
- The logger is initialized and injected by the core module.
- You can inject
RequestLoggerorAccessLoggerinto your controllers, services, or middleware. - Logs are automatically enriched with request/session/user information.
Where and when:
- Logging is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- Log level and options are set using environment variables:
LOG_LEVEL=info LOG_KEEP_RAW_FIELDS=false - You can adjust these values to fit your deployment requirements.
Example:
import { Module, Controller, Get, Req } from '@nestjs/common';
import { Logger } from 'nestjs-pino';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';
@Module({
imports: [CoreModule], // LoggerModule is included automatically
})
export class AppModule {}
@Controller()
export class MyController {
constructor(private readonly logger: Logger) {}
@Get('hello')
async hello(@Req() request: FastifyRequest) {
this.logger.info({ path: request.url }, 'Hello endpoint accessed');
return { message: 'Hello world' };
}
}
Note:
You do not need to configure logging manually; it is ready to use when you import CoreModule.
All logs are structured and can be consumed by log aggregation systems.
NATS (Messaging Client Integration)
The NatsModule is automatically included when you import CoreModule in your application.
It provides a centralized NATS client for messaging, service calls, and pub/sub communication between Edifice microservices.
Features:
- Centralized NATS configuration and connection management.
- Exports a configured NATS
ClientProxyfor messaging and service communication. - Supports pub/sub and request/response patterns using NestJS decorators (
EventPattern,MessagePattern). - Includes a safe deserializer to handle non-JSON messages gracefully.
- Allows you to instantiate external service clients (like
EntNatsServiceClientfrom@edifice.io/edifice-ent-client), which use the provided NATS connection for inter-service calls. - Provides
EntNatsServiceClientfor calling external Edifice services (request/response).
How it works:
- The NATS client is initialized and injected by the core module.
- You can inject
EntNatsServiceClientto call external services. - You can use abstract subscriber classes (generated by the CLI) to handle incoming events and requests.
Where and when:
- The NATS system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- NATS connection parameters are set using environment variables:
NATS_URL=nats://localhost:4222 NATS_USER=natsuser NATS_PASSWORD=natspass NATS_DEBUG=false - You can adjust these values to fit your deployment requirements.
Calling an external service:
This example shows how to call an external Edifice service using the
EntNatsServiceClient.
The package@edifice.io/edifice-ent-clientis generated from entcore via the CLI.
It is an external dependency and uses the NATS connection provided by the core module.
import { Injectable } from '@nestjs/common';
import { EntNatsServiceClient } from '@edifice.io/edifice-ent-client';
@Injectable()
export class CommunicationService {
constructor(private readonly entServiceClient: EntNatsServiceClient) {}
async addLinkBetweenGroups(
sourceGroupId: string,
targetGroupId: string,
): Promise<boolean> {
const request = { startGroupId: sourceGroupId, endGroupId: targetGroupId };
const response = await this.entServiceClient.addLinkBetweenGroups(request);
return response.created ?? false;
}
}
Handling pub/sub and service requests:
This example shows how to subscribe to events or respond to service requests using NestJS decorators and abstract classes generated by the CLI.
import {
EventPattern,
MessagePattern,
Payload,
Ctx,
NatsContext,
} from '@nestjs/microservices';
// These abstract subscriber classes are generated by the CLI.
// You should extend them to implement your own event/message handling logic.
// Example: Subscribe to events
export abstract class BrokerSubscriber {
@EventPattern('directory.groups.deleted')
onGroupsDeleted(
@Payload() data: GroupsDeletedDTO,
@Ctx() context: NatsContext,
) {
this.handleGroupsDeletedEvent(data, context.getSubject());
}
abstract handleGroupsDeletedEvent(
data: GroupsDeletedDTO,
subject: string,
): void;
}
// Example: Respond to service requests
export abstract class AudienceSubscriber {
@MessagePattern('audience.check.right.communities.*')
onCheckResourceAccess(
@Payload() request: CheckResourceAccessRequestDTO,
@Ctx() ctx: NatsContext,
): Promise<CheckResourceAccessResponseDTO> {
return this.handleCheckAnnouncementAccess(request, ctx.getSubject());
}
abstract handleCheckAnnouncementAccess(
request: CheckResourceAccessRequestDTO,
subject: string,
): Promise<CheckResourceAccessResponseDTO>;
}
// Example: Concrete implementation
@Controller()
export class MyBrokerSubscriber extends BrokerSubscriber {
handleGroupsDeletedEvent(data: GroupsDeletedDTO, subject: string): void {
// Your custom logic here
console.log(
`Groups deleted: ${JSON.stringify(data)} from subject: ${subject}`,
);
}
}
@Controller()
export class MyAudienceSubscriber extends AudienceSubscriber {
async handleCheckAnnouncementAccess(
request: CheckResourceAccessRequestDTO,
subject: string,
): Promise<CheckResourceAccessResponseDTO> {
// Your custom logic here
return { accessGranted: true };
}
}
Note:
- You do not need to configure NATS manually; it is ready to use when you import
CoreModule. - Use
EntNatsServiceClientfor external service calls, and abstract subscriber classes for pub/sub and request/response patterns. - The CLI can generate abstract subscriber classes to help you implement event and message handlers.
Permission (Authorization Guards & Decorators)
The PermissionModule is automatically included when you import CoreModule in your application.
It provides decorators and guards for workflow-based and admin authorization, enabling fine-grained access control for your endpoints.
Features:
@RequirePermission('PERMISSION_NAME'): Restricts access to endpoints based on user workflow rights. Mandatory decorator.@RequireAdmc(): Restricts access to endpoints for super administrators (ADMC).@Public(): Marks endpoints as public (no authentication required).@BasicAuth(): Adds Basic authorization method for an endpoint. The authorized user and password are set in configuration.
How it works:
- Decorators set metadata on your controllers and endpoints.
- Guards read this metadata and check the user's session and permissions.
- Permissions are automatically registered at startup by the AppRegistry service.
Where and when:
- The permission system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- User permissions and roles are provided in the session object (
entSession). - Workflow rights are defined in your business logic and registered via decorators.
Example:
import { Controller, Get, Post } from '@nestjs/common';
import {
RequirePermission,
RequireAdmc,
Public,
CoreModule,
} from '@edifice.io/edifice-nestjs-core';
@Module({
imports: [CoreModule], // PermissionModule is included automatically
})
export class AppModule {}
@Controller('resources')
export class ResourceController {
@Get()
@RequirePermission('COMMUNITY_ACCESS')
async findAll() {
// Only users with COMMUNITY_ACCESS permission can access this endpoint
}
@Post('/admin')
@RequireAdmc() // Only super administrators can access this endpoint
async adminTask() {
// Admin logic here
}
@Get('public-info')
@Public()
async publicInfo() {
// This endpoint is accessible without authentication
}
}
Note:
You do not need to configure permission guards manually; they are ready to use when you import CoreModule.
All permissions are automatically registered and enforced for your endpoints.
Session (User Session Management)
The SessionModule is automatically included when you import CoreModule in your application.
It provides middleware, decorators, and helpers for managing user sessions in your Edifice backend.
Features:
- Middleware to validate and attach user sessions to each request.
- Session decorator (
@Session()) to inject the session directly into your controller methods. - Exposes session information on the raw Fastify request object (
request.raw.entSession). - Integrates with the ENT service via NATS for session validation and refresh.
How it works:
- The session middleware runs on every API request, validates the session via the ENT service, and attaches it to the request.
- You can access the session in your controllers using either the
@Session()decorator or directly from the request object.
Where and when:
- The session system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- Session validation uses the NATS connection provided by the core module.
Example:
import { Controller, Get, Req } from '@nestjs/common';
import { CoreModule, Session } from '@edifice.io/edifice-nestjs-core';
import { FastifyRequest } from 'fastify';
import { ENTUserSession } from '@edifice.io/edifice-ent-client';
@Module({
imports: [CoreModule], // SessionModule is included automatically
})
export class AppModule {}
@Controller('profile')
export class ProfileController {
@Get()
async getProfile(@Session() session: ENTUserSession) {
// Access session directly via decorator
return { userId: session.userId, name: session.displayName };
}
@Get('raw')
async getProfileRaw(@Req() request: FastifyRequest) {
// Access session via Fastify request object
const session = request.raw.entSession;
return { userId: session.userId, name: session.displayName };
}
}
Note:
You do not need to configure session management manually; it is ready to use when you import CoreModule.
Session information is available in all controllers and can be accessed via the decorator or the request object.
Timeline (Notification Service)
The TimelineModule is automatically included when you import CoreModule in your application.
It provides services for registering notification templates and sending notifications to users via the Edifice timeline system.
Features:
- Register notification templates for your application.
- Send notifications to users (with push, mail, and preview options).
- Integrates with the ENT client and NATS for delivery.
- Supports localization via the I18n service.
How it works:
- The
TimelineServiceis initialized and injected by the core module. - You can register notification templates at startup or on demand.
- You can send notifications to users by calling the service methods.
Where and when:
- The timeline system is initialized automatically at application startup by
CoreModule. - No manual configuration is needed; all dependencies are wired by the core module.
Configuration:
- The application name (
APP_NAME) must be set using environment variables. - Notification templates can be registered at module initialization or dynamically.
Registering notification templates:
When you register a notification template, you provide a RegisterNotificationRequestDTO object.
This object describes how your notification will appear and behave in the Edifice timeline system.
Main fields in RegisterNotificationRequestDTO:
-
notificationName(string):
Unique identifier for your notification event (e.g.,"MY_EVENT"). -
title(string):
Title displayed to the user in the timeline. -
body(string):
Main content or message of the notification (can include HTML). -
appAddress(string, optional):
URL path to access the application or resource related to the notification. -
defaultFrequency(IMMEDIATE|DAILY|WEEKLY|NEVER, optional):
Default delivery frequency for the notification. -
restriction(NONE|INTERNAL|EXTERNAL|HIDDEN, optional):
Restriction level for visibility (e.g., only internal users). -
pushNotif(object, optional):
Push notification options, such as title and body for mobile/web push. -
preview(object, optional):
Preview configuration for the notification. -
params(object, optional):
Custom parameters for dynamic content or links.
Example:
const template: RegisterNotificationRequestDTO = {
notificationName: 'MY_EVENT',
title: 'My Event',
body: '<b>A new event occurred!</b>',
appAddress: '/events/123',
defaultFrequency: 'IMMEDIATE',
restriction: 'NONE',
pushNotif: {
title: 'Event!',
body: 'You have a new event.',
},
preview: {
imageUrl: '/assets/event.png',
description: 'Preview of the event notification',
},
params: {
resourceId: '123',
customParam: 'value',
},
};
import { Injectable, OnModuleInit } from '@nestjs/common';
import { TimelineService } from '@edifice.io/edifice-nestjs-core';
import { RegisterNotificationRequestDTO } from '@edifice.io/edifice-ent-client';
@Injectable()
export class MyNotificationService implements OnModuleInit {
constructor(private readonly timelineService: TimelineService) {}
async onModuleInit() {
const templates: RegisterNotificationRequestDTO[] = [
{
notificationName: 'MY_EVENT',
title: 'My Event',
body: 'A new event occurred!',
// ...other template fields
},
];
await this.timelineService.registerNotifications(templates);
}
}
Sending a notification:
import { TimelineService } from '@edifice.io/edifice-nestjs-core';
import {
SessionDto,
SendNotificationRequestDTO,
} from '@edifice.io/edifice-ent-client';
@Injectable()
export class MyService {
constructor(private readonly timelineService: TimelineService) {}
async sendNotification(session: SessionDto) {
const notification: SendNotificationRequestDTO = {
notificationName: 'MY_EVENT',
recipientIds: ['userId1', 'userId2'],
resourceUri: '/resource/123',
params: { customParam: 'value' },
pushNotif: {
title: 'Event!',
body: 'You have a new event.',
},
};
await this.timelineService.sendNotification(session, notification);
}
}
Note:
- You do not need to configure the timeline system manually; it is ready to use when you import
CoreModule. - Notifications are localized using the I18n service and delivered via NATS and the ENT client.
Swagger (OpenAPI Documentation)
The Swagger module is automatically enabled when you import CoreModule in your application (unless you disable it via environment variables).
It provides an interactive OpenAPI documentation for your API, available at /openapi.
Features:
- Auto-generates OpenAPI documentation from your controllers and DTOs.
- Serves the Swagger UI at
/openapiby default. - Supports custom title, description, version, and server URL via environment variables.
How it works:
- On application startup, Swagger is configured and started automatically if
ENABLE_SWAGGER=true(default). - The configuration is read from environment variables and injected via
ConfigService.
Configuration: Set the following environment variables to customize Swagger:
ENABLE_SWAGGER=true
SWAGGER_SERVER_URL=https://api.example.com
SWAGGER_TITLE=My Edifice API
SWAGGER_DESCRIPTION=API documentation for my Edifice backend
VERSION=1.0.0
Note:
You do not need to configure Swagger manually; it is ready to use when you import CoreModule.
Access your API documentation at /openapi.
Utilities
- Bootstrap: Application bootstrap helpers
- Entity Naming: Database entity naming conventions
- Static Assets: Static file serving utilities
📖 Usage
Basic Setup
import { Module } from '@nestjs/common';
import { CoreModule } from '@edifice.io/edifice-nestjs-core';
@Module({
imports: [CoreModule],
})
export class AppModule {}
CLI Tools
This package provides several CLI tools to help you automate common backend tasks.
Each tool is available as a binary when you install @edifice.io/edifice-nestjs-core.
- edifice-generate-entities: Generate MikroORM entities from database schema
- edifice-generate-metadata: Generate application metadata file
- edifice-k6-sync-dto: Synchronize DTOs for K6 Testing
- generate-swagger-pdf: Generate a PDF from your NestJS API Swagger documentation
Generate entities
Purpose:
Generate MikroORM entity files from your PostgreSQL database schema.
Usage:
pnpm edifice-generate-entities --schema <schema-name> [options]
Arguments:
--schema(required): Name of the database schema to use for entity generation.--path: Target directory for generated entities (default:./src/entities).--temp-dir: Temporary directory for initial generation (default:./src/temp/entities).--mapping-config: Path to entity-module mapping file (default:./src/config/entity-mapping.config.json).--keep-temp: Keep temporary directory after generation (trueorfalse, default:false).
Examples:
pnpm edifice-generate-entities --schema community
pnpm edifice-generate-entities --schema community --temp-dir ./src/temp --path ./src/entities
pnpm edifice-generate-entities --schema community --mapping-config ./src/config/entity-mapping.config.json
pnpm edifice-generate-entities --schema community --keep-temp true
Generate metadata
Purpose:
Generate a build metadata file containing build date, git commit hash, and branch name.
Usage:
pnpm edifice-generate-metadata <target-file-path>
Arguments:
<target-file-path>(required): Path to the file where metadata will be written.
Example:
pnpm edifice-generate-metadata ./dist/metadata.txt
Sync K6 DTO
Purpose:
Synchronize DTO TypeScript definitions to K6-compatible types for API testing.
Usage:
pnpm edifice-k6-sync-dto
Arguments:
This script uses configuration constants for DTOs and output paths.
You can adjust the paths in the script or via environment variables if supported.
Example:
pnpm edifice-k6-sync-dto
Details:
- Parses DTOs from
client/rest/src/dtos. - Generates K6-compatible types in
types/generated. - Excludes files named
index.tsby default.
generate-swagger-pdf
Purpose:
Generate a PDF from the Swagger (OpenAPI) documentation exposed by your NestJS server.
Usage:
npx generate-swagger-pdf --host <host> --port <port>
Options:
--host,-h: Swagger server host (default:127.0.0.1)--port,-p: Swagger server port (default:3002)
The PDF will be generated in the documentation/api-docs.pdf folder of your project.
Example:
npx generate-swagger-pdf --host 127.0.0.1 --port 4000
This package provides several CLI tools to help you automate common backend tasks.
Each tool is available as a binary when you install @edifice.io/edifice-nestjs-core.
- edifice-generate-entities: Generate MikroORM entities from database schema
- edifice-generate-metadata: Generate application metadata file
- edifice-k6-sync-dto: Synchronize DTOs for K6 Testing
- generate-swagger-pdf: Generate a PDF from your NestJS API Swagger documentation
Note:
All CLI tools are available after installing the package.
You can run them with pnpm or npx from your project root.
🔧 Configuration
The core module uses NestJS ConfigModule for configuration. You can provide configuration through environment variables or configuration files.
Environment Variables
DATABASE_URL: PostgreSQL connection stringNATS_URL: NATS server URLLOG_LEVEL: Logging level (debug, info, warn, error)NODE_ENV: Environment (development, production)
🛠 Development
# Install dependencies
pnpm install
# Build
pnpm build
# Format code
pnpm format
# Lint code
pnpm lint
🔗 Related Packages
- @edifice.io/edifice-ent-client - Edifice ENT client library
🐛 Issues
Report issues on GitHub Issues.