mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 14:50:57 +00:00
Muluhabt ERP modules
This commit is contained in:
102
apps/finance-api/src/modules/revenue/revenue.module.ts
Normal file
102
apps/finance-api/src/modules/revenue/revenue.module.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { DynamicModule, Module } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { RabbitMQModule } from "@golevelup/nestjs-rabbitmq";
|
||||
import { PAYMENT_EVENTS_DLX, PAYMENT_EVENTS_EXCHANGE } from "@edr/types";
|
||||
|
||||
import { CutoverModule } from "../cutover/cutover.module";
|
||||
import { RevenueMapping } from "./entities/revenue-mapping.entity";
|
||||
import { InboundEvent } from "./entities/inbound-event.entity";
|
||||
import {
|
||||
InboundEventsRepository,
|
||||
RevenueMappingsRepository,
|
||||
} from "./revenue.repository";
|
||||
import { RevenueMappingsService } from "./revenue-mappings.service";
|
||||
import { RevenueProjectionService } from "./revenue-projection.service";
|
||||
import { RevenuePostingService } from "./revenue-posting.service";
|
||||
import { RevenueController } from "./revenue.controller";
|
||||
import {
|
||||
FINANCE_PAYMENT_BINDING,
|
||||
FINANCE_PAYMENT_DLQ,
|
||||
PaymentEventsConsumer,
|
||||
} from "./payment-events.consumer";
|
||||
import { AccountsModule } from "../accounts/accounts.module";
|
||||
import { JournalsModule } from "../journals/journals.module";
|
||||
|
||||
/**
|
||||
* The broker is OPTIONAL.
|
||||
*
|
||||
* Without `PAYMENT_RABBITMQ_URL` this returns nothing and the app boots with
|
||||
* every screen and projection working — only live payment ingest is off. That
|
||||
* matters because Finance is useful long before it is wired to a broker (the
|
||||
* chart, journals, periods and projections need no messaging at all), and
|
||||
* because a developer without RabbitMQ should not be blocked from running it.
|
||||
*
|
||||
* Same gate freight and passenger use, so all three behave alike.
|
||||
*/
|
||||
function rabbitMQImport(): DynamicModule[] {
|
||||
if (!process.env.PAYMENT_RABBITMQ_URL) return [];
|
||||
|
||||
return [
|
||||
RabbitMQModule.forRootAsync({
|
||||
inject: [ConfigService],
|
||||
useFactory: (config: ConfigService) => ({
|
||||
uri:
|
||||
config.get<string>("rabbitmq.url") ??
|
||||
process.env.PAYMENT_RABBITMQ_URL ??
|
||||
"",
|
||||
exchanges: [
|
||||
{ name: PAYMENT_EVENTS_EXCHANGE, type: "topic", options: { durable: true } },
|
||||
{ name: PAYMENT_EVENTS_DLX, type: "topic", options: { durable: true } },
|
||||
],
|
||||
// The dead-letter queue is declared HERE, not by @RabbitSubscribe —
|
||||
// that decorator only declares the main queue and its DLX pointer. With
|
||||
// no bound DLQ, a dead-lettered message is silently discarded by the
|
||||
// broker. Freight and passenger declare theirs the same way.
|
||||
queues: [
|
||||
{
|
||||
name: FINANCE_PAYMENT_DLQ,
|
||||
exchange: PAYMENT_EVENTS_DLX,
|
||||
routingKey: FINANCE_PAYMENT_BINDING,
|
||||
options: { durable: true },
|
||||
},
|
||||
],
|
||||
prefetchCount: Number(process.env.PAYMENT_EVENTS_PREFETCH ?? 10),
|
||||
// Do not block boot on the broker: the API must still serve its
|
||||
// read-only screens when messaging is down.
|
||||
connectionInitOptions: { wait: false },
|
||||
}),
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([RevenueMapping, InboundEvent]),
|
||||
AccountsModule,
|
||||
JournalsModule,
|
||||
// For the cutover boundary: a payment settled before go-live is already
|
||||
// inside the opening balances and must not post again.
|
||||
CutoverModule,
|
||||
...rabbitMQImport(),
|
||||
],
|
||||
controllers: [RevenueController],
|
||||
providers: [
|
||||
RevenueMappingsRepository,
|
||||
InboundEventsRepository,
|
||||
RevenueMappingsService,
|
||||
RevenueProjectionService,
|
||||
RevenuePostingService,
|
||||
// Registered unconditionally. Without RabbitMQModule the @RabbitSubscribe
|
||||
// decorator is inert, so the class is simply never invoked — and it stays
|
||||
// directly callable, which is how the consumer's idempotency is tested
|
||||
// without standing up a broker.
|
||||
PaymentEventsConsumer,
|
||||
],
|
||||
exports: [
|
||||
RevenueProjectionService,
|
||||
RevenuePostingService,
|
||||
RevenueMappingsRepository,
|
||||
],
|
||||
})
|
||||
export class RevenueModule {}
|
||||
Reference in New Issue
Block a user