Demo

Database source အသစ် ထည့်သွင်းခြင်း

အများအားဖြင့် shared default DataSource ကို ဦးစားပေး အသုံးပြုရပါသည်။ Isolation လိုအပ်မှသာ root module ပေါ်တွင် @Database ဖြင့် TypeORM connection အပို ဖွင့်ရပါသည်။ Entities ကို ထို plugin + name သို့ register လုပ်ပြီး @InjectDatabaseSource ဖြင့် inject လုပ်ရပါမည်။

ပန်းတိုင်နှင့် မည်သည့်အခါ အသုံးပြုမည်နည်း

Plugin table အများစုသည် shared core Postgres connection ပေါ်တွင် ရှိသင့်ပါသည်။ သီးခြား host၊ schema၊ reporting ဒေတာဘေ့စ် သို့မဟုတ် replica လိုအပ်မှသာ custom source ထည့်သွင်းပါ။

  • Default ကို ဦးစားပေးပါ — entities ကို plugin: "default" ဖြင့် register လုပ်ပါ (@Database မလိုအပ်ပါ)
  • Custom — root @Module class ပေါ်တွင်သာ @Database({ name?, options }) တပ်ရပါသည်
  • ပြန်လည်အသုံးပြုခြင်း — အခြား plugin က ပိုင်ဆိုင်သူ၏ connection ကို inject လုပ်ပါ; @Database ထပ်မံ မကြေညာရပါ

1. လိုအပ်ချက်များ

အလုပ်လုပ်နေသော plugin backend module နှင့် env (PluginEnv / base .env) မှ credentials များ လိုအပ်ပါသည်။

  • Root @Module({ name: metadata.name, … }) ဖြင့် scaffold လုပ်ပြီးသား ဖြစ်ရပါမည်
  • Host၊ port၊ username၊ password၊ database ကို env မှ ရယူပါ — secret များကို hardcode မလုပ်ရပါ
  • Custom source အတွက် synchronize: false သတ်မှတ်ပြီး schema ကို migration ဖြင့် ပို့ဆောင်ပါ
  • အခြား plugin ၏ DB ကို inject လုပ်မည်ဆိုပါက ပိုင်ဆိုင်သူကို pluginDependencies တွင် ထည့်သွင်းပါ

2. Default DataSource ကို ဦးစားပေးခြင်း

Isolation မလိုအပ်ပါက shared connection သို့ ပေါင်းထည့်ပါ။ DataSourceManager.DEFAULT_PLUGIN (သို့မဟုတ် string "default") ဖြင့် inject လုပ်ပါ။

  • Table အမည်သည် metadata.name ဖြင့် စရပါမည်
  • create / update / soft-delete column များအတွက် BaseEntity ကို တိုးချဲ့ပါ
  • @Database decorator မလိုအပ်ပါ — core က "default" ကို ပိုင်ဆိုင်ပြီးသား ဖြစ်ပါသည်
TSXentities on default
1@Module({ 2 name: metadata.name, 3 providers: [OrderService], 4 controllers: [OrderController], 5 entities: [ 6 { 7 plugin: "default", 8 entities: [OrderEntity], 9 }, 10 ], 11}) 12export class MyPluginModule {}
TSXinject default
1import { DataSource } from "typeorm"; 2import { 3 InjectDatabaseSource, 4 DataSourceManager, 5 Service, 6} from "@quan-erp/shared-backend-core"; 7 8@Service() 9export class OrderService { 10 @InjectDatabaseSource(DataSourceManager.DEFAULT_PLUGIN) 11 source: DataSource; 12}

3. Custom @Database ထည့်သွင်းခြင်း

Connection ကို root @Module ပေါ်တွင် ကြေညာရပါသည်။ Entities ကို plugin: metadata.name နှင့် တူညီသော optional name ဖြင့် register လုပ်ပါ။ @InjectDatabaseSource(metadata.name, name?) ဖြင့် inject လုပ်ရပါသည်။

  • @Database({ name?, options }) — ပိုင်ဆိုင်သူကို loading plugin မှ ဖြည့်ပေးပါသည်
  • name — plugin တစ်ခုက connection အများအပြား ဖွင့်လျှင် လိုအပ်ပါသည်
  • options — TypeORM DataSourceOptions; credentials ကို env မှ တင်သွင်းပါ
  • Staging / production တွင် custom source အတွက် synchronize: false သုံးပါ
  • Entities — ကိုက်ညီသော plugin + name; options.entities ကို မမှီခိုရပါ
