Demo

Module lifecycle

Backend plugin pack / load / teardown — @Module နှင့် lifecycle hook များ (@OnInit, @OnAllModuleLoaded, @OnUninstall)။

IPlugin entry

backend/src/index.ts သည် IPlugin ကို implement လုပ်သော class ကို default-export လုပ်ရပါသည်။ Root @Module class နှင့် module.metadata.json မှ metadata ကို ပြန်ပေးပါသည်။

TSXbackend/src/index.ts
1import type { IPlugin, PluginMetadata } from "@quan-erp/shared-types"; 2import metadata from "../module.metadata.json" with { type: "json" }; 3import { MyPluginModule } from "./my-plugin.module.js"; 4 5export default class MyPlugin implements IPlugin { 6 getRootModule() { return MyPluginModule; } 7 getName() { return metadata.name; } 8 getVersion() { return metadata.pluginVersion; } 9 getMetadata() { return metadata as PluginMetadata; } 10}

Root @Module

Providers၊ controllers၊ entities (plugin: "default") နှင့် optional websocket handler များကို မှတ်ပုံတင်ရပါသည်။ Module-level cache အတွက် @Cache နှင့် တွဲသုံးနိုင်ပါသည်။ Lifecycle hook များကို များသောအားဖြင့် ဤ class (သို့မဟုတ် @Service) ပေါ်တွင် ထားရှိရပါသည်။

  • @Module({ name, providers, controllers, entities, websocket? })
  • @Cache(options) — in-memory သို့မဟုတ် redis; @Module class ပေါ်တွင်သာ
TSXmodule
1import { Cache, Module } from "@quan-erp/shared-backend-core"; 2import metadata from "../../module.metadata.json" with { type: "json" }; 3import { ChatWebsocket } from "./chat.websocket.js"; 4import { MyController } from "./my.controller.js"; 5import { MyEntity } from "./my.entity.js"; 6import { MyService } from "./my.service.js"; 7 8@Module({ 9 name: metadata.name, 10 providers: [MyService], 11 controllers: [MyController], 12 entities: [{ plugin: "default", entities: [MyEntity] }], 13 websocket: [ChatWebsocket], 14}) 15@Cache({ type: "in-memory", checkperiod: 1000 }) 16export class MyPluginModule {}

Lifecycle annotations

Boot နှင့် teardown အတွက် hook သုံးခု ရှိပါသည်။ Root @Module (သို့မဟုတ် DI-managed @Service) ပေါ်ရှိ method များတွင် အသုံးပြုရပါသည်။

  • @OnInit() — ဤ module/service အဆင်သင့်; seed / local setup
  • @OnAllModuleLoaded() — module အားလုံး @OnInit ပြီး; workers၊ cron listeners၊ cross-plugin
  • @OnUninstall() — plugin ဖယ်ရှားချိန်; queue/worker cleanup

@OnInit

Host module သို့မဟုတ် service အပြည့်အစုံ initialize ပြီးနောက် တစ်ကြိမ် အလုပ်လုပ်ပါသည်။ Default settings / seed အတွက် သင့်တော်ပါသည်။ Cross-plugin worker များကို ဤနေရာတွင် မစရပါ — @OnAllModuleLoaded ကို အသုံးပြုရပါသည်။

