Zum Hauptinhalt springen

Plugin Development Guide

Create custom plugins to extend Ever Gauzy functionality.

Overview​

Gauzy's plugin architecture allows developers to add new features, integrations, and modules without modifying the core codebase.

Plugin Structure​

A typical plugin follows this directory structure:

packages/plugins/my-plugin/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ lib/
β”‚ β”‚ β”œβ”€β”€ my-plugin.module.ts # Main module
β”‚ β”‚ β”œβ”€β”€ my-plugin.service.ts # Business logic
β”‚ β”‚ β”œβ”€β”€ my-plugin.controller.ts # REST endpoints
β”‚ β”‚ └── my-plugin.entity.ts # Database entities
β”‚ └── index.ts # Public API exports
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── README.md

Creating a Plugin​

1. Scaffold the Plugin​

# Create the plugin directory
mkdir -p packages/plugins/my-plugin/src/lib

2. Define the Module​

// my-plugin.module.ts
import { Module } from "@nestjs/common";
import { TypeOrmModule } from "@nestjs/typeorm";
import { MikroOrmModule } from "@mikro-orm/nestjs";
import { MyPluginService } from "./my-plugin.service";
import { MyPluginController } from "./my-plugin.controller";
import { MyEntity } from "./my-plugin.entity";

@Module({
imports: [
TypeOrmModule.forFeature([MyEntity]),
MikroOrmModule.forFeature([MyEntity]),
],
controllers: [MyPluginController],
providers: [MyPluginService],
exports: [MyPluginService],
})
export class MyPluginModule {}

3. Create an Entity​

// my-plugin.entity.ts
import { MultiORMEntity, MultiORMColumn } from "@gauzy/core";
import { TenantOrganizationBaseEntity } from "@gauzy/core";

@MultiORMEntity("my_entity")
export class MyEntity extends TenantOrganizationBaseEntity {
@MultiORMColumn()
name: string;

@MultiORMColumn({ nullable: true })
description?: string;
}

4. Create a Service​

// my-plugin.service.ts
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { TenantAwareCrudService } from "@gauzy/core";
import { MyEntity } from "./my-plugin.entity";

@Injectable()
export class MyPluginService extends TenantAwareCrudService<MyEntity> {
constructor(
@InjectRepository(MyEntity)
private readonly myRepository: Repository<MyEntity>,
) {
super(myRepository);
}
}

5. Create a Controller​

// my-plugin.controller.ts
import { Controller, UseGuards } from "@nestjs/common";
import { ApiTags } from "@nestjs/swagger";
import { CrudController } from "@gauzy/core";
import { TenantPermissionGuard, PermissionGuard } from "@gauzy/core";
import { MyEntity } from "./my-plugin.entity";
import { MyPluginService } from "./my-plugin.service";

@ApiTags("MyPlugin")
@UseGuards(TenantPermissionGuard, PermissionGuard)
@Controller("/my-plugin")
export class MyPluginController extends CrudController<MyEntity> {
constructor(private readonly service: MyPluginService) {
super(service);
}
}

6. Register the Plugin​

Add the plugin module to the application's main module:

// In app.module.ts or plugin registration
import { MyPluginModule } from "@gauzy/plugin-my-plugin";

@Module({
imports: [
// ... other modules
MyPluginModule,
],
})
export class AppModule {}

Plugin Lifecycle​

PhaseDescription
DiscoveryPlugin package is found in node_modules
RegistrationModule is imported and providers registered
InitializationDatabase entities are synced, services initialized
ReadyPlugin is fully operational
ShutdownCleanup on application shutdown

Best Practices​

  1. Extend base classes β€” use TenantOrganizationBaseEntity and TenantAwareCrudService
  2. Multi-ORM support β€” use MultiORMEntity and MultiORMColumn decorators
  3. Guard all endpoints β€” apply TenantPermissionGuard and PermissionGuard
  4. Use DTOs β€” create validation DTOs for all inputs
  5. Document API β€” apply @ApiTags and @ApiOperation decorators