"feat: add EventItem, EventReview models with seed data and mock files, update User and Event schemas"
This commit is contained in:
66
03_source/cms_backend/src/app/services/AccessLog.service.ts
Normal file
66
03_source/cms_backend/src/app/services/AccessLog.service.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
// src/app/services/AccessLog.service.ts
|
||||
//
|
||||
// PURPOSE:
|
||||
// Service for handling AccessLog records
|
||||
//
|
||||
// RULES:
|
||||
// - All methods return Promises
|
||||
// - Input validation should be done at controller level
|
||||
// - Errors should be propagated to caller
|
||||
|
||||
import type { AccessLog } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
// type CreateAccessLog = {
|
||||
// userId?: string;
|
||||
// message?: string;
|
||||
// metadata?: Record<string, any>;
|
||||
// };
|
||||
|
||||
// type UpdateAccessLog = {
|
||||
// status?: number;
|
||||
// metadata?: object;
|
||||
// };
|
||||
|
||||
async function listAccessLogs(): Promise<AccessLog[]> {
|
||||
return prisma.accessLog.findMany({
|
||||
orderBy: { timestamp: 'desc' },
|
||||
take: 100,
|
||||
});
|
||||
}
|
||||
|
||||
async function getAccessLog(id: string): Promise<AccessLog | null> {
|
||||
return prisma.accessLog.findUnique({ where: { id } });
|
||||
}
|
||||
|
||||
async function createAccessLog(userId?: string, message?: string, metadata?: Record<string, any>): Promise<AccessLog> {
|
||||
return prisma.accessLog.create({
|
||||
data: {
|
||||
userId,
|
||||
message,
|
||||
metadata,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// async function update(id: string, data: UpdateAccessLog): Promise<AccessLog> {
|
||||
// return prisma.accessLog.update({
|
||||
// where: { id },
|
||||
// data: {
|
||||
// ...data,
|
||||
// metadata: data.metadata || {},
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// async function deleteAccessLog(id: string): Promise<AccessLog> {
|
||||
// return prisma.accessLog.delete({ where: { id } });
|
||||
// }
|
||||
|
||||
export {
|
||||
//
|
||||
getAccessLog,
|
||||
listAccessLogs,
|
||||
createAccessLog,
|
||||
};
|
52
03_source/cms_backend/src/app/services/AppLog.service.ts
Normal file
52
03_source/cms_backend/src/app/services/AppLog.service.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
// src/app/services/AppLog.service.ts
|
||||
//
|
||||
// REQ0047/T.B.A.
|
||||
//
|
||||
// PURPOSE:
|
||||
// - AppLog example for handling AppLog Record
|
||||
//
|
||||
// RULES:
|
||||
// - T.B.A.
|
||||
//
|
||||
|
||||
import type { AppLog } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
type CreateAppLog = {
|
||||
level: number;
|
||||
message: string;
|
||||
};
|
||||
|
||||
// type UpdateAppLog = {
|
||||
// level: number;
|
||||
// message: string;
|
||||
// };
|
||||
|
||||
async function listAppLogs(): Promise<AppLog[]> {
|
||||
return prisma.appLog.findMany();
|
||||
}
|
||||
|
||||
async function getAppLog(appLogId: string) {
|
||||
return prisma.appLog.findFirst({ where: { id: appLogId } });
|
||||
}
|
||||
|
||||
async function createNewAppLog(createForm: CreateAppLog) {
|
||||
return prisma.appLog.create({ data: createForm });
|
||||
}
|
||||
|
||||
// async function updateAppLog(appLogId: string, updateForm: UpdateAppLog) {
|
||||
// return prisma.appLog.update({ where: { id: appLogId }, data: updateForm });
|
||||
// }
|
||||
|
||||
async function deleteAppLog(appLogId: string) {
|
||||
return prisma.appLog.delete({ where: { id: appLogId } });
|
||||
}
|
||||
|
||||
export {
|
||||
getAppLog,
|
||||
listAppLogs,
|
||||
// updateAppLog,
|
||||
deleteAppLog,
|
||||
createNewAppLog,
|
||||
};
|
@@ -0,0 +1,7 @@
|
||||
with knowledge in schema.prisma file,
|
||||
please refer the below helloworld example `helloworld.service.ts`
|
||||
and create `user.service.ts` to cover user record
|
||||
|
||||
thanks
|
||||
|
||||
`/home/logic/_wsl_workspace/001_github_ws/HKSingleParty-ws/HKSingleParty/03_source/cms_backend/src/app/services/helloworld.service.ts`
|
65
03_source/cms_backend/src/app/services/event.service.ts
Normal file
65
03_source/cms_backend/src/app/services/event.service.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
// src/app/services/event.service.ts
|
||||
//
|
||||
// PURPOSE:
|
||||
// - Service for handling Event records
|
||||
//
|
||||
// RULES:
|
||||
// - Follows same pattern as helloworld.service.ts
|
||||
//
|
||||
|
||||
import type { Event } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
type CreateEvent = {
|
||||
eventDate: DateTime;
|
||||
title: string;
|
||||
joinMembers?: Json[];
|
||||
price: number;
|
||||
currency: string;
|
||||
duration_m: number;
|
||||
ageBottom: number;
|
||||
ageTop: number;
|
||||
location: string;
|
||||
avatar?: string;
|
||||
memberId?: number;
|
||||
};
|
||||
|
||||
type UpdateEvent = {
|
||||
eventDate?: DateTime;
|
||||
title?: string;
|
||||
joinMembers?: Json[];
|
||||
price?: number;
|
||||
currency?: string;
|
||||
duration_m?: number;
|
||||
ageBottom?: number;
|
||||
ageTop?: number;
|
||||
location?: string;
|
||||
avatar?: string;
|
||||
memberId?: number;
|
||||
};
|
||||
|
||||
async function listEvents(): Promise<Event[]> {
|
||||
return prisma.event.findMany();
|
||||
}
|
||||
|
||||
async function getEvent(eventId: number) {
|
||||
return prisma.event.findFirst({ where: { id: eventId } });
|
||||
}
|
||||
|
||||
async function createNewEvent(createForm: CreateEvent) {
|
||||
return prisma.event.create({ data: createForm });
|
||||
}
|
||||
|
||||
async function updateEvent(eventId: number, updateForm: UpdateEvent) {
|
||||
return prisma.event.update({
|
||||
where: { id: eventId },
|
||||
data: updateForm,
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteEvent(eventId: number) {
|
||||
return prisma.event.delete({ where: { id: eventId } });
|
||||
}
|
||||
|
||||
export { getEvent, listEvents, updateEvent, deleteEvent, createNewEvent };
|
70
03_source/cms_backend/src/app/services/order.service.ts
Normal file
70
03_source/cms_backend/src/app/services/order.service.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
// src/app/services/order.service.ts
|
||||
//
|
||||
// PURPOSE:
|
||||
// - Handle Order Record CRUD operations
|
||||
// - Manage order status transitions
|
||||
// - Handle order-event relationships
|
||||
//
|
||||
|
||||
import type { OrderItem } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
type CreateOrderItem = {
|
||||
orderNumber?: string;
|
||||
// status?: string;
|
||||
// eventIds?: number[];
|
||||
};
|
||||
|
||||
type UpdateOrderItem = {
|
||||
orderNumber?: string;
|
||||
// status?: string;
|
||||
// last_payment_date?: Date;
|
||||
// eventIds?: number[];
|
||||
};
|
||||
|
||||
async function listOrders(): Promise<OrderItem[]> {
|
||||
return prisma.orderItem.findMany();
|
||||
}
|
||||
|
||||
async function getOrder(orderId: string): Promise<OrderItem | null> {
|
||||
return prisma.orderItem.findFirst({
|
||||
where: { id: orderId },
|
||||
});
|
||||
}
|
||||
|
||||
async function createOrder(createForm: CreateOrderItem): Promise<OrderItem> {
|
||||
return prisma.orderItem.create({
|
||||
data: createForm,
|
||||
});
|
||||
}
|
||||
|
||||
async function updateOrder(orderId: string, updateForm: UpdateOrderItem): Promise<OrderItem> {
|
||||
return prisma.orderItem.update({
|
||||
where: { id: orderId },
|
||||
data: updateForm,
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteOrder(orderId: string): Promise<OrderItem> {
|
||||
return prisma.orderItem.delete({
|
||||
where: { id: orderId },
|
||||
});
|
||||
}
|
||||
|
||||
async function getOrdersByStatus(status: string): Promise<OrderItem[]> {
|
||||
return prisma.orderItem.findMany({
|
||||
where: { status },
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
getOrder,
|
||||
listOrders,
|
||||
createOrder,
|
||||
updateOrder,
|
||||
deleteOrder,
|
||||
getOrdersByStatus,
|
||||
type CreateOrderItem as CreateOrder,
|
||||
type UpdateOrderItem as UpdateOrder,
|
||||
};
|
114
03_source/cms_backend/src/app/services/product.service.ts
Normal file
114
03_source/cms_backend/src/app/services/product.service.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
// src/app/services/product.service.ts
|
||||
//
|
||||
// PURPOSE:
|
||||
// - Service for handling ProductItem Record
|
||||
//
|
||||
|
||||
import type { ProductItem } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
type CreateProduct = {
|
||||
sku: string;
|
||||
name: string;
|
||||
// price: number;
|
||||
// code?: string;
|
||||
// taxes?: number;
|
||||
// tags?: string[];
|
||||
// sizes?: string[];
|
||||
// gender?: string[];
|
||||
// colors?: string[];
|
||||
// category?: string;
|
||||
// quantity?: number;
|
||||
// available?: number;
|
||||
// coverUrl?: string;
|
||||
// images?: string[];
|
||||
// description?: string;
|
||||
// subDescription?: string;
|
||||
// publish?: string;
|
||||
// totalSold?: number;
|
||||
// totalRatings?: number;
|
||||
// totalReviews?: number;
|
||||
// inventoryType?: string;
|
||||
// ratings?: number[];
|
||||
// reviews?: string[];
|
||||
// result?: string;
|
||||
// thanks?: string;
|
||||
};
|
||||
|
||||
type UpdateProduct = {
|
||||
sku?: string;
|
||||
name?: string;
|
||||
// price?: number;
|
||||
// code?: string;
|
||||
// taxes?: number;
|
||||
// tags?: string[];
|
||||
// sizes?: string[];
|
||||
// gender?: string[];
|
||||
// colors?: string[];
|
||||
// category?: string;
|
||||
// quantity?: number;
|
||||
// available?: number;
|
||||
// coverUrl?: string;
|
||||
// images?: string[];
|
||||
// description?: string;
|
||||
// subDescription?: string;
|
||||
// publish?: string;
|
||||
// totalSold?: number;
|
||||
// totalRatings?: number;
|
||||
// totalReviews?: number;
|
||||
// inventoryType?: string;
|
||||
// ratings?: number[];
|
||||
// reviews?: string[];
|
||||
// result?: string;
|
||||
// thanks?: string;
|
||||
};
|
||||
|
||||
async function listProducts(): Promise<ProductItem[]> {
|
||||
return prisma.productItem.findMany();
|
||||
}
|
||||
|
||||
async function getProduct(productId: string) {
|
||||
return prisma.productItem.findUnique({ where: { id: productId } });
|
||||
}
|
||||
|
||||
async function createProduct(createForm: CreateProduct) {
|
||||
// return prisma.productItem.create({
|
||||
// data: {
|
||||
// ...createForm,
|
||||
// code: createForm.code || '',
|
||||
// taxes: createForm.taxes || 0,
|
||||
// tags: createForm.tags || [],
|
||||
// sizes: createForm.sizes || [],
|
||||
// gender: createForm.gender || [],
|
||||
// colors: createForm.colors || [],
|
||||
// category: createForm.category || '',
|
||||
// quantity: createForm.quantity || 0,
|
||||
// available: createForm.available || 0,
|
||||
// coverUrl: createForm.coverUrl || '',
|
||||
// images: createForm.images || [],
|
||||
// description: createForm.description || '',
|
||||
// subDescription: createForm.subDescription || '',
|
||||
// publish: createForm.publish || 'published',
|
||||
// totalSold: createForm.totalSold || 0,
|
||||
// totalRatings: createForm.totalRatings || 0,
|
||||
// totalReviews: createForm.totalReviews || 0,
|
||||
// inventoryType: createForm.inventoryType || '',
|
||||
// ratings: createForm.ratings || [],
|
||||
// reviews: createForm.reviews || [],
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
async function updateProduct(productId: string, updateForm: UpdateProduct) {
|
||||
return prisma.productItem.update({
|
||||
where: { id: productId },
|
||||
data: updateForm,
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteProduct(productId: string) {
|
||||
return prisma.productItem.delete({ where: { id: productId } });
|
||||
}
|
||||
|
||||
export { getProduct, listProducts, createProduct, updateProduct, deleteProduct, type CreateProduct, type UpdateProduct };
|
122
03_source/cms_backend/src/app/services/userItem.service.ts
Normal file
122
03_source/cms_backend/src/app/services/userItem.service.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
// src/app/services/user.service.ts
|
||||
//
|
||||
// PURPOSE:
|
||||
// - Handle User Record CRUD operations
|
||||
//
|
||||
// RULES:
|
||||
// - Follow Prisma best practices for database operations
|
||||
// - Validate input data before processing
|
||||
//
|
||||
|
||||
import type { UserItem } from '@prisma/client';
|
||||
|
||||
import prisma from '../lib/prisma';
|
||||
|
||||
type CreateUser = {
|
||||
email: string;
|
||||
// name?: string;
|
||||
// password: string;
|
||||
// role?: Role;
|
||||
// isEmailVerified?: boolean;
|
||||
// admin?: boolean;
|
||||
};
|
||||
|
||||
type UpdateUser = {
|
||||
email?: string;
|
||||
// name?: string;
|
||||
// password?: string;
|
||||
// role?: Role;
|
||||
// isEmailVerified?: boolean;
|
||||
isAdmin?: boolean;
|
||||
};
|
||||
|
||||
async function listUsers(): Promise<UserItem[]> {
|
||||
return prisma.userItem.findMany();
|
||||
}
|
||||
|
||||
async function getUserItem(userId: string): Promise<UserItem | null> {
|
||||
return prisma.userItem.findFirst({ where: { id: userId } });
|
||||
}
|
||||
|
||||
async function updateUser(userId: string, updateForm: UpdateUser): Promise<User> {
|
||||
return prisma.userItem.update({
|
||||
where: { id: userId },
|
||||
data: updateForm,
|
||||
});
|
||||
}
|
||||
|
||||
// check if userId is a admin
|
||||
// check if userId is a admin
|
||||
async function isAdmin(userId: string): Promise<boolean> {
|
||||
const user = await getUserItem(userId);
|
||||
return user?.isAdmin === true;
|
||||
}
|
||||
|
||||
async function changeToAdmin(userIdToPromote: string, userIdOfApplicant: string) {
|
||||
// check the applicant is admin or not
|
||||
const userApplicant = await getUserItem(userIdOfApplicant);
|
||||
let promoteResult = {};
|
||||
|
||||
if (userApplicant && userApplicant.isAdmin) {
|
||||
// applicant is an admin
|
||||
promoteResult = await updateUser(userIdToPromote, { isAdmin: true });
|
||||
} else {
|
||||
promoteResult = { status: 'failed', message: 'applicant is not a admin' };
|
||||
}
|
||||
|
||||
return promoteResult;
|
||||
}
|
||||
|
||||
async function changeToUser(userIdToPromote: string, userIdOfApplicant: string) {
|
||||
// check the applicant is admin or not
|
||||
const userApplicant = await getUserItem(userIdOfApplicant);
|
||||
let promoteResult = {};
|
||||
|
||||
if (userApplicant && userApplicant.isAdmin) {
|
||||
// applicant is an admin
|
||||
promoteResult = await updateUser(userIdToPromote, { isAdmin: false });
|
||||
} else {
|
||||
promoteResult = { status: 'failed', message: 'applicant is not a admin' };
|
||||
}
|
||||
|
||||
return promoteResult;
|
||||
}
|
||||
|
||||
async function getUserByEmail(email: string): Promise<void> {
|
||||
// return prisma.userItem.findUnique({
|
||||
// where: { email },
|
||||
// include: {
|
||||
// Token: true,
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
async function createNewUser(createForm: CreateUser): Promise<void> {
|
||||
// return prisma.userItem.create({
|
||||
// data: {
|
||||
// email: createForm.email,
|
||||
// name: createForm.name,
|
||||
// password: createForm.password,
|
||||
// role: createForm.role || 'USER',
|
||||
// isEmailVerified: createForm.isEmailVerified || false,
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
async function deleteUser(userId: number): Promise<void> {
|
||||
// return prisma.userItem.delete({ where: { id: userId } });
|
||||
}
|
||||
|
||||
export {
|
||||
// getUser,
|
||||
isAdmin,
|
||||
listUsers,
|
||||
updateUser,
|
||||
deleteUser,
|
||||
changeToUser,
|
||||
createNewUser,
|
||||
changeToAdmin,
|
||||
getUserByEmail,
|
||||
type CreateUser,
|
||||
type UpdateUser,
|
||||
};
|
Reference in New Issue
Block a user