refactor: ( iam ) remove user relations

This commit is contained in:
Abubeker Yasin
2026-06-22 15:01:16 +03:00
parent a63b49d419
commit 4b3c47ca03
9 changed files with 92 additions and 39 deletions

View File

@@ -13,9 +13,13 @@ export class AgentsService {
constructor(private prisma: PrismaService) {}
async createAgentBooking(dto: CreateAgentBookingDto) {
const agent = await this.prisma.agent.findUnique({ where: { id: dto.agentId }, include: { user: { include: { passenger: true } } } });
const agent = await this.prisma.agent.findUnique({ where: { id: dto.agentId } });
if (!agent || !agent.active) throw new NotFoundException('Agent not found or inactive');
if (!agent.user.passenger) throw new BadRequestException('Agent must have passenger account');
const passenger = agent.iamUserId
? await this.prisma.passenger.findUnique({ where: { iamUserId: agent.iamUserId } })
: null;
if (!passenger) throw new BadRequestException('Agent must have a linked passenger account');
const schedule = await this.prisma.trainSchedule.findUnique({ where: { id: dto.scheduleId } });
if (!schedule) throw new NotFoundException('Schedule not found');
@@ -30,7 +34,7 @@ export class AgentsService {
const booking = await this.prisma.booking.create({
data: {
bookingRef: generateRef(),
passengerId: agent.user.passenger.id,
passengerId: passenger.id,
scheduleId: dto.scheduleId,
status: dto.paymentMethod === 'CASH' ? 'CONFIRMED' : 'PENDING_PAYMENT',
totalMinor,

View File

@@ -2,7 +2,9 @@ import { Controller, Get, Post, Patch, Delete, Body, Param, HttpCode, UseGuards
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger';
import { CurrenciesService } from './currencies.service';
import { CreateCurrencyDto, UpdateCurrencyDto } from './currencies.dto';
import { IamGuard, IamRoles } from '../../common/iam-adapter';
import { IamGuard } from '../../common/iam-adapter';
import { Roles } from '../../common/roles.decorator';
import { RolesGuard } from '../../common/roles.guard';
@ApiTags('Currencies')
@Controller('currencies')
@@ -15,8 +17,8 @@ export class CurrenciesController {
}
@Post()
@UseGuards(IamGuard)
@IamRoles('ADMIN')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN')
@ApiBearerAuth('IAM-auth')
@HttpCode(201)
createCurrency(@Body() dto: CreateCurrencyDto) {
@@ -24,24 +26,24 @@ export class CurrenciesController {
}
@Patch(':id')
@UseGuards(IamGuard)
@IamRoles('ADMIN')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN')
@ApiBearerAuth('IAM-auth')
updateCurrency(@Param('id') id: string, @Body() dto: UpdateCurrencyDto) {
return this.currenciesService.updateCurrency(id, dto);
}
@Delete(':id')
@UseGuards(IamGuard)
@IamRoles('ADMIN')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN')
@ApiBearerAuth('IAM-auth')
deleteCurrency(@Param('id') id: string) {
return this.currenciesService.deleteCurrency(id);
}
@Post('sync-rates')
@UseGuards(IamGuard)
@IamRoles('ADMIN')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN')
@ApiBearerAuth('IAM-auth')
@HttpCode(200)
syncRates() {

View File

@@ -2,7 +2,9 @@ import { Controller, Get, Param, Patch, Post, Body, UseGuards } from '@nestjs/co
import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody } from '@nestjs/swagger';
import { NotificationsService } from './notifications.service';
import { JwtGuard } from '../../common/jwt.guard';
import { IamGuard, IamRoles } from '../../common/iam-adapter';
import { IamGuard } from '../../common/iam-adapter';
import { Roles } from '../../common/roles.decorator';
import { RolesGuard } from '../../common/roles.guard';
import { TestNotificationDto } from './notifications.dto';
import { EmailClientService } from './email-client.service';
import { SmsClientService } from './sms-client.service';
@@ -39,8 +41,8 @@ export class NotificationsController {
}
@Post('send/email')
@UseGuards(IamGuard)
@IamRoles('ADMIN', 'STAFF')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN', 'STAFF')
@ApiOperation({ summary: 'Send a direct email via the email microservice' })
@ApiBody({ type: SendEmail })
sendEmail(@Body() dto: SendEmail) {
@@ -48,8 +50,8 @@ export class NotificationsController {
}
@Post('send/sms')
@UseGuards(IamGuard)
@IamRoles('ADMIN', 'STAFF')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN', 'STAFF')
@ApiOperation({ summary: 'Send a direct SMS via the SMS microservice' })
@ApiBody({ type: SingleMessageDto })
sendSms(@Body() dto: SingleMessageDto) {
@@ -57,8 +59,8 @@ export class NotificationsController {
}
@Post('send/sms/bulk')
@UseGuards(IamGuard)
@IamRoles('ADMIN', 'STAFF')
@UseGuards(IamGuard, RolesGuard)
@Roles('ADMIN', 'STAFF')
@ApiOperation({ summary: 'Send bulk SMS messages via the SMS microservice' })
@ApiBody({ type: BulkMessagesDto })
sendBulkSms(@Body() dto: BulkMessagesDto) {

View File

@@ -31,7 +31,6 @@ import {
import { JwtGuard } from "../../common/jwt.guard";
import { RolesGuard } from "../../common/roles.guard";
import { Roles } from "../../common/roles.decorator";
import { UserRole } from "@prisma/client";
@ApiTags("Payment")
@Controller("payments")
@@ -40,7 +39,7 @@ export class PaymentsController {
@Get("all")
@UseGuards(JwtGuard, RolesGuard)
@Roles(UserRole.ADMIN, UserRole.SUPERVISOR, UserRole.STAFF)
@Roles('ADMIN', 'SUPERVISOR', 'STAFF')
@ApiBearerAuth("JWT-auth")
@ApiOperation({ summary: "Get all payments with filters (staff/admin only)" })
@ApiQuery({ name: "search", required: false })
@@ -103,7 +102,7 @@ export class PaymentsController {
@Post("refund")
@UseGuards(JwtGuard, RolesGuard)
@Roles(UserRole.ADMIN, UserRole.STAFF, UserRole.AGENT)
@Roles('ADMIN', 'STAFF', 'AGENT')
@ApiBearerAuth("JWT-auth")
@ApiOperation({ summary: "Refund a confirmed booking (staff/agent only)" })
refund(@Body() dto: RefundDto) {
@@ -112,7 +111,7 @@ export class PaymentsController {
@Post("methods")
@UseGuards(JwtGuard, RolesGuard)
@Roles(UserRole.ADMIN, UserRole.STAFF)
@Roles('ADMIN', 'STAFF')
@ApiBearerAuth("JWT-auth")
@ApiOperation({
summary: "Add a payment system to the platform catalog (admin only)",

View File

@@ -1,10 +1,15 @@
import { Injectable } from '@nestjs/common';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { PrismaService } from '../../common/prisma.service';
import { GenerateReportDto, ReportType } from './reports.dto';
@Injectable()
export class ReportsService {
constructor(private prisma: PrismaService) {}
constructor(
private prisma: PrismaService,
@InjectDataSource() private dataSource: DataSource,
) {}
async generateReport(dto: GenerateReportDto) {
const dateFrom = new Date(dto.dateFrom);
@@ -113,13 +118,25 @@ export class ReportsService {
...(agentId ? { agentId } : {})
},
include: {
agent: { include: { user: true } },
agent: { select: { id: true, iamUserId: true, agentCode: true } },
booking: true
}
});
const iamUserIds = [...new Set(
agentBookings.map(ab => ab.agent.iamUserId).filter(Boolean) as string[]
)];
const iamRows = iamUserIds.length > 0
? await this.dataSource.query<{ id: string; name: { en?: string; am?: string } | null }[]>(
`SELECT id, name FROM iam.users WHERE id = ANY($1)`,
[iamUserIds],
)
: [];
const iamMap = new Map(iamRows.map(r => [r.id, r]));
const byAgent = agentBookings.reduce((acc, ab) => {
const agentName = ab.agent.user.fullName;
const iam = ab.agent.iamUserId ? iamMap.get(ab.agent.iamUserId) : undefined;
const agentName = iam?.name?.en ?? iam?.name?.am ?? ab.agent.agentCode;
if (!acc[agentName]) {
acc[agentName] = { bookings: 0, revenueMinor: 0, cashCollected: 0 };
}