TSX@OnInit on module
1import { 2 ContainerRegistryManager, 3 DataSeedHistoryService, 4 Inject, 5 InjectBuiltinLogger, 6 Module, 7 OnInit, 8} from "@quan-erp/shared-backend-core"; 9import type { Loggable } from "@quan-erp/shared-backend-core"; 10import metadata from "../../module.metadata.json" with { type: "json" }; 11import { MyService } from "./my.service.js"; 12 13@Module({ 14 name: metadata.name, 15 providers: [MyService], 16 controllers: [], 17 entities: [], 18}) 19export class MyPluginModule { 20 @InjectBuiltinLogger() 21 logger: Loggable; 22 23 @Inject(DataSeedHistoryService, ContainerRegistryManager.BUILTIN_PLUGIN) 24 dataSeedHistoryService: DataSeedHistoryService; 25 26 @OnInit() 27 async init() { 28 const alreadySeeded = await this.dataSeedHistoryService.find( 29 metadata.name, 30 metadata.pluginVersion, 31 "init", 32 ); 33 if (alreadySeeded) { 34 this.logger.log("Seeding skipped (already initialized)"); 35 return; 36 } 37 // … seed defaults … 38 await this.dataSeedHistoryService.add({ 39 data: { 40 pluginName: metadata.name, 41 pluginVersion: metadata.pluginVersion, 42 name: "init", 43 }, 44 }); 45 this.logger.log("Module seeded successfully"); 46 } 47}
TSX@OnInit on service
1import { InjectBuiltinLogger, OnInit, Service } from "@quan-erp/shared-backend-core"; 2import type { Loggable } from "@quan-erp/shared-backend-core"; 3 4@Service() 5export class CacheWarmupService { 6 @InjectBuiltinLogger() 7 logger: Loggable; 8 9 @OnInit() 10 async init() { 11 this.logger.log("Warming local caches"); 12 // … 13 } 14}

@OnAllModuleLoaded

Installed module အားလုံး @OnInit ပြီးဆုံးပြီးနောက် တစ်ကြိမ် အလုပ်လုပ်ပါသည်။ Background worker၊ CronJobService listener သို့မဟုတ် အခြား plugin service လိုအပ်သော အလုပ်အတွက် အသုံးပြုရပါသည်။

TSX@OnAllModuleLoaded
1import { 2 ContainerRegistryManager, 3 CronJobService, 4 Inject, 5 InjectBuiltinLogger, 6 Module, 7 OnAllModuleLoaded, 8} from "@quan-erp/shared-backend-core"; 9import type { Loggable } from "@quan-erp/shared-backend-core"; 10import metadata from "../../module.metadata.json" with { type: "json" }; 11import { MaturedSweepService } from "./matured-sweep.service.js"; 12 13@Module({ 14 name: metadata.name, 15 providers: [MaturedSweepService], 16 controllers: [], 17 entities: [], 18}) 19export class MyPluginModule { 20 @InjectBuiltinLogger() 21 logger: Loggable; 22 23 @Inject(CronJobService, ContainerRegistryManager.BUILTIN_PLUGIN) 24 cronJobService: CronJobService; 25 26 @Inject(MaturedSweepService) 27 sweep: MaturedSweepService; 28 29 @OnAllModuleLoaded() 30 async onAllModuleLoaded() { 31 this.logger.log("All modules loaded — attaching cron listeners"); 32 this.cronJobService.addEventListener( 33 metadata.name, 34 "matured-sweep", 35 () => this.sweep.run(), 36 ); 37 } 38}

@OnUninstall

Plugin ကို system မှ uninstall လုပ်သောအခါ အလုပ်လုပ်ပါသည်။ @OnInit / @OnAllModuleLoaded တွင် စတင်ထားသော Redis/BullMQ worker၊ socket စသည်ကို ဖြတ်တောက်ရပါသည်။

TSX@OnUninstall
1import { 2 InjectBuiltinLogger, 3 Module, 4 OnUninstall, 5} from "@quan-erp/shared-backend-core"; 6import type { Loggable } from "@quan-erp/shared-backend-core"; 7import metadata from "../../module.metadata.json" with { type: "json" }; 8import { BackgroundWorker } from "./background.worker.js"; 9 10@Module({ 11 name: metadata.name, 12 providers: [BackgroundWorker], 13 controllers: [], 14 entities: [], 15}) 16export class MyPluginModule { 17 @InjectBuiltinLogger() 18 logger: Loggable; 19 20 private worker = new BackgroundWorker(); 21 22 @OnUninstall() 23 async cleanup() { 24 this.logger.log("Uninstalling — stopping worker"); 25 await this.worker.disconnect(); 26 } 27}

Boot & teardown order

  1. 01

    Installed plugin များကို စကင်ခြင်း

    installed=true ရှိသော module များသာ installed-plugins မှ load ဖြစ်ပါသည်။

  2. 02

    module.js ကို import လုပ်ခြင်း

    IPlugin ကို instantiate လုပ်ပြီး getRootModule() ခေါ်ပါသည်။

  3. 03

    DI + entities

    Service များကို ချိတ်ဆက်ပြီး ဇယားများကို sync လုပ်ပါသည်။

  4. 04

    @OnInit

    Module/service အလိုက် init — seed နှင့် local setup။

  5. 05

    @OnAllModuleLoaded

    Cross-module hook — workers၊ cron listeners။

  6. 06

    @OnUninstall

    Plugin ဖယ်ရှားချိန် — resource cleanup။

Build lifecycle

quan-erp watch <plugin> (သို့မဟုတ် အချို့ repo တွင် quan-erp watch) ဖြင့် backend + frontend ကို base/available-plugins/ သို့ compile လုပ်ပြီး ERP UI မှ install လုပ်ရပါသည်။