Selaa lähdekoodia

fix(server): Revert using Nest's onModuleInit hook to run service setup

This reverts commit d300978c. When using onModuleInit, we cannot guarantee the order of execution, which breaks the initial bootstrap.
Michael Bromley 7 vuotta sitten
vanhempi
sitoutus
c333530f2a

+ 2 - 1
server/src/service/helpers/order-calculator/order-calculator.spec.ts

@@ -46,7 +46,8 @@ describe('OrderCalculator', () => {
             taxZoneStrategy: new DefaultTaxZoneStrategy(),
             taxZoneStrategy: new DefaultTaxZoneStrategy(),
             taxCalculationStrategy: new DefaultTaxCalculationStrategy(),
             taxCalculationStrategy: new DefaultTaxCalculationStrategy(),
         };
         };
-        await module.init();
+        const taxRateService = module.get(TaxRateService);
+        await taxRateService.initTaxRates();
     });
     });
 
 
     function createOrder(
     function createOrder(

+ 3 - 1
server/src/service/helpers/tax-calculator/tax-calculator.spec.ts

@@ -37,12 +37,14 @@ describe('TaxCalculator', () => {
                 { provide: ListQueryBuilder, useValue: {} },
                 { provide: ListQueryBuilder, useValue: {} },
             ],
             ],
         }).compile();
         }).compile();
+
         taxCalculator = module.get(TaxCalculator);
         taxCalculator = module.get(TaxCalculator);
+        const taxRateService = module.get(TaxRateService);
         const mockConfigService = module.get<ConfigService, MockConfigService>(ConfigService);
         const mockConfigService = module.get<ConfigService, MockConfigService>(ConfigService);
         mockConfigService.taxOptions = {
         mockConfigService.taxOptions = {
             taxCalculationStrategy: new DefaultTaxCalculationStrategy(),
             taxCalculationStrategy: new DefaultTaxCalculationStrategy(),
         };
         };
-        await module.init();
+        await taxRateService.initTaxRates();
     });
     });
 
 
     describe('with prices which do not include tax', () => {
     describe('with prices which do not include tax', () => {

+ 26 - 2
server/src/service/service.module.ts

@@ -1,4 +1,4 @@
-import { Module } from '@nestjs/common';
+import { Module, OnModuleInit } from '@nestjs/common';
 import { TypeOrmModule } from '@nestjs/typeorm';
 import { TypeOrmModule } from '@nestjs/typeorm';
 
 
 import { getConfig } from '../config/config-helpers';
 import { getConfig } from '../config/config-helpers';
@@ -89,4 +89,28 @@ const exportedProviders = [
     ],
     ],
     exports: exportedProviders,
     exports: exportedProviders,
 })
 })
-export class ServiceModule {}
+export class ServiceModule implements OnModuleInit {
+    constructor(
+        private channelService: ChannelService,
+        private roleService: RoleService,
+        private administratorService: AdministratorService,
+        private taxRateService: TaxRateService,
+        private shippingMethodService: ShippingMethodService,
+        private paymentMethodService: PaymentMethodService,
+    ) {}
+
+    async onModuleInit() {
+        // IMPORTANT - why manually invoke these init methods rather than just relying on
+        // Nest's "onModuleInit" lifecycle hook within each individual service class?
+        // The reason is that the order of invokation matters. By explicitly invoking the
+        // methods below, we can e.g. guarantee that the default channel exists
+        // (channelService.initChannels()) before we try to create any roles (which assume that
+        // there is a default Channel to work with.
+        await this.channelService.initChannels();
+        await this.roleService.initRoles();
+        await this.administratorService.initAdministrators();
+        await this.taxRateService.initTaxRates();
+        await this.shippingMethodService.initShippingMethods();
+        await this.paymentMethodService.initPaymentMethods();
+    }
+}

+ 3 - 3
server/src/service/services/administrator.service.ts

@@ -1,4 +1,4 @@
-import { Injectable, OnModuleInit } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -17,7 +17,7 @@ import { RoleService } from './role.service';
 import { UserService } from './user.service';
 import { UserService } from './user.service';
 
 
 @Injectable()
 @Injectable()
