@mbc-cqrs-serverless/master 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,7 +44,7 @@ import { AppTaskQueueEventFactory } from './task/app-task-queue-event.factory';
44
44
  }),
45
45
  MasterModule.register({
46
46
  enableController: true, // Optional: enable REST endpoints
47
- prismaService: PrismaService, // Required when enableController is true
47
+ prismaService: PrismaService, // Required (MasterDataService/MasterSettingService inject it)
48
48
  dataSyncHandlers: [MasterDataSyncHandler], // Optional: custom sync handlers
49
49
  }),
50
50
  ],
@@ -294,6 +294,50 @@ Full documentation available at [https://mbc-cqrs-serverless.mbc-net.com/](https
294
294
 
295
295
  - [Master Service Guide](https://mbc-cqrs-serverless.mbc-net.com/docs/master-service)
296
296
 
297
+ ## Configurable table name
298
+
299
+ `MasterModule` uses the `master` DynamoDB table by default. Pass `tableName` to
300
+ override it (backward compatible — omitting it keeps `master`). Both
301
+ `register` and `registerAsync` accept it:
302
+
303
+ > **⚠️ Renaming the master table is not fully supported.** The `master` table is a
304
+ > framework-wide **central config store** — `TtlService` (TTL config) and the
305
+ > `@mbc-cqrs-serverless/sequence` package (numbering formats) read a fixed
306
+ > `master-data` table name. If you override the master `tableName`, those readers
307
+ > keep looking at `master-data`, so TTLs are not applied and sequence formats
308
+ > silently fall back to defaults. `MasterModule.register`/`registerAsync` logs a
309
+ > warning when a custom `tableName` is set. Prefer keeping the default `master`;
310
+ > only override it if you have separately addressed those readers. (Customizing
311
+ > the directory / survey-template / ui-setting table names has no such caveat.)
312
+
313
+ ```ts
314
+ MasterModule.register({
315
+ enableController: true,
316
+ prismaService: PrismaService,
317
+ tableName: 'catalog', // default: 'master' — see the caveat above
318
+ })
319
+
320
+ MasterModule.registerAsync({
321
+ tableName: 'catalog',
322
+ imports: [PrismaModule],
323
+ inject: [PrismaService], // resolve and return the PrismaService INSTANCE
324
+ useFactory: (prisma) => ({ prismaService: prisma }),
325
+ })
326
+ ```
327
+
328
+ > **Provisioning:** Add **only the raw base name** (e.g. `"catalog"`) to
329
+ > `prisma/dynamodbs/cqrs.json`; the CLI creates the `-command` / `-data` /
330
+ > `-history` physical tables, and your IaC must define the same three. Note that
331
+ > `@mbc-cqrs-serverless/master`'s postinstall auto-adds only the default `master`
332
+ > name — a custom name must be added manually.
333
+ >
334
+ > **Shared table:** If you also use `@mbc-cqrs-serverless/ui-setting`
335
+ > (`SettingModule`), both modules must use the **same** `tableName`, because they
336
+ > share the same physical table. `MasterModule` should own the data-sync
337
+ > pipeline — register `SettingModule` with `registerEventHandlerAlias: false`.
338
+ > If both modules own the `<tableName>_CommandEventHandler` alias, the app boots
339
+ > but logs a warning and the effective owner becomes import-order dependent.
340
+
297
341
  ## License
298
342
 
299
343
  Copyright © 2024-2025, Murakami Business Consulting, Inc. [https://www.mbc-net.com/](https://www.mbc-net.com/)
@@ -1,9 +1,29 @@
1
1
  import { IDataSyncHandler } from '@mbc-cqrs-serverless/core';
2
- import { Type } from '@nestjs/common';
2
+ import { ModuleMetadata, Type } from '@nestjs/common';
3
3
  export declare const PRISMA_SERVICE = "PrismaServiceInjectToken";
4
4
  export interface MasterModuleOptions {
5
5
  enableController?: boolean;
6
6
  dataSyncHandlers?: Type<IDataSyncHandler>[];
7
7
  prismaService?: Type<any>;
8
+ /** DynamoDB base table name. Default: 'master'. */
9
+ tableName?: string;
10
+ }
11
+ export interface MasterModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
12
+ enableController?: boolean;
13
+ dataSyncHandlers?: Type<IDataSyncHandler>[];
14
+ tableName?: string;
15
+ inject?: any[];
16
+ /**
17
+ * Resolves the runtime module options. Must return the resolved PrismaService
18
+ * **instance** under `prismaService` (typically by injecting it), so the master
19
+ * services (which inject PRISMA_SERVICE) can be constructed. Optional only to
20
+ * stay assignment-compatible with the inherited `registerAsync` signature;
21
+ * omitting it makes PRISMA_SERVICE fail fast.
22
+ */
23
+ useFactory?: (...args: any[]) => Promise<{
24
+ prismaService?: any;
25
+ }> | {
26
+ prismaService?: any;
27
+ };
8
28
  }
9
29
  export declare const ConfigurableModuleClass: import("@nestjs/common").ConfigurableModuleCls<MasterModuleOptions, "register", "create", {}>, MODULE_OPTIONS_TOKEN: string | symbol, OPTIONS_TYPE: MasterModuleOptions & Partial<{}>;
@@ -1 +1 @@
1
- {"version":3,"file":"master.module-definition.js","sourceRoot":"","sources":["../src/master.module-definition.ts"],"names":[],"mappings":";;;;AACA,2CAA0D;AAG7C,QAAA,cAAc,GAAG,0BAA0B,CAAA;AAQ3C,KACX,IAAI,kCAAyB,EAAuB,CAAC,KAAK,EAAE,EAD/C,+BAAuB,+BAAE,4BAAoB,4BAAE,oBAAY,mBACZ"}
1
+ {"version":3,"file":"master.module-definition.js","sourceRoot":"","sources":["../src/master.module-definition.ts"],"names":[],"mappings":";;;;AACA,2CAAgF;AAEnE,QAAA,cAAc,GAAG,0BAA0B,CAAA;AA4B3C,KACX,IAAI,kCAAyB,EAAuB,CAAC,KAAK,EAAE,EAD/C,+BAAuB,+BAAE,4BAAoB,4BAAE,oBAAY,mBACZ"}
@@ -1,5 +1,13 @@
1
1
  import { DynamicModule } from '@nestjs/common';
2
- import { ConfigurableModuleClass, OPTIONS_TYPE } from './master.module-definition';
2
+ import { ConfigurableModuleClass, MasterModuleAsyncOptions, OPTIONS_TYPE } from './master.module-definition';
3
3
  export declare class MasterModule extends ConfigurableModuleClass {
4
+ private static readonly logger;
5
+ /**
6
+ * The `master` table is a framework-wide central config store: `TtlService`
7
+ * (TTL config) and the sequence package (numbering formats) read the fixed
8
+ * `master-data` table. Renaming it silently breaks those readers, so warn.
9
+ */
10
+ private static warnIfCustomTable;
4
11
  static register(options: typeof OPTIONS_TYPE): DynamicModule;
12
+ static registerAsync(options: MasterModuleAsyncOptions): DynamicModule;
5
13
  }
@@ -5,6 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var MasterModule_1;
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.MasterModule = void 0;
10
11
  const core_1 = require("@mbc-cqrs-serverless/core");
@@ -16,46 +17,82 @@ const custom_task_module_1 = require("./custom-task/custom-task.module");
16
17
  const master_sfn_task_handler_1 = require("./handler/master-sfn-task.handler");
17
18
  const master_module_definition_1 = require("./master.module-definition");
18
19
  const services_1 = require("./services");
19
- let MasterModule = class MasterModule extends master_module_definition_1.ConfigurableModuleClass {
20
+ let MasterModule = MasterModule_1 = class MasterModule extends master_module_definition_1.ConfigurableModuleClass {
21
+ /**
22
+ * The `master` table is a framework-wide central config store: `TtlService`
23
+ * (TTL config) and the sequence package (numbering formats) read the fixed
24
+ * `master-data` table. Renaming it silently breaks those readers, so warn.
25
+ */
26
+ static warnIfCustomTable(tableName) {
27
+ if (tableName && tableName !== constants_1.TABLE_NAME) {
28
+ MasterModule_1.logger.warn(`tableName '${tableName}' overrides the 'master' table, which is also read ` +
29
+ `at a fixed 'master-data' name by TtlService (TTL config) and the sequence ` +
30
+ `package (numbering formats). Renaming the master table is not fully ` +
31
+ `supported — TTL and sequence formats will silently fall back. Also, if you ` +
32
+ `use ui-setting's SettingModule, set its tableName to '${tableName}' too ` +
33
+ `(they share this table). Keep the default 'master' unless you have ` +
34
+ `addressed those readers.`);
35
+ }
36
+ }
20
37
  static register(options) {
21
- const module = super.register(options);
38
+ MasterModule_1.warnIfCustomTable(options.tableName);
39
+ const base = super.register(options);
40
+ const providers = [...(base.providers ?? [])];
41
+ const controllers = [...(base.controllers ?? [])];
42
+ const imports = [...(base.imports ?? [])];
43
+ // The master services inject PRISMA_SERVICE unconditionally.
44
+ providers.push((0, core_1.buildPrismaProviderSync)(options.prismaService, master_module_definition_1.PRISMA_SERVICE));
45
+ // Data-sync handlers are registered here (not inside CommandModule) so they
46
+ // can resolve PRISMA_SERVICE from this module's scope.
47
+ const handlers = options.dataSyncHandlers ?? [];
48
+ providers.push(...handlers);
49
+ if (options.enableController) {
50
+ controllers.push(controllers_1.MasterBulkController, controllers_1.MasterDataController, controllers_1.MasterSettingController);
51
+ providers.push(master_sfn_task_handler_1.MasterSfnTaskEventHandler);
52
+ imports.push(custom_task_module_1.CustomTaskModule, sequence_1.SequencesModule);
53
+ }
54
+ imports.push((0, core_1.buildDomainCommandModule)(constants_1.TABLE_NAME, {
55
+ tableName: options.tableName,
56
+ dataSyncHandlers: handlers,
57
+ }));
58
+ return { ...base, providers, controllers, imports };
59
+ }
60
+ static registerAsync(options) {
61
+ MasterModule_1.warnIfCustomTable(options.tableName);
62
+ const base = super.registerAsync({
63
+ imports: options.imports,
64
+ inject: options.inject ?? [],
65
+ useFactory: async (...args) => {
66
+ const resolved = (await options.useFactory?.(...args)) ?? {};
67
+ return {
68
+ ...resolved,
69
+ enableController: options.enableController,
70
+ dataSyncHandlers: options.dataSyncHandlers,
71
+ tableName: options.tableName ?? constants_1.TABLE_NAME,
72
+ };
73
+ },
74
+ });
75
+ const providers = [...(base.providers ?? [])];
76
+ const controllers = [...(base.controllers ?? [])];
77
+ const imports = [...(base.imports ?? [])];
78
+ providers.push((0, core_1.buildPrismaProviderAsync)(master_module_definition_1.MODULE_OPTIONS_TOKEN, master_module_definition_1.PRISMA_SERVICE));
79
+ const handlers = options.dataSyncHandlers ?? [];
80
+ providers.push(...handlers);
22
81
  if (options.enableController) {
23
- if (!options.prismaService) {
24
- throw new Error('PrismaService must be provided when enableController is true.');
25
- }
26
- if (!module.controllers) {
27
- module.controllers = [];
28
- }
29
- module.controllers.push(controllers_1.MasterBulkController);
30
- module.controllers.push(controllers_1.MasterDataController);
31
- module.controllers.push(controllers_1.MasterSettingController);
32
- if (!module.providers) {
33
- module.providers = [];
34
- }
35
- module.providers.push({
36
- provide: master_module_definition_1.PRISMA_SERVICE,
37
- useExisting: options.prismaService,
38
- });
39
- module.providers.push(master_sfn_task_handler_1.MasterSfnTaskEventHandler);
40
- if (!module.imports) {
41
- module.imports = [];
42
- }
43
- module.imports.push(custom_task_module_1.CustomTaskModule);
44
- module.imports.push(sequence_1.SequencesModule);
82
+ controllers.push(controllers_1.MasterBulkController, controllers_1.MasterDataController, controllers_1.MasterSettingController);
83
+ providers.push(master_sfn_task_handler_1.MasterSfnTaskEventHandler);
84
+ imports.push(custom_task_module_1.CustomTaskModule, sequence_1.SequencesModule);
45
85
  }
46
- const imports = [...(module.imports ?? [])];
47
- imports.push(core_1.CommandModule.register({
48
- tableName: constants_1.TABLE_NAME,
49
- dataSyncHandlers: options?.dataSyncHandlers,
86
+ imports.push((0, core_1.buildDomainCommandModule)(constants_1.TABLE_NAME, {
87
+ tableName: options.tableName,
88
+ dataSyncHandlers: handlers,
50
89
  }));
51
- return {
52
- ...module,
53
- imports,
54
- };
90
+ return { ...base, providers, controllers, imports };
55
91
  }
56
92
  };
57
93
  exports.MasterModule = MasterModule;
58
- exports.MasterModule = MasterModule = __decorate([
94
+ MasterModule.logger = new common_1.Logger(MasterModule_1.name);
95
+ exports.MasterModule = MasterModule = MasterModule_1 = __decorate([
59
96
  (0, common_1.Module)({
60
97
  imports: [core_1.DataStoreModule, core_1.QueueModule],
61
98
  providers: [services_1.MasterDataService, services_1.MasterSettingService],
@@ -1 +1 @@
1
- {"version":3,"file":"master.module.js","sourceRoot":"","sources":["../src/master.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAIkC;AAClC,4DAA+D;AAC/D,2CAAsD;AAEtD,2CAAwC;AACxC,+CAIsB;AACtB,yEAAmE;AACnE,+EAA6E;AAC7E,yEAImC;AACnC,yCAAoE;AAO7D,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,kDAAuB;IACvD,MAAM,CAAC,QAAQ,CAAC,OAA4B;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAEtC,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAA;YACH,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACxB,MAAM,CAAC,WAAW,GAAG,EAAE,CAAA;YACzB,CAAC;YACD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,kCAAoB,CAAC,CAAA;YAC7C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,kCAAoB,CAAC,CAAA;YAC7C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,qCAAuB,CAAC,CAAA;YAEhD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,CAAC,SAAS,GAAG,EAAE,CAAA;YACvB,CAAC;YAED,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;gBACpB,OAAO,EAAE,yCAAc;gBACvB,WAAW,EAAE,OAAO,CAAC,aAAa;aACnC,CAAC,CAAA;YACF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,mDAAyB,CAAC,CAAA;YAEhD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,OAAO,GAAG,EAAE,CAAA;YACrB,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,qCAAgB,CAAC,CAAA;YACrC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,0BAAe,CAAC,CAAA;QACtC,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAA;QAE3C,OAAO,CAAC,IAAI,CACV,oBAAa,CAAC,QAAQ,CAAC;YACrB,SAAS,EAAE,sBAAU;YACrB,gBAAgB,EAAE,OAAO,EAAE,gBAAgB;SAC5C,CAAC,CACH,CAAA;QAED,OAAO;YACL,GAAG,MAAM;YACT,OAAO;SACR,CAAA;IACH,CAAC;CACF,CAAA;AA/CY,oCAAY;uBAAZ,YAAY;IALxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,sBAAe,EAAE,kBAAW,CAAC;QACvC,SAAS,EAAE,CAAC,4BAAiB,EAAE,+BAAoB,CAAC;QACpD,OAAO,EAAE,CAAC,4BAAiB,EAAE,+BAAoB,CAAC;KACnD,CAAC;GACW,YAAY,CA+CxB"}
1
+ {"version":3,"file":"master.module.js","sourceRoot":"","sources":["../src/master.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const core_1 = require("@mbc-cqrs-serverless/core");
10
+ const task_1 = require("@mbc-cqrs-serverless/task");
11
+ const common_1 = require("@nestjs/common");
12
+ const config_1 = require("@nestjs/config");
13
+ const testing_1 = require("@nestjs/testing");
14
+ const master_module_1 = require("./master.module");
15
+ const services_1 = require("./services");
16
+ class MockPrismaService {
17
+ constructor() {
18
+ this.kind = 'instance';
19
+ }
20
+ }
21
+ /**
22
+ * Provides the globally-scoped dependencies a real app supplies. PrismaService
23
+ * is provided via an ASYNC factory (mirroring PrismaModule.forRootAsync) so the
24
+ * registerAsync path is exercised against the realistic ordering where the
25
+ * Prisma instance is not available synchronously.
26
+ */
27
+ let SupportModule = class SupportModule {
28
+ };
29
+ SupportModule = __decorate([
30
+ (0, common_1.Global)(),
31
+ (0, common_1.Module)({
32
+ imports: [
33
+ config_1.ConfigModule.forRoot({
34
+ isGlobal: true,
35
+ ignoreEnvFile: true,
36
+ load: [() => ({ NODE_ENV: 'local', APP_NAME: 'app' })],
37
+ }),
38
+ ],
39
+ providers: [
40
+ core_1.StepFunctionService,
41
+ { provide: task_1.TaskService, useValue: {} },
42
+ {
43
+ provide: MockPrismaService,
44
+ useFactory: async () => {
45
+ await new Promise((r) => setTimeout(r, 5));
46
+ return new MockPrismaService();
47
+ },
48
+ },
49
+ ],
50
+ exports: [core_1.StepFunctionService, task_1.TaskService, MockPrismaService],
51
+ })
52
+ ], SupportModule);
53
+ describe('MasterModule', () => {
54
+ afterEach(() => jest.restoreAllMocks());
55
+ describe('register (sync)', () => {
56
+ it('forwards the default table name to CommandModule', () => {
57
+ const spy = jest.spyOn(core_1.CommandModule, 'register');
58
+ master_module_1.MasterModule.register({ prismaService: MockPrismaService });
59
+ expect(spy).toHaveBeenCalledWith(expect.objectContaining({ tableName: 'master' }));
60
+ });
61
+ it('forwards a custom table name to CommandModule', () => {
62
+ const spy = jest.spyOn(core_1.CommandModule, 'register');
63
+ master_module_1.MasterModule.register({
64
+ prismaService: MockPrismaService,
65
+ tableName: 'custom-master',
66
+ });
67
+ expect(spy).toHaveBeenCalledWith(expect.objectContaining({ tableName: 'custom-master' }));
68
+ });
69
+ it('throws fast when prismaService is missing', () => {
70
+ expect(() => master_module_1.MasterModule.register({})).toThrow(/prismaService/);
71
+ });
72
+ it('warns that renaming the central master table breaks TTL/sequence config', () => {
73
+ const warnSpy = jest.spyOn(common_1.Logger.prototype, 'warn');
74
+ master_module_1.MasterModule.register({
75
+ prismaService: MockPrismaService,
76
+ tableName: 'catalog',
77
+ });
78
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringMatching(/central config|master-data|not fully supported/));
79
+ });
80
+ it('does not warn for the default master table', () => {
81
+ const warnSpy = jest.spyOn(common_1.Logger.prototype, 'warn');
82
+ master_module_1.MasterModule.register({ prismaService: MockPrismaService });
83
+ expect(warnSpy).not.toHaveBeenCalledWith(expect.stringMatching(/not fully supported/));
84
+ });
85
+ });
86
+ describe('registerAsync', () => {
87
+ it('resolves an async-provided PrismaService instance (not null)', async () => {
88
+ const moduleRef = await testing_1.Test.createTestingModule({
89
+ imports: [
90
+ SupportModule,
91
+ master_module_1.MasterModule.registerAsync({
92
+ inject: [MockPrismaService],
93
+ useFactory: (prisma) => ({
94
+ prismaService: prisma,
95
+ }),
96
+ }),
97
+ ],
98
+ }).compile();
99
+ await moduleRef.init();
100
+ const svc = moduleRef.get(services_1.MasterDataService);
101
+ expect(svc).toBeDefined();
102
+ // Regression: the injected PRISMA_SERVICE must be the resolved instance,
103
+ // not null (async Prisma) and not the class reference.
104
+ expect(svc.prismaService).toBeInstanceOf(MockPrismaService);
105
+ expect(svc.prismaService.kind).toBe('instance');
106
+ await moduleRef.close();
107
+ });
108
+ it('forwards a custom table name via registerAsync', () => {
109
+ const spy = jest.spyOn(core_1.CommandModule, 'register');
110
+ master_module_1.MasterModule.registerAsync({
111
+ inject: [],
112
+ useFactory: () => ({ prismaService: new MockPrismaService() }),
113
+ tableName: 'custom-master',
114
+ });
115
+ expect(spy).toHaveBeenCalledWith(expect.objectContaining({ tableName: 'custom-master' }));
116
+ });
117
+ it('rejects a useFactory that returns the PrismaService class instead of an instance', async () => {
118
+ await expect(testing_1.Test.createTestingModule({
119
+ imports: [
120
+ SupportModule,
121
+ master_module_1.MasterModule.registerAsync({
122
+ inject: [],
123
+ // wrong: returns the class, not an instance
124
+ useFactory: () => ({ prismaService: MockPrismaService }),
125
+ }),
126
+ ],
127
+ }).compile()).rejects.toThrow(/CLASS, not an instance/);
128
+ });
129
+ });
130
+ describe('CommandModule.registerAsync guard', () => {
131
+ it('throws a clear error (not supported)', () => {
132
+ expect(() => core_1.CommandModule.registerAsync({})).toThrow(/not supported/);
133
+ });
134
+ });
135
+ });
136
+ //# sourceMappingURL=master.module.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"master.module.spec.js","sourceRoot":"","sources":["../src/master.module.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mbc-cqrs-serverless/master",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": " Master data management such as setting, sequence, etc.",
5
5
  "keywords": [
6
6
  "mbc",
@@ -43,10 +43,10 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@mbc-cqrs-serverless/core": "1.3.4",
47
- "@mbc-cqrs-serverless/sequence": "1.3.4",
48
- "@mbc-cqrs-serverless/task": "1.3.4",
46
+ "@mbc-cqrs-serverless/core": "1.4.0",
47
+ "@mbc-cqrs-serverless/sequence": "1.4.0",
48
+ "@mbc-cqrs-serverless/task": "1.4.0",
49
49
  "ulid": "^2.3.0"
50
50
  },
51
- "gitHead": "e5b2e10fe73ebd89bf26b23942752d4ebe79388e"
51
+ "gitHead": "972a2726e2696e94e988dfc3135086b13cf2345b"
52
52
  }
@@ -1,4 +1,3 @@
1
- import { CommandModule } from '@mbc-cqrs-serverless/core'
2
1
  import { MasterModule as CoreMasterModule } from '@mbc-cqrs-serverless/master'
3
2
  import { Module } from '@nestjs/common'
4
3
  import { PrismaService } from 'src/prisma'
@@ -7,10 +6,6 @@ import { MasterDataSyncRdsHandler } from './handler/master-rds.handler'
7
6
 
8
7
  @Module({
9
8
  imports: [
10
- CommandModule.register({
11
- tableName: 'master',
12
- dataSyncHandlers: [MasterDataSyncRdsHandler],
13
- }),
14
9
  CoreMasterModule.register({
15
10
  enableController: true,
16
11
  prismaService: PrismaService,