mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-11-26 16:44:54 +00:00
228 lines
8.1 KiB
TypeScript
228 lines
8.1 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
Get,
|
|
HttpCode,
|
|
HttpStatus,
|
|
Param,
|
|
Patch,
|
|
Post,
|
|
Query,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import { ApiBearerAuth, ApiTags, ApiQuery } from '@nestjs/swagger';
|
|
import { Roles } from '~/auth/enums';
|
|
import { IJwtPayload } from '~/auth/interfaces';
|
|
import { AllowedRoles, AuthenticatedUser, Public } from '~/common/decorators';
|
|
import { RolesGuard } from '~/common/guards';
|
|
import { ApiDataPageResponse, ApiDataResponse, ApiLangRequestHeader } from '~/core/decorators';
|
|
import { PageOptionsRequestDto } from '~/core/dtos';
|
|
import { CustomParseUUIDPipe } from '~/core/pipes';
|
|
import { ResponseFactory } from '~/core/utils';
|
|
import {
|
|
CreateJuniorRequestDto,
|
|
SetThemeRequestDto,
|
|
TransferToJuniorRequestDto,
|
|
UpdateJuniorRequestDto,
|
|
} from '../dtos/request';
|
|
import {
|
|
JuniorResponseDto,
|
|
QrCodeValidationResponseDto,
|
|
ThemeResponseDto,
|
|
TransferToJuniorResponseDto,
|
|
} from '../dtos/response';
|
|
import { WeeklySummaryResponseDto } from '../dtos/response/weekly-summary.response.dto';
|
|
import { JuniorHomeResponseDto, PagedChildTransfersResponseDto } from '~/card/dtos/responses';
|
|
import { JuniorService } from '../services';
|
|
|
|
@Controller('juniors')
|
|
@ApiTags('Juniors')
|
|
@ApiBearerAuth()
|
|
@ApiLangRequestHeader()
|
|
export class JuniorController {
|
|
constructor(private readonly juniorService: JuniorService) {}
|
|
|
|
@Post()
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse(JuniorResponseDto)
|
|
async createJunior(@Body() body: CreateJuniorRequestDto, @AuthenticatedUser() user: IJwtPayload) {
|
|
const token = await this.juniorService.createJuniors(body, user.sub);
|
|
|
|
return ResponseFactory.data(token);
|
|
}
|
|
|
|
@Get()
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataPageResponse(JuniorResponseDto)
|
|
async findJuniors(@AuthenticatedUser() user: IJwtPayload, @Query() pageOptions: PageOptionsRequestDto) {
|
|
const [juniors, count] = await this.juniorService.findJuniorsByGuardianId(user.sub, pageOptions);
|
|
|
|
return ResponseFactory.dataPage(
|
|
juniors.map((juniors) => new JuniorResponseDto(juniors)),
|
|
{
|
|
page: pageOptions.page,
|
|
size: pageOptions.size,
|
|
itemCount: count,
|
|
},
|
|
);
|
|
}
|
|
|
|
@Get(':juniorId')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse(JuniorResponseDto)
|
|
async findJuniorById(
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
) {
|
|
const junior = await this.juniorService.findJuniorById(juniorId, false, user.sub);
|
|
|
|
return ResponseFactory.data(new JuniorResponseDto(junior));
|
|
}
|
|
|
|
@Patch(':juniorId')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse(JuniorResponseDto)
|
|
async updateJunior(
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@Body() body: UpdateJuniorRequestDto,
|
|
) {
|
|
const junior = await this.juniorService.updateJunior(juniorId, body, user.sub);
|
|
|
|
return ResponseFactory.data(new JuniorResponseDto(junior));
|
|
}
|
|
|
|
@Delete(':juniorId')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@HttpCode(HttpStatus.NO_CONTENT)
|
|
async deleteJunior(@AuthenticatedUser() user: IJwtPayload, @Param('juniorId', CustomParseUUIDPipe) juniorId: string) {
|
|
await this.juniorService.deleteJunior(juniorId, user.sub);
|
|
}
|
|
|
|
@Post('set-theme')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.JUNIOR)
|
|
@ApiDataResponse(JuniorResponseDto)
|
|
async setTheme(@Body() body: SetThemeRequestDto, @AuthenticatedUser() user: IJwtPayload) {
|
|
const theme = await this.juniorService.setTheme(body, user.sub);
|
|
return ResponseFactory.data(new ThemeResponseDto(theme));
|
|
}
|
|
|
|
@Get(':juniorId/qr-code')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse('string')
|
|
async generateQrCode(@Param('juniorId', CustomParseUUIDPipe) juniorId: string) {
|
|
const qrCode = await this.juniorService.generateToken(juniorId);
|
|
|
|
return ResponseFactory.data(qrCode);
|
|
}
|
|
|
|
@Get('qr-code/:token/validate')
|
|
@Public()
|
|
@ApiDataResponse(QrCodeValidationResponseDto)
|
|
async validateToken(@Param('token') token: string) {
|
|
const junior = await this.juniorService.validateToken(token);
|
|
|
|
return ResponseFactory.data(new QrCodeValidationResponseDto(junior));
|
|
}
|
|
|
|
@Post(':juniorId/transfer')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse(TransferToJuniorResponseDto)
|
|
async transferToJunior(
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@Body() body: TransferToJuniorRequestDto,
|
|
) {
|
|
const newAmount = await this.juniorService.transferToJunior(juniorId, body, user.sub);
|
|
|
|
return ResponseFactory.data(new TransferToJuniorResponseDto(newAmount));
|
|
}
|
|
|
|
@Get(':juniorId/weekly-summary')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.GUARDIAN)
|
|
@ApiDataResponse(WeeklySummaryResponseDto)
|
|
@ApiQuery({ name: 'startUtc', required: false, type: String, example: '2025-10-20T00:00:00.000Z', description: 'Start date (defaults to start of current week)' })
|
|
@ApiQuery({ name: 'endUtc', required: false, type: String, example: '2025-10-26T23:59:59.999Z', description: 'End date (defaults to end of current week)' })
|
|
async getWeeklySummary(
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Query('startUtc') startUtc?: string,
|
|
@Query('endUtc') endUtc?: string,
|
|
) {
|
|
const startDate = startUtc ? new Date(startUtc) : undefined;
|
|
const endDate = endUtc ? new Date(endUtc) : undefined;
|
|
const summary = await this.juniorService.getWeeklySummary(juniorId, user.sub, startDate, endDate);
|
|
return ResponseFactory.data(summary);
|
|
}
|
|
|
|
@Get(':juniorId/home')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.JUNIOR, Roles.GUARDIAN)
|
|
@ApiQuery({ name: 'size', required: false, type: Number, example: 5 })
|
|
@ApiDataResponse(JuniorHomeResponseDto)
|
|
async getJuniorHome(
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Query('size') size?: number,
|
|
) {
|
|
const limit = Math.max(1, Math.min(Number(size) || 5, 20));
|
|
const res = await this.juniorService.getJuniorHome(juniorId, user.sub, limit);
|
|
return ResponseFactory.data(res);
|
|
}
|
|
|
|
@Get(':juniorId/transfers')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.JUNIOR, Roles.GUARDIAN)
|
|
@ApiQuery({ name: 'page', required: false, type: Number, example: 1 })
|
|
@ApiQuery({ name: 'size', required: false, type: Number, example: 10 })
|
|
@ApiDataResponse(PagedChildTransfersResponseDto)
|
|
async getJuniorTransfers(
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Query('page') page?: number,
|
|
@Query('size') size?: number,
|
|
) {
|
|
const pageNum = Math.max(1, Number(page) || 1);
|
|
const pageSize = Math.max(1, Math.min(Number(size) || 10, 50));
|
|
const res = await this.juniorService.getJuniorTransfers(juniorId, user.sub, pageNum, pageSize);
|
|
return ResponseFactory.data(res);
|
|
}
|
|
|
|
@Get(':juniorId/spending-history')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.JUNIOR, Roles.GUARDIAN)
|
|
@ApiQuery({ name: 'startUtc', required: true, type: String, example: '2025-01-01T00:00:00.000Z' })
|
|
@ApiQuery({ name: 'endUtc', required: true, type: String, example: '2025-01-31T23:59:59.999Z' })
|
|
async getSpendingHistory(
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
@Query('startUtc') startUtc: string,
|
|
@Query('endUtc') endUtc: string,
|
|
) {
|
|
const res = await this.juniorService.getSpendingHistory(juniorId, user.sub, new Date(startUtc), new Date(endUtc));
|
|
return ResponseFactory.data(res);
|
|
}
|
|
|
|
@Get(':juniorId/transactions/:transactionId')
|
|
@UseGuards(RolesGuard)
|
|
@AllowedRoles(Roles.JUNIOR, Roles.GUARDIAN)
|
|
async getTransactionDetail(
|
|
@Param('juniorId', CustomParseUUIDPipe) juniorId: string,
|
|
@Param('transactionId', CustomParseUUIDPipe) transactionId: string,
|
|
@AuthenticatedUser() user: IJwtPayload,
|
|
) {
|
|
const res = await this.juniorService.getTransactionDetail(juniorId, user.sub, transactionId);
|
|
return ResponseFactory.data(res);
|
|
}
|
|
}
|