feat: add REQ0188 frontend party-user CRUD functionality with backend API endpoints and database schema
This commit is contained in:
20
01_Requirements/REQ0188/index.md
Normal file
20
01_Requirements/REQ0188/index.md
Normal file
@@ -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
|
@@ -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?
|
||||
}
|
||||
|
@@ -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;
|
||||
|
50
03_source/cms_backend/prisma/seeds/partyUser.ts
Normal file
50
03_source/cms_backend/prisma/seeds/partyUser.ts
Normal file
@@ -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 };
|
60
03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md
Normal file
60
03_source/cms_backend/src/app/api/party-user/_GUIDELINES.md
Normal file
@@ -0,0 +1,60 @@
|
||||
<!-- NOTES to AI: please maintain same format and level of detail when edit this file -->
|
||||
|
||||
# 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
|
34
03_source/cms_backend/src/app/api/party-user/create/route.ts
Normal file
34
03_source/cms_backend/src/app/api/party-user/create/route.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
35
03_source/cms_backend/src/app/api/party-user/delete/route.ts
Normal file
35
03_source/cms_backend/src/app/api/party-user/delete/route.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
###
|
||||
|
||||
PATCH http://localhost:7272/api/party-user/delete
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"partyUserId": "cmbxz8t2b000oiigxib3o4jla"
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
###
|
||||
|
||||
GET http://localhost:7272/api/party-user/details?partyUserId=cmbxziat6000b715hmhrnwlx2
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
###
|
||||
|
||||
GET http://localhost:7272/api/party-user/helloworld
|
35
03_source/cms_backend/src/app/api/party-user/list/route.ts
Normal file
35
03_source/cms_backend/src/app/api/party-user/list/route.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,2 @@
|
||||
###
|
||||
GET http://localhost:7272/api/party-user/list
|
35
03_source/cms_backend/src/app/api/party-user/search/route.ts
Normal file
35
03_source/cms_backend/src/app/api/party-user/search/route.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
88
03_source/cms_backend/src/app/api/party-user/update/route.ts
Normal file
88
03_source/cms_backend/src/app/api/party-user/update/route.ts
Normal file
@@ -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[];
|
||||
};
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
|
81
03_source/cms_backend/src/app/api/user/_GUIDELINES.md
Normal file
81
03_source/cms_backend/src/app/api/user/_GUIDELINES.md
Normal file
@@ -0,0 +1,81 @@
|
||||
<!-- AI: please maintain same format and level of detail when edit this file -->
|
||||
|
||||
# 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
|
@@ -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.
|
||||
|
76
03_source/cms_backend/src/app/services/party-user.service.ts
Normal file
76
03_source/cms_backend/src/app/services/party-user.service.ts
Normal file
@@ -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<PartyUser[]> {
|
||||
return prisma.partyUser.findMany({});
|
||||
}
|
||||
|
||||
async function getPartyUser(partyUserId: string): Promise<PartyUser | null> {
|
||||
return prisma.partyUser.findUnique({
|
||||
where: { id: partyUserId },
|
||||
// include: { reviews: true },
|
||||
});
|
||||
}
|
||||
|
||||
async function getUserById(id: string): Promise<User | null> {
|
||||
return prisma.user.findFirst({ where: { id } });
|
||||
}
|
||||
|
||||
async function createPartyUser(partyUserData: any): Promise<PartyUser> {
|
||||
return prisma.partyUser.create({ data: partyUserData });
|
||||
}
|
||||
|
||||
async function updatePartyUser(partyUserId: string, partyUserData: any): Promise<PartyUser | null> {
|
||||
return prisma.partyUser.update({
|
||||
where: { id: partyUserId },
|
||||
data: partyUserData,
|
||||
});
|
||||
}
|
||||
|
||||
async function deletePartyUser(partyUserId: string): Promise<PartyUser | null> {
|
||||
return prisma.partyUser.delete({
|
||||
where: { id: partyUserId },
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
getUserById,
|
||||
getPartyUser,
|
||||
listPartyUsers,
|
||||
createPartyUser,
|
||||
updatePartyUser,
|
||||
deletePartyUser,
|
||||
//
|
||||
type CreateUser,
|
||||
type UpdateUser,
|
||||
//
|
||||
};
|
Reference in New Issue
Block a user