Demo

Database

Quark ERP သည် PostgreSQL ပေါ်တွင် TypeORM ကို အသုံးပြုပါသည်။ အများအားဖြင့် shared default DataSource ကို အသုံးပြုရပါသည်။ Plugin တစ်ခုသည် @Database ဖြင့် connection တစ်ခု သို့မဟုတ် အများအပြား ဖွင့်နိုင်ပြီး၊ အခြား plugin များက owner plugin name (နှင့် optional connection name) ဖြင့် ထို connection ကို inject လုပ်သုံးနိုင်ပါသည်။

Stack

  • PostgreSQL — အဓိက persistent store (PluginEnv / base .env မှ env)
  • TypeORM — entities၊ repositories၊ QueryRunner၊ migrations
  • Default datasource — shared core; plugin: "default" ဖြင့် merge
  • Custom datasource — root @Module ပေါ်တွင် @Database; named connection အများအပြား ဖွင့်နိုင်ပါသည်
  • Cross-plugin — @InjectDatabaseSource("other-plugin", "connection-name?")

@InjectDatabaseSource

Service property ပေါ်တွင် TypeORM DataSource ကို inject လုပ်ရပါသည် (constructor injection မထောက်ပံ့ပါ)။ ပထမ arg သည် connection ပိုင်သော plugin; ဒုတိယ arg သည် optional connection name ဖြစ်ပါသည်။

  • DataSourceManager.DEFAULT_PLUGIN — အဓိက core datasource
  • metadata.name — ဤ plugin ပိုင် default custom connection
  • "other-plugin" — အခြား plugin က ဖန်တီးထားသော connection
  • ဒုတိယ arg name — owner plugin တွင် @Database အများအပြား ရှိလျှင် (ဥပမာ "analytics")
