From 17aaf97722774fe2e30b007531266ebd7aa2b1cd Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Mon, 16 Jun 2025 02:26:41 +0800 Subject: [PATCH] feat: add REQ0188 frontend party-user CRUD functionality with backend API endpoints and database schema --- 01_Requirements/REQ0188/index.md | 20 +++++ 03_source/cms_backend/prisma/schema.prisma | 32 +++++-- 03_source/cms_backend/prisma/seed.ts | 5 +- .../cms_backend/prisma/seeds/partyUser.ts | 50 +++++++++++ .../src/app/api/party-user/_GUIDELINES.md | 60 +++++++++++++ .../src/app/api/party-user/create/route.ts | 34 +++++++ .../src/app/api/party-user/create/test.http | 20 +++++ .../src/app/api/party-user/delete/route.ts | 35 ++++++++ .../src/app/api/party-user/delete/test.http | 8 ++ .../src/app/api/party-user/details/route.ts | 43 +++++++++ .../src/app/api/party-user/details/test.http | 4 + .../app/api/party-user/helloworld/route.ts | 11 +++ .../app/api/party-user/helloworld/test.http | 3 + .../src/app/api/party-user/list/route.ts | 35 ++++++++ .../src/app/api/party-user/list/test.http | 2 + .../src/app/api/party-user/search/route.ts | 35 ++++++++ .../src/app/api/party-user/update/route.ts | 88 +++++++++++++++++++ .../src/app/api/party-user/update/test.http | 21 +++++ .../src/app/api/product/create/route.ts | 3 - .../src/app/api/user/_GUIDELINES.md | 81 +++++++++++++++++ .../app/services/_PROMPTS/clone_srevice.md | 8 +- .../src/app/services/party-user.service.ts | 76 ++++++++++++++++ 22 files changed, 661 insertions(+), 13 deletions(-) create mode 100644 01_Requirements/REQ0188/index.md create mode 100644 03_source/cms_backend/prisma/seeds/partyUser.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md create mode 100644 03_source/cms_backend/src/app/api/party-user/create/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/create/test.http create mode 100644 03_source/cms_backend/src/app/api/party-user/delete/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/delete/test.http create mode 100644 03_source/cms_backend/src/app/api/party-user/details/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/details/test.http create mode 100644 03_source/cms_backend/src/app/api/party-user/helloworld/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/helloworld/test.http create mode 100644 03_source/cms_backend/src/app/api/party-user/list/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/list/test.http create mode 100644 03_source/cms_backend/src/app/api/party-user/search/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/update/route.ts create mode 100644 03_source/cms_backend/src/app/api/party-user/update/test.http create mode 100644 03_source/cms_backend/src/app/api/user/_GUIDELINES.md create mode 100644 03_source/cms_backend/src/app/services/party-user.service.ts diff --git a/01_Requirements/REQ0188/index.md b/01_Requirements/REQ0188/index.md new file mode 100644 index 0000000..87687b9 --- /dev/null +++ b/01_Requirements/REQ0188/index.md @@ -0,0 +1,20 @@ +--- +tags: frontend, party-user +--- + +# REQ0188 frontend party-user + +frontend page to handle party-user (CRUD) + +edit page T.B.A. + +## TODO + +## sources + +T.B.A. + +## branch + +develop/requirements/REQ0188 +develop/frontend/party-user/trunk diff --git a/03_source/cms_backend/prisma/schema.prisma b/03_source/cms_backend/prisma/schema.prisma index 4a3eba4..5302bcc 100644 --- a/03_source/cms_backend/prisma/schema.prisma +++ b/03_source/cms_backend/prisma/schema.prisma @@ -31,17 +31,21 @@ model Account { oauth_token_secret String? oauth_token String? - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + PartyUser PartyUser? @relation(fields: [partyUserId], references: [id]) + partyUserId String? @@unique([provider, providerAccountId]) } model Session { - id String @id @default(cuid()) - sessionToken String @unique @map("session_token") - userId String @map("user_id") + id String @id @default(cuid()) + sessionToken String @unique @map("session_token") + userId String @map("user_id") expires DateTime - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + PartyUser PartyUser? @relation(fields: [partyUserId], references: [id]) + partyUserId String? } model User { @@ -1257,3 +1261,21 @@ model PartyOrderItem { // OrderPayment OrderPayment[] // OrderShippingAddress OrderShippingAddress[] } + +model PartyUser { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + // + name String? + username String? @unique + email String @unique + emailVerified DateTime? + password String? + image String? + bucketImage String? + admin Boolean @default(false) + accounts Account[] + sessions Session[] + info Json? +} diff --git a/03_source/cms_backend/prisma/seed.ts b/03_source/cms_backend/prisma/seed.ts index 1f31c63..43a3560 100644 --- a/03_source/cms_backend/prisma/seed.ts +++ b/03_source/cms_backend/prisma/seed.ts @@ -31,7 +31,9 @@ import { EventReviewSeed } from './seeds/eventReview'; import { appLogSeed } from './seeds/AppLog'; import { accessLogSeed } from './seeds/AccessLog'; import { userMetaSeed } from './seeds/userMeta'; +// import { partyOrderItemSeed } from './seeds/partyOrderItem'; +import { partyUserSeed } from './seeds/partyUser'; // // import { Blog } from './seeds/blog'; @@ -60,8 +62,9 @@ import { partyOrderItemSeed } from './seeds/partyOrderItem'; // await appLogSeed; await accessLogSeed; - + // await partyOrderItemSeed; + await partyUserSeed; // await Blog; // await Mail; diff --git a/03_source/cms_backend/prisma/seeds/partyUser.ts b/03_source/cms_backend/prisma/seeds/partyUser.ts new file mode 100644 index 0000000..243e8a4 --- /dev/null +++ b/03_source/cms_backend/prisma/seeds/partyUser.ts @@ -0,0 +1,50 @@ +import { PrismaClient } from '@prisma/client'; +const prisma = new PrismaClient(); + +async function partyUser() { + const alice = await prisma.partyUser.upsert({ + where: { email: 'alice@prisma.io' }, + update: {}, + create: { + email: 'alice@prisma.io', + name: 'Alice', + password: 'Aa12345678', + emailVerified: new Date(), + }, + }); + + await prisma.partyUser.upsert({ + where: { email: 'demo@minimals.cc' }, + update: {}, + create: { + email: 'demo@minimals.cc', + name: 'Demo', + password: '@2Minimal', + emailVerified: new Date(), + }, + }); + + await prisma.partyUser.upsert({ + where: { email: 'bob@prisma.io' }, + update: {}, + create: { + email: 'bob@prisma.io', + name: 'Bob', + password: 'Aa12345678', + emailVerified: new Date(), + }, + }); + console.log('seed partyUser done'); +} + +const partyUserSeed = partyUser() + .then(async () => { + await prisma.$disconnect(); + }) + .catch(async (e) => { + console.error(e); + await prisma.$disconnect(); + process.exit(1); + }); + +export { partyUserSeed }; diff --git a/03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md b/03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md new file mode 100644 index 0000000..df371e5 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md @@ -0,0 +1,60 @@ + + +# GUIDELINE + +- Party-user Management API endpoint for managing party-user accounts +- Handles party-user CRUD operations and profile updates +- Follows Next.js API route conventions + +## Endpoints + +### `create/route.ts` + +Creates new party-user account with required details + +### `delete/route.ts` + +Deletes party-user account by ID + +### `details/route.ts` + +Gets detailed party-user information + +### `helloworld/route.ts` + +Simple test endpoint returning "Hello World" + +### `list/route.ts` + +Lists all party-users with pagination support + +### `search/route.ts` + +Searches party-users by name or email + +### `update/route.ts` + +Updates party-user profile information + +## Testing + +Test files are available per endpoint in their respective directories: + +- `create/test.http` +- `delete/test.http` +- `details/test.http` +- `helloworld/test.http` +- `list/test.http` +- `update/test.http` + +## Related Services + +`../../services/party-user.service.ts` (assumed) would handle: + +`createUser` - Register new party-user account +`updateUser` - Update party-user profile +`deleteUser` - Remove party-user account +`listUsers` - Get paginated party-user list +`searchUsers` - Search party-users by criteria +`changeUserRole` - Modify party-user permissions +`uploadUserImage` - Handle profile picture uploads diff --git a/03_source/cms_backend/src/app/api/party-user/create/route.ts b/03_source/cms_backend/src/app/api/party-user/create/route.ts new file mode 100644 index 0000000..4a3e319 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/create/route.ts @@ -0,0 +1,34 @@ +// src/app/api/party-user/create/route.ts +// +// PURPOSE: +// create new party user in db +// +// RULES: +// 1. Validates input data shape +// 2. Returns created party user data +// + +import type { NextRequest } from 'next/server'; + +import { STATUS, response, handleError } from 'src/utils/response'; + +import { createPartyUser } from 'src/app/services/party-user.service'; + +// ---------------------------------------------------------------------- + +/** + *************************************** + * POST - create PartyUser + *************************************** + */ +export async function POST(req: NextRequest) { + const { partyUserData } = await req.json(); + + try { + const partyUser = await createPartyUser(partyUserData); + + return response({ partyUser }, STATUS.OK); + } catch (error) { + return handleError('PartyUser - Create', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/create/test.http b/03_source/cms_backend/src/app/api/party-user/create/test.http new file mode 100644 index 0000000..2fb346e --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/create/test.http @@ -0,0 +1,20 @@ +### + +POST http://localhost:7272/api/party-user/create +Content-Type: application/json + +{ + "partyUserData": { + "createdAt": "2025-06-15T17:47:24.547Z", + "updatedAt": "2025-06-15T17:47:24.547Z", + "name": "Alice", + "username": null, + "email": "alice@prisma.io", + "emailVerified": "2025-06-15T17:47:23.919Z", + "password": "Aa12345678", + "image": null, + "bucketImage": null, + "admin": false, + "info": null + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/delete/route.ts b/03_source/cms_backend/src/app/api/party-user/delete/route.ts new file mode 100644 index 0000000..3f689a5 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/delete/route.ts @@ -0,0 +1,35 @@ +// src/app/api/party-user/delete/route.ts +// +// PURPOSE: +// delete party user from db by id +// +// RULES: +// 1. Requires valid party user ID +// 2. Returns deleted party user ID +// 3. Handles errors appropriately + +import type { NextRequest } from 'next/server'; + +import { STATUS, response, handleError } from 'src/utils/response'; + +import { deletePartyUser } from 'src/app/services/party-user.service'; + +/** + ************************************** + * PATCH - Delete party user + *************************************** + */ + +export async function PATCH(req: NextRequest) { + try { + const { partyUserId } = await req.json(); + + if (!partyUserId) throw new Error('partyUserId cannot be null'); + + await deletePartyUser(partyUserId); + + return response({ partyUserId }, STATUS.OK); + } catch (error) { + return handleError('PartyUser - Delete', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/delete/test.http b/03_source/cms_backend/src/app/api/party-user/delete/test.http new file mode 100644 index 0000000..ba6b295 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/delete/test.http @@ -0,0 +1,8 @@ +### + +PATCH http://localhost:7272/api/party-user/delete +Content-Type: application/json + +{ + "partyUserId": "cmbxz8t2b000oiigxib3o4jla" +} diff --git a/03_source/cms_backend/src/app/api/party-user/details/route.ts b/03_source/cms_backend/src/app/api/party-user/details/route.ts new file mode 100644 index 0000000..4fa8264 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/details/route.ts @@ -0,0 +1,43 @@ +// src/app/api/party-user/details/route.ts +// +// PURPOSE: +// get party user details from db by id +// +// RULES: +// 1. Requires valid partyUserId parameter +// 2. Returns party user details if found +// 3. Handles not found case appropriately +// 4. Logs the operation + +import type { NextRequest } from 'next/server'; + +import { logger } from 'src/utils/logger'; +import { STATUS, response, handleError } from 'src/utils/response'; + +import { getPartyUser } from 'src/app/services/party-user.service'; + +// ---------------------------------------------------------------------- + +/** ************************************** + * GET PartyUser detail + *************************************** */ +export async function GET(req: NextRequest) { + try { + const { searchParams } = req.nextUrl; + + // RULES: userId must exist + const partyUserId = searchParams.get('partyUserId'); + if (!partyUserId) return response({ message: 'partyUserId is required!' }, STATUS.BAD_REQUEST); + + // NOTE: userId confirmed exist, run below + const partyUser = await getPartyUser(partyUserId); + + if (!partyUser) return response({ message: 'User not found!' }, STATUS.NOT_FOUND); + + logger('[User] details', partyUser.id); + + return response({ partyUser }, STATUS.OK); + } catch (error) { + return handleError('PartyUser - Get details', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/details/test.http b/03_source/cms_backend/src/app/api/party-user/details/test.http new file mode 100644 index 0000000..f2531c5 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/details/test.http @@ -0,0 +1,4 @@ +### + +GET http://localhost:7272/api/party-user/details?partyUserId=cmbxziat6000b715hmhrnwlx2 + diff --git a/03_source/cms_backend/src/app/api/party-user/helloworld/route.ts b/03_source/cms_backend/src/app/api/party-user/helloworld/route.ts new file mode 100644 index 0000000..1a34fac --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/helloworld/route.ts @@ -0,0 +1,11 @@ +import type { NextRequest, NextResponse } from 'next/server'; + +import { STATUS, response, handleError } from 'src/utils/response'; + +export async function GET(req: NextRequest, res: NextResponse) { + try { + return response({ helloworld: 'party-user' }, STATUS.OK); + } catch (error) { + return handleError('GET - helloworld', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/helloworld/test.http b/03_source/cms_backend/src/app/api/party-user/helloworld/test.http new file mode 100644 index 0000000..f8667ab --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/helloworld/test.http @@ -0,0 +1,3 @@ +### + +GET http://localhost:7272/api/party-user/helloworld diff --git a/03_source/cms_backend/src/app/api/party-user/list/route.ts b/03_source/cms_backend/src/app/api/party-user/list/route.ts new file mode 100644 index 0000000..14eee11 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/list/route.ts @@ -0,0 +1,35 @@ +// src/app/api/party-user/update/route.ts +// +// PURPOSE: +// update existing party user in db +// +// RULES: +// 1. Requires valid party user ID +// 2. Validates input data shape +// + +// + +import { logger } from 'src/utils/logger'; +import { STATUS, response, handleError } from 'src/utils/response'; + +import { listPartyUsers } from 'src/app/services/party-user.service'; + +// ---------------------------------------------------------------------- + +/** + *************************************** + * GET - Products + *************************************** + */ +export async function GET() { + try { + const partyUsers = await listPartyUsers(); + + logger('[User] list', partyUsers.length); + + return response({ users: partyUsers }, STATUS.OK); + } catch (error) { + return handleError('Product - Get list', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/list/test.http b/03_source/cms_backend/src/app/api/party-user/list/test.http new file mode 100644 index 0000000..616d2b3 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/list/test.http @@ -0,0 +1,2 @@ +### +GET http://localhost:7272/api/party-user/list diff --git a/03_source/cms_backend/src/app/api/party-user/search/route.ts b/03_source/cms_backend/src/app/api/party-user/search/route.ts new file mode 100644 index 0000000..6583336 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/search/route.ts @@ -0,0 +1,35 @@ +import type { NextRequest } from 'next/server'; + +import { logger } from 'src/utils/logger'; +import { STATUS, response, handleError } from 'src/utils/response'; + +import { _products } from 'src/_mock/_product'; + +// ---------------------------------------------------------------------- + +export const runtime = 'edge'; + +/** ************************************** + * GET - Search products + *************************************** */ +export async function GET(req: NextRequest) { + try { + const { searchParams } = req.nextUrl; + const query = searchParams.get('query')?.trim().toLowerCase(); + + if (!query) { + return response({ results: [] }, STATUS.OK); + } + + const products = _products(); + + // Accept search by name or sku + const results = products.filter(({ name, sku }) => name.toLowerCase().includes(query) || sku?.toLowerCase().includes(query)); + + logger('[Product] search-results', results.length); + + return response({ results }, STATUS.OK); + } catch (error) { + return handleError('Product - Get search', error); + } +} diff --git a/03_source/cms_backend/src/app/api/party-user/update/route.ts b/03_source/cms_backend/src/app/api/party-user/update/route.ts new file mode 100644 index 0000000..3b94d0b --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/update/route.ts @@ -0,0 +1,88 @@ +// src/app/api/party-user/update/route.ts +// +// PURPOSE: +// update existing party user in db +// +// RULES: +// 1. Requires valid party user ID +// 2. Validates input data shape +// 3. Returns updated party user data +// 4. Handles errors appropriately + +import type { NextRequest } from 'next/server'; + +import { STATUS, response, handleError } from 'src/utils/response'; + +import { updatePartyUser } from 'src/app/services/party-user.service'; + +// ---------------------------------------------------------------------- + +/** ************************************** + * PUT - Update PartyUser + *************************************** */ +export async function PUT(req: NextRequest) { + // logger('[Product] list', products.length); + const { partyUserData } = await req.json(); + + try { + await updatePartyUser(partyUserData.id, partyUserData); + return response({ partyUserData }, STATUS.OK); + } catch (error) { + return handleError('PartyUser - Update', error); + } +} + +export type IProductItem = { + id: string; + sku: string; + name: string; + code: string; + price: number; + taxes: number; + tags: string[]; + sizes: string[]; + publish: string; + gender: string[]; + coverUrl: string; + images: string[]; + colors: string[]; + quantity: number; + category: string; + available: number; + totalSold: number; + description: string; + totalRatings: number; + totalReviews: number; + // createdAt: IDateValue; + inventoryType: string; + subDescription: string; + priceSale: number | null; + // reviews: IProductReview[]; + newLabel: { + content: string; + enabled: boolean; + }; + saleLabel: { + content: string; + enabled: boolean; + }; + ratings: { + name: string; + starCount: number; + reviewCount: number; + }[]; +}; + +export type IDateValue = string | number | null; + +export type IProductReview = { + id: string; + name: string; + rating: number; + comment: string; + helpful: number; + avatarUrl: string; + postedAt: IDateValue; + isPurchased: boolean; + attachments?: string[]; +}; diff --git a/03_source/cms_backend/src/app/api/party-user/update/test.http b/03_source/cms_backend/src/app/api/party-user/update/test.http new file mode 100644 index 0000000..5b59a25 --- /dev/null +++ b/03_source/cms_backend/src/app/api/party-user/update/test.http @@ -0,0 +1,21 @@ +### + +PUT http://localhost:7272/api/party-user/update +Content-Type: application/json + +{ + "partyUserData": { + "id": "cmbxzds7q0009xyn5367ifizp", + "createdAt": "2025-06-15T17:47:24.547Z", + "updatedAt": "2025-06-15T17:47:24.547Z", + "name": "Alice", + "username": null, + "email": "alice@prisma.io", + "emailVerified": "2025-06-15T17:47:23.919Z", + "password": "Aa12345678", + "image": null, + "bucketImage": null, + "admin": false, + "info": null + } +} diff --git a/03_source/cms_backend/src/app/api/product/create/route.ts b/03_source/cms_backend/src/app/api/product/create/route.ts index d5bf269..ec62ee7 100644 --- a/03_source/cms_backend/src/app/api/product/create/route.ts +++ b/03_source/cms_backend/src/app/api/product/create/route.ts @@ -13,10 +13,7 @@ import type { NextRequest } from 'next/server'; import { STATUS, response, handleError } from 'src/utils/response'; import { isDev } from 'src/constants'; - -import prisma from '../../../lib/prisma'; import { createProduct } from 'src/app/services/product.service'; -// import { createProduct } from 'src/app/services/product.service'; // ---------------------------------------------------------------------- diff --git a/03_source/cms_backend/src/app/api/user/_GUIDELINES.md b/03_source/cms_backend/src/app/api/user/_GUIDELINES.md new file mode 100644 index 0000000..19d6374 --- /dev/null +++ b/03_source/cms_backend/src/app/api/user/_GUIDELINES.md @@ -0,0 +1,81 @@ + + +# GUIDELINE + +- User Management API endpoint for managing user accounts +- Handles user CRUD operations, role management and profile updates +- Follows Next.js API route conventions + +## `route.ts` + +Main user route handler with HTTP methods: + +- `GET` - Get current user details +- `POST` - Create new user account +- `PUT` - Update user profile +- `DELETE` - Delete user account + +## Sub-routes + +### `changeToAdmin/route.ts` + +Changes user role to admin + +### `changeToUser/route.ts` + +Changes user role to regular user + +### `checkAdmin/route.ts` + +Verifies if user has admin privileges + +### `createUser/route.ts` + +Creates new user account with required details + +### `deleteUser/route.ts` + +Deletes user account by ID + +### `details/route.ts` + +Gets detailed user information + +### `list/route.ts` + +Lists all users with pagination support + +### `saveUser/route.ts` + +Saves user profile changes + +### `search/route.ts` + +Searches users by name or email + +### `image/upload/route.ts` + +Handles user profile picture uploads + +## `test.http` + +Contains test requests for: + +- User authentication +- Role changes (admin/user) +- Profile updates +- Account creation/deletion +- User listing/searching +- Image uploads + +## Related Services + +`../../services/user.service.ts` (assumed) would handle: + +`createUser` - Register new user account +`updateUser` - Update user profile +`deleteUser` - Remove user account +`listUsers` - Get paginated user list +`searchUsers` - Search users by criteria +`changeUserRole` - Modify user permissions +`uploadUserImage` - Handle profile picture uploads diff --git a/03_source/cms_backend/src/app/services/_PROMPTS/clone_srevice.md b/03_source/cms_backend/src/app/services/_PROMPTS/clone_srevice.md index 5f71ac9..dec9ffb 100644 --- a/03_source/cms_backend/src/app/services/_PROMPTS/clone_srevice.md +++ b/03_source/cms_backend/src/app/services/_PROMPTS/clone_srevice.md @@ -1,13 +1,13 @@ Hi, i copied from -`03_source/cms_backend/src/app/services/party-event.service.ts` +`03_source/cms_backend/src/app/services/user.service.ts` to -`03_source/cms_backend/src/app/services/party-order.service.ts` +`03_source/cms_backend/src/app/services/party-user.service.ts` with knowledge in `schema.prisma` file, and reference to the sibling files in same folder -i want you to update `party-order.service.ts` content to handle party order (the purchase order of the party) -please use the model `PartyOrderItem` to handle it. +i want you to update `party-user.service.ts` content to handle `party user` (the user joining party) +please use the model `PartyUser` to handle it. thanks. diff --git a/03_source/cms_backend/src/app/services/party-user.service.ts b/03_source/cms_backend/src/app/services/party-user.service.ts new file mode 100644 index 0000000..e6d1af1 --- /dev/null +++ b/03_source/cms_backend/src/app/services/party-user.service.ts @@ -0,0 +1,76 @@ +// 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 { User, PartyUser } 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 listPartyUsers(): Promise { + return prisma.partyUser.findMany({}); +} + +async function getPartyUser(partyUserId: string): Promise { + return prisma.partyUser.findUnique({ + where: { id: partyUserId }, + // include: { reviews: true }, + }); +} + +async function getUserById(id: string): Promise { + return prisma.user.findFirst({ where: { id } }); +} + +async function createPartyUser(partyUserData: any): Promise { + return prisma.partyUser.create({ data: partyUserData }); +} + +async function updatePartyUser(partyUserId: string, partyUserData: any): Promise { + return prisma.partyUser.update({ + where: { id: partyUserId }, + data: partyUserData, + }); +} + +async function deletePartyUser(partyUserId: string): Promise { + return prisma.partyUser.delete({ + where: { id: partyUserId }, + }); +} + +export { + getUserById, + getPartyUser, + listPartyUsers, + createPartyUser, + updatePartyUser, + deletePartyUser, + // + type CreateUser, + type UpdateUser, + // +};