Add project board, loyalty club, and if/then automations.

Separate modules for post-sales kanban, person points/tiers, and deal-won/ticket-resolved rules without overlapping the sales pipeline.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-30 09:42:07 +03:30
co-authored by Cursor
parent 2e6c4779ab
commit c2bfa7749d
29 changed files with 3126 additions and 9 deletions
+18
View File
@@ -15,6 +15,7 @@ import { PrismaService } from '../prisma/prisma.service';
import { PipelinesService } from './pipelines.service';
import { toJsonCustomFields } from '../common/custom-fields';
import { NotificationsService } from '../notifications/notifications.service';
import { AutomationsService } from '../automations/automations.service';
import {
type Actor,
canReassignOwner,
@@ -37,6 +38,7 @@ export class DealsService {
private readonly prisma: PrismaService,
private readonly pipelines: PipelinesService,
private readonly notifications: NotificationsService,
private readonly automations: AutomationsService,
) {}
async get(
@@ -240,6 +242,9 @@ export class DealsService {
pipelineId: true,
stageId: true,
ownerId: true,
status: true,
personId: true,
companyId: true,
},
});
if (!deal) throw new NotFoundException('معامله پیدا نشد');
@@ -285,6 +290,19 @@ export class DealsService {
});
}
if (status === 'won' && deal.status !== 'won') {
await this.automations.runTrigger('deal_won', {
organizationId,
entityType: 'deal',
entityId: deal.id,
title: deal.title,
personId: deal.personId,
companyId: deal.companyId,
dealId: deal.id,
ownerId: deal.ownerId,
});
}
return this.pipelines.toDealDto(row);
}
+3 -2
View File
@@ -1,13 +1,14 @@
import { Module } from '@nestjs/common';
import { Module, forwardRef } from '@nestjs/common';
import { DealsController } from './deals.controller';
import { DealsService } from './deals.service';
import { PipelinesController } from './pipelines.controller';
import { PipelinesService } from './pipelines.service';
import { NotificationsModule } from '../notifications/notifications.module';
import { AuthModule } from '../auth/auth.module';
import { AutomationsModule } from '../automations/automations.module';
@Module({
imports: [NotificationsModule, AuthModule],
imports: [NotificationsModule, AuthModule, forwardRef(() => AutomationsModule)],
controllers: [PipelinesController, DealsController],
providers: [PipelinesService, DealsService],
exports: [PipelinesService, DealsService],