mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
refactor(nestjs): banking modules
This commit is contained in:
@@ -5,6 +5,7 @@ import { EnsureTenantIsSeededGuard } from "./EnsureTenantIsSeeded.guards";
|
||||
import { APP_GUARD } from "@nestjs/core";
|
||||
import { TenancyContext } from "./TenancyContext.service";
|
||||
import { TenantController } from "./Tenant.controller";
|
||||
import { TenancyInitializeModelsGuard } from "./TenancyInitializeModels.guard";
|
||||
|
||||
|
||||
@Module({
|
||||
@@ -23,6 +24,10 @@ import { TenantController } from "./Tenant.controller";
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: EnsureTenantIsSeededGuard
|
||||
},
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: TenancyInitializeModelsGuard
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Inject,
|
||||
Injectable,
|
||||
SetMetadata,
|
||||
} from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { IS_PUBLIC_ROUTE } from '../Auth/Auth.constants';
|
||||
import { TENANT_MODELS_INIT } from './TenantModelsInitialize.module';
|
||||
|
||||
export const IGNORE_TENANT_MODELS_INITIALIZE =
|
||||
'IGNORE_TENANT_MODELS_INITIALIZE';
|
||||
export const IgnoreTenantModelsInitialize = () =>
|
||||
SetMetadata(IGNORE_TENANT_MODELS_INITIALIZE, true);
|
||||
|
||||
@Injectable()
|
||||
export class TenancyInitializeModelsGuard implements CanActivate {
|
||||
constructor(
|
||||
@Inject(TENANT_MODELS_INIT)
|
||||
private readonly tenantModelsInit: () => Promise<boolean>,
|
||||
private reflector: Reflector,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Initialize tenant models if the route is decorated with TriggerTenantModelsInitialize.
|
||||
* @param {ExecutionContext} context
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const isPublic = this.reflector.getAllAndOverride<boolean>(
|
||||
IS_PUBLIC_ROUTE,
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
// Skip initialization for public routes
|
||||
if (isPublic) {
|
||||
return true;
|
||||
}
|
||||
const shouldIgnoreInitialization =
|
||||
this.reflector.getAllAndOverride<boolean>(
|
||||
IGNORE_TENANT_MODELS_INITIALIZE,
|
||||
[context.getHandler(), context.getClass()],
|
||||
);
|
||||
// Initialize models unless the route is decorated with IgnoreTenantModelsInitialize
|
||||
if (!shouldIgnoreInitialization) {
|
||||
try {
|
||||
await this.tenantModelsInit();
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize tenant models:', error);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { ContextIdFactory, ModuleRef } from '@nestjs/core';
|
||||
import { ClsModule } from 'nestjs-cls';
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { initialize } from 'objection';
|
||||
import { TENANCY_DB_CONNECTION } from './TenancyDB/TenancyDB.constants';
|
||||
|
||||
const RegisteredModels = [
|
||||
'SaleInvoice',
|
||||
'Bill',
|
||||
'Expense',
|
||||
'BankTransaction',
|
||||
'MatchedBankTransaction',
|
||||
'ManualJournalEntry',
|
||||
'Account',
|
||||
'UncategorizedBankTransaction',
|
||||
'RecognizedBankTransaction',
|
||||
];
|
||||
export const TENANT_MODELS_INIT = 'TENANT_MODELS_INIT';
|
||||
|
||||
const provider = ClsModule.forFeatureAsync({
|
||||
provide: TENANT_MODELS_INIT,
|
||||
inject: [TENANCY_DB_CONNECTION, ModuleRef],
|
||||
useFactory: (tenantKnex: () => Knex, moduleRef: ModuleRef) => async () => {
|
||||
const knexInstance = tenantKnex();
|
||||
const contextId = ContextIdFactory.create();
|
||||
const models = await Promise.all(
|
||||
RegisteredModels.map((model) => {
|
||||
return moduleRef.resolve(model, contextId, { strict: false });
|
||||
}),
|
||||
);
|
||||
const modelsInstances = models.map((model) => model());
|
||||
|
||||
if (modelsInstances.length > 0) {
|
||||
try {
|
||||
// Initialize all models with the knex instance
|
||||
await initialize(knexInstance, modelsInstances);
|
||||
} catch (error) {
|
||||
console.error('Error initializing models:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
strict: true,
|
||||
type: 'function',
|
||||
});
|
||||
|
||||
@Module({
|
||||
imports: [provider],
|
||||
exports: [provider],
|
||||
})
|
||||
@Global()
|
||||
export class TenantModelsInitializeModule {}
|
||||
Reference in New Issue
Block a user