From d13d7c4dcbb2a23be06f110846ccf9eefb44544f Mon Sep 17 00:00:00 2001 From: Phuoc Nguyen Date: Fri, 10 Oct 2025 16:15:22 +0700 Subject: [PATCH] runable --- src/common/dto/pagination.dto.ts | 4 ++-- src/common/interceptors/cache.interceptor.ts | 2 +- src/config/app.config.ts | 2 +- src/config/database.config.ts | 7 ++----- src/config/redis.config.ts | 6 +++--- src/database/data-source.ts | 2 +- src/modules/auth/strategies/jwt.strategy.ts | 2 +- src/modules/categories/categories.repository.ts | 2 +- src/modules/categories/categories.service.ts | 13 ++++++++----- src/modules/products/entities/product.entity.ts | 2 +- src/modules/users/users.repository.ts | 2 +- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/common/dto/pagination.dto.ts b/src/common/dto/pagination.dto.ts index d07df6c..5bded0e 100644 --- a/src/common/dto/pagination.dto.ts +++ b/src/common/dto/pagination.dto.ts @@ -28,10 +28,10 @@ export class PaginationDto { limit?: number = 20; get skip(): number { - return (this.page - 1) * this.limit; + return ((this.page || 1) - 1) * (this.limit || 20); } get take(): number { - return this.limit; + return this.limit || 20; } } diff --git a/src/common/interceptors/cache.interceptor.ts b/src/common/interceptors/cache.interceptor.ts index b4ae694..69b74e3 100644 --- a/src/common/interceptors/cache.interceptor.ts +++ b/src/common/interceptors/cache.interceptor.ts @@ -8,7 +8,7 @@ import { import { Observable, of } from 'rxjs'; import { tap } from 'rxjs/operators'; import { CACHE_MANAGER } from '@nestjs/cache-manager'; -import { Cache } from 'cache-manager'; +import type { Cache } from 'cache-manager'; @Injectable() export class CustomCacheInterceptor implements NestInterceptor { diff --git a/src/config/app.config.ts b/src/config/app.config.ts index e83009f..991c478 100644 --- a/src/config/app.config.ts +++ b/src/config/app.config.ts @@ -1,7 +1,7 @@ import { registerAs } from '@nestjs/config'; export default registerAs('app', () => ({ - port: parseInt(process.env.PORT, 10) || 3000, + port: parseInt(process.env.PORT || '', 10) || 3000, environment: process.env.NODE_ENV || 'development', apiPrefix: process.env.API_PREFIX || 'api', diff --git a/src/config/database.config.ts b/src/config/database.config.ts index 69a72eb..4c21747 100644 --- a/src/config/database.config.ts +++ b/src/config/database.config.ts @@ -11,7 +11,7 @@ export default registerAs( (): TypeOrmModuleOptions => ({ type: 'postgres', host: process.env.DB_HOST || 'localhost', - port: parseInt(process.env.DB_PORT, 10) || 5432, + port: parseInt(process.env.DB_PORT || '', 10) || 5432, username: process.env.DB_USERNAME || 'postgres', password: process.env.DB_PASSWORD || 'postgres', database: process.env.DB_DATABASE || 'retail_pos', @@ -20,9 +20,6 @@ export default registerAs( logging: process.env.NODE_ENV === 'development', migrations: ['dist/database/migrations/*.js'], migrationsRun: false, // Run migrations manually - ssl: - process.env.NODE_ENV === 'production' - ? { rejectUnauthorized: false } - : false, + ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false, }), ); diff --git a/src/config/redis.config.ts b/src/config/redis.config.ts index 66f7b8f..cbeaacc 100644 --- a/src/config/redis.config.ts +++ b/src/config/redis.config.ts @@ -2,10 +2,10 @@ import { registerAs } from '@nestjs/config'; export default registerAs('redis', () => ({ host: process.env.REDIS_HOST || 'localhost', - port: parseInt(process.env.REDIS_PORT, 10) || 6379, + port: parseInt(process.env.REDIS_PORT || '', 10) || 6379, password: process.env.REDIS_PASSWORD || undefined, - ttl: parseInt(process.env.CACHE_TTL, 10) || 300, // 5 minutes default - max: parseInt(process.env.CACHE_MAX_ITEMS, 10) || 1000, + ttl: parseInt(process.env.CACHE_TTL || '', 10) || 300, // 5 minutes default + max: parseInt(process.env.CACHE_MAX_ITEMS || '', 10) || 1000, // Cache strategy cache: { diff --git a/src/database/data-source.ts b/src/database/data-source.ts index 7d9acad..e2c3909 100644 --- a/src/database/data-source.ts +++ b/src/database/data-source.ts @@ -12,7 +12,7 @@ config(); export const dataSourceOptions: DataSourceOptions = { type: 'postgres', host: process.env.DB_HOST || 'localhost', - port: parseInt(process.env.DB_PORT, 10) || 5432, + port: parseInt(process.env.DB_PORT || '', 10) || 5432, username: process.env.DB_USERNAME || 'postgres', password: process.env.DB_PASSWORD || 'postgres', database: process.env.DB_DATABASE || 'retail_pos', diff --git a/src/modules/auth/strategies/jwt.strategy.ts b/src/modules/auth/strategies/jwt.strategy.ts index 9ff5d35..97faff0 100644 --- a/src/modules/auth/strategies/jwt.strategy.ts +++ b/src/modules/auth/strategies/jwt.strategy.ts @@ -14,7 +14,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, - secretOrKey: configService.get('JWT_SECRET'), + secretOrKey: configService.get('JWT_SECRET') || 'fallback-secret', }); } diff --git a/src/modules/categories/categories.repository.ts b/src/modules/categories/categories.repository.ts index f11ad97..f8f7027 100644 --- a/src/modules/categories/categories.repository.ts +++ b/src/modules/categories/categories.repository.ts @@ -38,7 +38,7 @@ export class CategoriesRepository { return this.repository.findOne({ where: { name } }); } - async update(id: string, updateCategoryDto: UpdateCategoryDto): Promise { + async update(id: string, updateCategoryDto: UpdateCategoryDto): Promise { await this.repository.update(id, updateCategoryDto); return this.findOne(id); } diff --git a/src/modules/categories/categories.service.ts b/src/modules/categories/categories.service.ts index 7e66bd4..f707d9d 100644 --- a/src/modules/categories/categories.service.ts +++ b/src/modules/categories/categories.service.ts @@ -72,18 +72,21 @@ export class CategoriesService { const total = category.products.length; const products = category.products.slice(skip, skip + take); + const limit = paginationDto.limit || 20; + const page = paginationDto.page || 1; + return { ...plainToClass(CategoryResponseDto, category, { excludeExtraneousValues: false, }), products, meta: { - page: paginationDto.page, - limit: paginationDto.limit, + page, + limit, total, - totalPages: Math.ceil(total / paginationDto.limit), - hasPreviousPage: paginationDto.page > 1, - hasNextPage: paginationDto.page < Math.ceil(total / paginationDto.limit), + totalPages: Math.ceil(total / limit), + hasPreviousPage: page > 1, + hasNextPage: page < Math.ceil(total / limit), }, }; } diff --git a/src/modules/products/entities/product.entity.ts b/src/modules/products/entities/product.entity.ts index 813582c..6b4e534 100644 --- a/src/modules/products/entities/product.entity.ts +++ b/src/modules/products/entities/product.entity.ts @@ -13,7 +13,7 @@ import { Category } from '../../categories/entities/category.entity'; import { TransactionItem } from '../../transactions/entities/transaction-item.entity'; @Entity('products') -@Index(['name', 'categoryId'], { name: 'idx_products_name_category' }) +@Index('idx_products_name_category', ['name', 'categoryId']) export class Product { @PrimaryGeneratedColumn('uuid') id: string; diff --git a/src/modules/users/users.repository.ts b/src/modules/users/users.repository.ts index 816280c..cbcec08 100644 --- a/src/modules/users/users.repository.ts +++ b/src/modules/users/users.repository.ts @@ -31,7 +31,7 @@ export class UsersRepository { return this.repository.findOne({ where: { email } }); } - async update(id: string, updateUserDto: UpdateUserDto): Promise { + async update(id: string, updateUserDto: UpdateUserDto): Promise { await this.repository.update(id, updateUserDto); return this.findOne(id); }