TSXroot module — custom source
1import { 2 Database, 3 Module, 4} from "@quan-erp/shared-backend-core"; 5import metadata from "../../module.metadata.json" with { type: "json" }; 6import { AnalyticsEntity } from "./analytics.entity.js"; 7import { AnalyticsService } from "./analytics.service.js"; 8 9@Database({ 10 name: "analytics", 11 options: { 12 type: "postgres", 13 host: process.env.ANALYTICS_DB_HOST, 14 port: Number(process.env.ANALYTICS_DB_PORT ?? 5432), 15 username: process.env.ANALYTICS_DB_USERNAME, 16 password: process.env.ANALYTICS_DB_PASSWORD, 17 database: process.env.ANALYTICS_DB_SCHEMA, 18 synchronize: false, 19 }, 20}) 21@Module({ 22 name: metadata.name, 23 providers: [AnalyticsService], 24 controllers: [], 25 entities: [ 26 { 27 plugin: metadata.name, 28 name: "analytics", 29 entities: [AnalyticsEntity], 30 }, 31 ], 32}) 33export class MyPluginModule {}
TSinject custom
@InjectDatabaseSource(metadata.name, "analytics") analyticsSource: DataSource;

4. Cross-plugin inject

Connection များသည် ပိုင်ဆိုင်သော plugin (+ optional name) ဖြင့် process-wide registry တွင် ရှိပါသည်။ Consumer က ပိုင်ဆိုင်သူ၏ DataSource ကို inject လုပ်ပြီး၊ လိုအပ်ပါက ထို plugin + name သို့ ကိုယ်ပိုင် entity များကို register လုပ်နိုင်ပါသည်။

  • ပိုင်ဆိုင်သူ — @Database ကြေညာပြီး အရင် boot လုပ်ရပါသည် (pluginDependencies တွင် စာရင်းသွင်းပါ)
  • Consumer — @InjectDatabaseSource("owner-plugin", "connection-name?")
  • Foreign entities — entities entry တွင် plugin: "owner-plugin" နှင့် name: "connection-name" သုံးပါ
  • Consumer တိုင်းတွင် တူညီသော @Database ကို ထပ်မံ မကြေညာရပါ
TSconsumer service
1@Service() 2export class ReportService { 3 // "warehouse" plugin declared @Database({ name: "replica", ... }) 4 @InjectDatabaseSource("warehouse", "replica") 5 warehouseReplica: DataSource; 6}

5. စစ်ဆေးခြင်း

  • Plugin boot လုပ်ရာတွင် DI / DataSource အမှား မရှိရပါ
  • Inject လုပ်ထားသော DataSource သတ်မှတ်ပြီး getRepository(Entity) အလုပ်လုပ်ရပါသည်
  • Entities သည် ရည်ရွယ်ထားသော connection ပေါ်တွင် ပေါ်ရပါသည် (default vs custom name)
  • Env credentials သည် Docker / staging နှင့် local တူညီစွာ ဖြေရှင်းရပါသည်

အဖြစ်များသော အမှားများ

  • @Database ကို service သို့မဟုတ် nested module ပေါ်တွင် တပ်ခြင်း — root @Module ပေါ်တွင်သာ တပ်ရပါသည်
  • Custom DB entities ကို plugin: "default" (သို့မဟုတ် မှားသော name) ဖြင့် register လုပ်ခြင်း
  • Password ကို hardcode လုပ်ခြင်း — PluginEnv / base .env ကို အသုံးပြုရပါသည်
  • Production တွင် custom source ၏ synchronize: true သုံးခြင်း
  • Consumer တွင် @Database ထပ်မံ ကြေညာခြင်း — @InjectDatabaseSource ကို သုံးရပါသည်
  • pluginDependencies မေ့ခြင်း — ပိုင်ဆိုင်သူက consumer နောက်မှ load ဖြစ်သွားပါသည်