"feat: add EventItem, EventReview models with seed data and mock files, update User and Event schemas"

This commit is contained in:
louiscklaw
2025-06-03 15:29:05 +08:00
parent a0a4ffcb4e
commit 24920fb313
52 changed files with 2140 additions and 56 deletions

View 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,
};

View 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,
};

View File

@@ -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`

View 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 };

View 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,
};

View 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 };

View 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,
};