-export class AdministratorService implements OnModuleInit {
+export class AdministratorService {
     constructor(
     constructor(
         @InjectConnection() private connection: Connection,
         @InjectConnection() private connection: Connection,
         private listQueryBuilder: ListQueryBuilder,
         private listQueryBuilder: ListQueryBuilder,
@@ -26,7 +26,7 @@ export class AdministratorService implements OnModuleInit {
         private roleService: RoleService,
         private roleService: RoleService,
     ) {}
     ) {}
 
 
-    async onModuleInit() {
+    async initAdministrators() {
         await this.ensureSuperAdminExists();
         await this.ensureSuperAdminExists();
     }
     }
 
 

+ 3 - 3
server/src/service/services/channel.service.ts

@@ -1,4 +1,4 @@
-import { Injectable, OnModuleInit } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -18,7 +18,7 @@ import { getEntityOrThrow } from '../helpers/utils/get-entity-or-throw';
 import { patchEntity } from '../helpers/utils/patch-entity';
 import { patchEntity } from '../helpers/utils/patch-entity';
 
 
 @Injectable()
 @Injectable()
-export class ChannelService implements OnModuleInit {
+export class ChannelService {
     private allChannels: Channel[] = [];
     private allChannels: Channel[] = [];
 
 
     constructor(@InjectConnection() private connection: Connection, private configService: ConfigService) {}
     constructor(@InjectConnection() private connection: Connection, private configService: ConfigService) {}
@@ -27,7 +27,7 @@ export class ChannelService implements OnModuleInit {
      * When the app is bootstrapped, ensure a default Channel exists and populate the
      * When the app is bootstrapped, ensure a default Channel exists and populate the
      * channel lookup array.
      * channel lookup array.
      */
      */
-    async onModuleInit() {
+    async initChannels() {
         await this.ensureDefaultChannelExists();
         await this.ensureDefaultChannelExists();
         await this.updateAllChannels();
         await this.updateAllChannels();
     }
     }

+ 3 - 3
server/src/service/services/payment-method.service.ts

@@ -1,4 +1,4 @@
-import { Injectable, OnModuleInit } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -22,14 +22,14 @@ import { getEntityOrThrow } from '../helpers/utils/get-entity-or-throw';
 import { patchEntity } from '../helpers/utils/patch-entity';
 import { patchEntity } from '../helpers/utils/patch-entity';
 
 
 @Injectable()
 @Injectable()
-export class PaymentMethodService implements OnModuleInit {
+export class PaymentMethodService {
     constructor(
     constructor(
         @InjectConnection() private connection: Connection,
         @InjectConnection() private connection: Connection,
         private configService: ConfigService,
         private configService: ConfigService,
         private listQueryBuilder: ListQueryBuilder,
         private listQueryBuilder: ListQueryBuilder,
     ) {}
     ) {}
 
 
-    async onModuleInit() {
+    async initPaymentMethods() {
         await this.ensurePaymentMethodsExist();
         await this.ensurePaymentMethodsExist();
     }
     }
 
 

+ 3 - 3
server/src/service/services/role.service.ts

@@ -1,4 +1,4 @@
-import { Injectable, OnModuleInit } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -20,14 +20,14 @@ import { patchEntity } from '../helpers/utils/patch-entity';
 import { ChannelService } from './channel.service';
 import { ChannelService } from './channel.service';
 
 
 @Injectable()
 @Injectable()
-export class RoleService implements OnModuleInit {
+export class RoleService {
     constructor(
     constructor(
         @InjectConnection() private connection: Connection,
         @InjectConnection() private connection: Connection,
         private channelService: ChannelService,
         private channelService: ChannelService,
         private listQueryBuilder: ListQueryBuilder,
         private listQueryBuilder: ListQueryBuilder,
     ) {}
     ) {}
 
 
-    async onModuleInit() {
+    async initRoles() {
         await this.ensureSuperAdminRoleExists();
         await this.ensureSuperAdminRoleExists();
         await this.ensureCustomerRoleExists();
         await this.ensureCustomerRoleExists();
     }
     }

+ 3 - 3
server/src/service/services/shipping-method.service.ts

@@ -1,4 +1,4 @@
-import { Injectable, OnModuleInit } from '@nestjs/common';
+import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -24,7 +24,7 @@ import { patchEntity } from '../helpers/utils/patch-entity';
 import { ChannelService } from './channel.service';
 import { ChannelService } from './channel.service';
 
 
 @Injectable()
 @Injectable()
-export class ShippingMethodService implements OnModuleInit {
+export class ShippingMethodService {
     shippingEligibilityCheckers: ShippingEligibilityChecker[];
     shippingEligibilityCheckers: ShippingEligibilityChecker[];
     shippingCalculators: ShippingCalculator[];
     shippingCalculators: ShippingCalculator[];
     private activeShippingMethods: ShippingMethod[];
     private activeShippingMethods: ShippingMethod[];
@@ -40,7 +40,7 @@ export class ShippingMethodService implements OnModuleInit {
         this.shippingCalculators = this.configService.shippingOptions.shippingCalculators || [];
         this.shippingCalculators = this.configService.shippingOptions.shippingCalculators || [];
     }
     }
 
 
-    async onModuleInit() {
+    async initShippingMethods() {
         await this.updateActiveShippingMethods();
         await this.updateActiveShippingMethods();
     }
     }
 
 

+ 2 - 3
server/src/service/services/tax-rate.service.ts

@@ -1,4 +1,3 @@
-import { OnModuleInit } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
 import { InjectConnection } from '@nestjs/typeorm';
 import { Connection } from 'typeorm';
 import { Connection } from 'typeorm';
 
 
@@ -15,7 +14,7 @@ import { ListQueryBuilder } from '../helpers/list-query-builder/list-query-build
 import { getEntityOrThrow } from '../helpers/utils/get-entity-or-throw';
 import { getEntityOrThrow } from '../helpers/utils/get-entity-or-throw';
 import { patchEntity } from '../helpers/utils/patch-entity';
 import { patchEntity } from '../helpers/utils/patch-entity';
 
 
-export class TaxRateService implements OnModuleInit {
+export class TaxRateService {
     /**
     /**
      * We cache all active TaxRates to avoid hitting the DB many times
      * We cache all active TaxRates to avoid hitting the DB many times
      * per request.
      * per request.
@@ -33,7 +32,7 @@ export class TaxRateService implements OnModuleInit {
         private listQueryBuilder: ListQueryBuilder,
         private listQueryBuilder: ListQueryBuilder,
     ) {}
     ) {}
 
 
-    async onModuleInit() {
+    async initTaxRates() {
         return this.updateActiveTaxRates();
         return this.updateActiveTaxRates();
     }
     }