Tour package booking, app release, new endpoints, more updates and fixes

This commit is contained in:
Stephanos A
2026-07-05 00:28:06 +03:00
parent 868639084c
commit 595be6e123
68 changed files with 2773 additions and 787 deletions

View File

@@ -1,4 +1,4 @@
import { Body, Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, Param, Post, Delete, UseGuards, SetMetadata, Query } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { Throttle } from '@nestjs/throttler';
import { WalletService } from './wallet.service';
@@ -11,6 +11,8 @@ import { JwtGuard } from '../../common/jwt.guard';
@Throttle({ strict: { limit: 20, ttl: 60_000 } })
export class WalletController {
constructor(private service: WalletService) {}
@Get(':passengerId') @ApiOperation({ summary: 'Get wallet balance and ledger' }) getWallet(@Param('passengerId') id: string) { return this.service.getWallet(id); }
@Post(':passengerId/topup') @ApiOperation({ summary: 'Top up wallet' }) topUp(@Param('passengerId') id: string, @Body('amountMinor') amount: number) { return this.service.topUp(id, amount); }
@Get('accounts') @SetMetadata('isPublic', true) @ApiOperation({ summary: 'List all wallet accounts' }) getAccounts(@Query() q: any) { return this.service.getAccounts(q); }
@Get(':passengerId') @ApiOperation({ summary: 'Get wallet balance and ledger' }) getWallet(@Param('passengerId') id: string) { return this.service.getWallet(id); }
@Post(':passengerId/topup') @ApiOperation({ summary: 'Top up wallet' }) topUp(@Param('passengerId') id: string, @Body('amountMinor') amount: number) { return this.service.topUp(id, amount); }
@Delete('accounts/:id') @SetMetadata('isPublic', true) @ApiOperation({ summary: 'Delete wallet account' }) deleteAccount(@Param('id') id: string) { return this.service.deleteAccount(id); }
}

View File

@@ -5,6 +5,42 @@ import { PrismaService } from '../../common/prisma.service';
export class WalletService {
constructor(private prisma: PrismaService) {}
async getAccounts(params: { search?: string; page?: string; pageSize?: string } = {}) {
const { search, page = '1', pageSize = '20' } = params;
const skip = (parseInt(page) - 1) * parseInt(pageSize);
const where: any = {};
if (search) {
where.passenger = {
OR: [
{ user: { fullName: { contains: search, mode: 'insensitive' } } },
{ user: { email: { contains: search, mode: 'insensitive' } } },
],
};
}
const [items, total] = await Promise.all([
this.prisma.walletAccount.findMany({
where,
skip,
take: parseInt(pageSize),
orderBy: { balanceMinor: 'desc' },
include: { passenger: { include: { user: true } } },
}),
this.prisma.walletAccount.count({ where }),
]);
return {
items: items.map(w => ({
...w,
passenger: w.passenger ? {
id: w.passenger.id,
fullName: (w.passenger as any).user?.fullName ?? null,
email: (w.passenger as any).user?.email ?? null,
phone: (w.passenger as any).user?.phone ?? null,
} : null,
})),
meta: { page: parseInt(page), pageSize: parseInt(pageSize), total, totalPages: Math.ceil(total / parseInt(pageSize)) },
};
}
async getWallet(passengerId: string) {
const wallet = await this.prisma.walletAccount.findUnique({ where: { passengerId }, include: { ledger: { orderBy: { createdAt: 'desc' }, take: 20 } } });
if (!wallet) throw new NotFoundException('Wallet not found');
@@ -18,4 +54,14 @@ export class WalletService {
await this.prisma.walletAccount.update({ where: { passengerId }, data: { balanceMinor: newBalance } });
return this.prisma.walletLedgerEntry.create({ data: { walletId: wallet.id, type: 'CREDIT', amountMinor, balanceAfterMinor: newBalance, description } });
}
async deleteAccount(id: string) {
const wallet = await this.prisma.walletAccount.findUnique({ where: { id } });
if (!wallet) throw new NotFoundException('Wallet account not found');
await this.prisma.$transaction([
this.prisma.walletLedgerEntry.deleteMany({ where: { walletId: id } }),
this.prisma.walletAccount.delete({ where: { id } }),
]);
return { deleted: true, accountId: id };
}
}