TSXinject
1import { DataSource } from "typeorm"; 2import { 3 InjectDatabaseSource, 4 DataSourceManager, 5 Service, 6} from "@quan-erp/shared-backend-core"; 7import metadata from "../../module.metadata.json" with { type: "json" }; 8import { OrderEntity } from "./order.entity.js"; 9 10@Service() 11export class OrderService { 12 // Shared core Postgres 13 @InjectDatabaseSource(DataSourceManager.DEFAULT_PLUGIN) 14 source: DataSource; 15 16 // This plugin’s own connection (default name) 17 @InjectDatabaseSource(metadata.name) 18 pluginSource: DataSource; 19 20 // This plugin’s named connection 21 @InjectDatabaseSource(metadata.name, "analytics") 22 analyticsSource: DataSource; 23 24 // Connection owned by another plugin 25 @InjectDatabaseSource("warehouse", "replica") 26 warehouseReplica: DataSource; 27 28 private get repo() { 29 return this.source.getRepository(OrderEntity); 30 } 31}

Entity သတ်မှတ်ခြင်း

ဇယားအမည်များသည် plugin name ဖြင့် စရပါမည်။ Template literal တွင် metadata.name ကို အသုံးပြုရပါသည်။ create/update/soft-delete ကော်လံများအတွက် BaseEntity ကို အမြဲ extend လုပ်ရပါသည်။

TSXentity
1import { BaseEntity } from "@quan-erp/shared-backend-core"; 2import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"; 3import metadata from "../../../../module.metadata.json" with { type: "json" }; 4 5@Entity(`${metadata.name}_driver_document`) 6export class DriverDocumentEntity extends BaseEntity { 7 @PrimaryGeneratedColumn("increment") 8 id: number; 9 10 @Column() 11 documentName: string; 12}

Module တွင် မှတ်ပုံတင်ခြင်း

Entity များကို datasource အလိုက် အုပ်စုဖွဲ့ရပါသည်။ Primary shared connection အတွက် plugin: "default"။ Custom @Database အတွက် plugin (နှင့် optional name) ကို ထို connection နှင့် ကိုက်အောင် သတ်မှတ်ရပါသည်။

TSXdefault datasource
1import { Module } from "@quan-erp/shared-backend-core"; 2import metadata from "../../module.metadata.json" with { type: "json" }; 3import { OrderController } from "./order.controller.js"; 4import { OrderService } from "./order.service.js"; 5import { DriverDocumentEntity } from "./driver-document.entity.js"; 6 7@Module({ 8 name: metadata.name, 9 providers: [OrderService], 10 controllers: [OrderController], 11 entities: [ 12 { 13 plugin: "default", 14 entities: [DriverDocumentEntity], 15 }, 16 ], 17}) 18export class MyPluginModule {}

Custom datasource (@Database)

Root module ပေါ်တွင် @Database တစ်ခု သို့မဟုတ် အများအပြားဖြင့် TypeORM connection ကြေညာရပါသည်။ သီးခြား host/schema၊ reporting DB၊ replica စသည် တကယ်လိုမှသာ အသုံးပြုရပါသည်။ Credentials ကို env မှ ယူရပါသည်။

  • @Database({ name?, options }) — root @Module class ပေါ်တွင်
  • name — plugin တစ်ခုတွင် DB အများအပြား ဖွင့်လျှင် လိုအပ်ပါသည်
  • options — TypeORM DataSourceOptions
  • Entities — plugin + name ကိုက်အောင် မှတ်ပုံတင်ရပါသည်
  • Module class တစ်ခုပေါ်တွင် @Database အများအပြား = connection အများအပြား
TSXmultiple connections in one plugin
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 { WarehouseEntity } from "./warehouse.entity.js"; 8import { AnalyticsService } from "./analytics.service.js"; 9 10@Database({ 11 name: "analytics", 12 options: { 13 type: "postgres", 14 host: process.env.ANALYTICS_DB_HOST, 15 port: Number(process.env.ANALYTICS_DB_PORT ?? 5432), 16 username: process.env.ANALYTICS_DB_USERNAME, 17 password: process.env.ANALYTICS_DB_PASSWORD, 18 database: process.env.ANALYTICS_DB_SCHEMA, 19 synchronize: process.env.ANALYTICS_DB_SYNC === "true", 20 }, 21}) 22@Database({ 23 name: "replica", 24 options: { 25 type: "postgres", 26 host: process.env.REPLICA_DB_HOST, 27 port: Number(process.env.REPLICA_DB_PORT ?? 5432), 28 username: process.env.REPLICA_DB_USERNAME, 29 password: process.env.REPLICA_DB_PASSWORD, 30 database: process.env.REPLICA_DB_SCHEMA, 31 synchronize: false, 32 }, 33}) 34@Module({ 35 name: metadata.name, 36 providers: [AnalyticsService], 37 controllers: [], 38 entities: [ 39 { 40 plugin: metadata.name, 41 name: "analytics", 42 entities: [AnalyticsEntity], 43 }, 44 { 45 plugin: metadata.name, 46 name: "replica", 47 entities: [WarehouseEntity], 48 }, 49 ], 50}) 51export class MyPluginModule {}

အခြား plugin ၏ connection သုံးခြင်း

Connection များသည် owner plugin (+ optional name) ဖြင့် process-wide registry တွင် ရှိပါသည်။ Consumer plugin သည် ထို DB အတွက် @Database ပြန်မကြေညာဘဲ owner ၏ connection ကို inject လုပ်သုံးပါသည်။

  • Owner plugin — @Database ကြေညာပြီး အရင် boot လုပ်ရပါသည် (pluginDependencies တွင် ထည့်ရပါသည်)
  • Consumer — @InjectDatabaseSource("owner-plugin", "connection-name")
  • Foreign connection ပေါ်ရှိ entities — plugin: "owner-plugin", name: "connection-name"
  • Consumer တိုင်းတွင် တူညီသော @Database ကို ထပ်မကြေညာရပါ
  • Owner plugin install / load ပြီးမှ consumer က DataSource inject လုပ်ရပါမည်
TSXconsumer plugin service
1import { DataSource } from "typeorm"; 2import { InjectDatabaseSource, Service } from "@quan-erp/shared-backend-core"; 3 4@Service() 5export class ReportService { 6 // "warehouse" plugin declared @Database({ name: "replica", ... }) 7 @InjectDatabaseSource("warehouse", "replica") 8 warehouseReplica: DataSource; 9}
TSXconsumer module entities on foreign connection
1@Module({ 2 name: metadata.name, 3 providers: [ReportService], 4 controllers: [], 5 entities: [ 6 { 7 plugin: "warehouse", 8 name: "replica", 9 entities: [ReportSnapshotEntity], 10 }, 11 ], 12}) 13export class ReportPluginModule {}

CRUD patterns

  • Create: repo.insert(...) → identifiers မှ { id } ပြန်ပေးရပါသည်
  • Update: repo.update + affected စစ်ဆေးရပါသည်
  • Delete: repo.softDelete + affected ကို ဦးစားပေးရပါသည်