142 lines
5.9 KiB
TypeScript
142 lines
5.9 KiB
TypeScript
import { prisma } from '../config/database';
|
|
import { Prisma } from '@prisma/client';
|
|
import { config } from '../config';
|
|
import { logger } from '../config/logger';
|
|
import jwt from 'jsonwebtoken';
|
|
import { createCategory, createCategoryResponse, deleteCategoryResponse, updateCategory, updateCategoryResponse, ListCategoriesResponse, Category } from '../types/categories.type';
|
|
import { UnauthorizedError, ValidationError, ForbiddenError } from '../middleware/errorHandler';
|
|
import { auditService } from './audit.service';
|
|
import { AuditAction } from '@prisma/client';
|
|
|
|
export class CategoryService {
|
|
async listCategories(): Promise<ListCategoriesResponse> {
|
|
try {
|
|
const categories = await prisma.category.findMany();
|
|
return {
|
|
code: 200,
|
|
message: 'Categories fetched successfully',
|
|
data: {
|
|
categories: categories as unknown as Category[],
|
|
total: categories.length
|
|
}
|
|
};
|
|
} catch (error) {
|
|
logger.error('Failed to list categories', { error });
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async createCategory(token: string, category: createCategory): Promise<createCategoryResponse> {
|
|
try {
|
|
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
|
const newCategory = await prisma.category.create({
|
|
data: category
|
|
});
|
|
auditService.log({
|
|
userId: decoded.id,
|
|
action: AuditAction.CREATE,
|
|
entityType: 'Category',
|
|
entityId: newCategory.id,
|
|
newValue: { name: newCategory.name as { th: string; en: string }, slug: newCategory.slug, description: newCategory.description as { th: string; en: string } },
|
|
});
|
|
return {
|
|
code: 200,
|
|
message: 'Category created successfully',
|
|
data: {
|
|
id: newCategory.id,
|
|
name: newCategory.name as { th: string; en: string },
|
|
slug: newCategory.slug,
|
|
description: newCategory.description as { th: string; en: string },
|
|
created_by: decoded.id,
|
|
}
|
|
};
|
|
} catch (error) {
|
|
logger.error('Failed to create category', { error });
|
|
await auditService.logSync({
|
|
userId: 0,
|
|
action: AuditAction.ERROR,
|
|
entityType: 'Category',
|
|
entityId: 0,
|
|
metadata: {
|
|
operation: 'create_category',
|
|
error: error instanceof Error ? error.message : String(error)
|
|
}
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async updateCategory(token: string, id: number, category: updateCategory): Promise<updateCategoryResponse> {
|
|
try {
|
|
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
|
const updatedCategory = await prisma.category.update({
|
|
where: { id },
|
|
data: category
|
|
});
|
|
auditService.log({
|
|
userId: decoded.id,
|
|
action: AuditAction.UPDATE,
|
|
entityType: 'Category',
|
|
entityId: id,
|
|
newValue: { name: updatedCategory.name as { th: string; en: string }, slug: updatedCategory.slug, description: updatedCategory.description as { th: string; en: string } },
|
|
});
|
|
return {
|
|
code: 200,
|
|
message: 'Category updated successfully',
|
|
data: {
|
|
id: updatedCategory.id,
|
|
name: updatedCategory.name as { th: string; en: string },
|
|
slug: updatedCategory.slug,
|
|
description: updatedCategory.description as { th: string; en: string },
|
|
updated_by: decoded.id,
|
|
}
|
|
};
|
|
} catch (error) {
|
|
logger.error('Failed to update category', { error });
|
|
await auditService.logSync({
|
|
userId: 0,
|
|
action: AuditAction.ERROR,
|
|
entityType: 'Category',
|
|
entityId: 0,
|
|
metadata: {
|
|
operation: 'update_category',
|
|
error: error instanceof Error ? error.message : String(error)
|
|
}
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async deleteCategory(token: string, id: number): Promise<deleteCategoryResponse> {
|
|
try {
|
|
const decoded = jwt.verify(token, config.jwt.secret) as { id: number; username: string; email: string; roleCode: string };
|
|
const deletedCategory = await prisma.category.delete({
|
|
where: { id }
|
|
});
|
|
auditService.log({
|
|
userId: decoded.id,
|
|
action: AuditAction.DELETE,
|
|
entityType: 'Category',
|
|
entityId: id,
|
|
newValue: { name: deletedCategory.name as { th: string; en: string }, slug: deletedCategory.slug, description: deletedCategory.description as { th: string; en: string } },
|
|
});
|
|
return {
|
|
code: 200,
|
|
message: 'Category deleted successfully',
|
|
};
|
|
} catch (error) {
|
|
logger.error('Failed to delete category', { error });
|
|
await auditService.logSync({
|
|
userId: 0,
|
|
action: AuditAction.ERROR,
|
|
entityType: 'Category',
|
|
entityId: 0,
|
|
metadata: {
|
|
operation: 'delete_category',
|
|
error: error instanceof Error ? error.message : String(error)
|
|
}
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
}
|