finance-api/src/common/utils/validation.utils.ts
Заид Омар Медхат 33602d0fe9 chore: initialize NestJS project with Docker and environment configuration
Add project scaffolding and development infrastructure:
- Add environment configuration files (.env.development, .env.example) with database, JWT, security, AI integration, logging, and CORS settings
- Add .gitignore to exclude build artifacts, logs, IDE files, and environment variables
- Add .prettierrc with single quotes and trailing commas configuration
- Add multi-stage Dockerfile with development, build, and production stages
- Ad
2025-12-13 15:45:08 +05:00

124 lines
2.9 KiB
TypeScript

import { BadRequestException } from '@nestjs/common';
import { ErrorMessages } from '../constants/error-messages';
/**
* Validate UUID format
*/
export function isValidUUID(id: string): boolean {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(id);
}
/**
* Validate and throw if UUID is invalid
*/
export function validateUUID(id: string, fieldName: string = 'ID'): void {
if (!isValidUUID(id)) {
throw new BadRequestException(`Некорректный формат ${fieldName}`);
}
}
/**
* Validate email format
*/
export function isValidEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
/**
* Validate date string format (YYYY-MM-DD)
*/
export function isValidDateString(dateStr: string): boolean {
const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
if (!dateRegex.test(dateStr)) return false;
const date = new Date(dateStr);
return !isNaN(date.getTime());
}
/**
* Validate pagination parameters
*/
export interface PaginationParams {
page: number;
limit: number;
}
export function validatePagination(page?: number, limit?: number): PaginationParams {
const validPage = Math.max(1, page || 1);
const validLimit = Math.min(100, Math.max(1, limit || 20));
return { page: validPage, limit: validLimit };
}
/**
* Calculate pagination offset
*/
export function calculateOffset(page: number, limit: number): number {
return (page - 1) * limit;
}
/**
* Create pagination response metadata
*/
export interface PaginationMeta {
page: number;
limit: number;
total: number;
totalPages: number;
hasNext: boolean;
hasPrev: boolean;
}
export function createPaginationMeta(
page: number,
limit: number,
total: number,
): PaginationMeta {
const totalPages = Math.ceil(total / limit);
return {
page,
limit,
total,
totalPages,
hasNext: page < totalPages,
hasPrev: page > 1,
};
}
/**
* Validate date range
*/
export function validateDateRange(startDate: string, endDate: string): void {
if (!isValidDateString(startDate)) {
throw new BadRequestException('Некорректная дата начала');
}
if (!isValidDateString(endDate)) {
throw new BadRequestException('Некорректная дата окончания');
}
if (new Date(startDate) > new Date(endDate)) {
throw new BadRequestException('Дата начала не может быть позже даты окончания');
}
}
/**
* Validate transaction amount
*/
export function validateTransactionAmount(amount: number): void {
if (typeof amount !== 'number' || isNaN(amount)) {
throw new BadRequestException(ErrorMessages.INVALID_AMOUNT);
}
if (amount <= 0) {
throw new BadRequestException(ErrorMessages.AMOUNT_MUST_BE_POSITIVE);
}
if (amount > 1_000_000_000) {
throw new BadRequestException(ErrorMessages.AMOUNT_TOO_LARGE);
}
}