This commit is contained in:
louiscklaw
2025-05-30 01:14:10 +08:00
parent 98bc3fe3ce
commit 834f58bde1
52 changed files with 624 additions and 604 deletions

View File

@@ -511,7 +511,7 @@ model UserCard {
}
model UserItem {
id Int @id @default(autoincrement())
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
//

View File

@@ -20,13 +20,13 @@ async function userItem() {
const username = `${firstName.toLowerCase()}-${lastName.toLowerCase()}`;
const alice = await prisma.userItem.upsert({
where: { id: 0 },
where: { id: 'admin_uuid' },
update: {},
create: {
name: `${firstName} ${lastName}`,
name: `admin test`,
city: '',
role: '',
email: `${username}@${SEED_EMAIL_DOMAIN}`,
email: `admin@123.com`,
state: '',
status: '',
address: '',
@@ -37,8 +37,8 @@ async function userItem() {
phoneNumber: '',
isVerified: true,
//
username,
password: await generateHash('Abc1234!'),
username: 'admin@123.com',
password: await generateHash('Aa1234567'),
},
});
@@ -57,16 +57,16 @@ async function userItem() {
}
const randomFaker = getRandomCJKFaker();
const alice = await prisma.userItem.upsert({
where: { id: i },
await prisma.userItem.upsert({
where: { id: i.toString() },
update: {},
create: {
name: randomFaker.person.fullName(),
city: randomFaker.location.city(),
role: 'user',
role: ROLE[Math.floor(Math.random() * ROLE.length)],
email: randomFaker.internet.email(),
state: randomFaker.location.state(),
status: '',
status: STATUS[Math.floor(Math.random() * STATUS.length)],
address: randomFaker.location.streetAddress(),
country: randomFaker.location.country(),
zipCode: randomFaker.location.zipCode(),
@@ -95,3 +95,32 @@ const userItemSeed = userItem()
});
export { userItemSeed };
const ROLE = [
`CEO`,
`CTO`,
`Project Coordinator`,
`Team Leader`,
`Software Developer`,
`Marketing Strategist`,
`Data Analyst`,
`Product Owner`,
`Graphic Designer`,
`Operations Manager`,
`Customer Support Specialist`,
`Sales Manager`,
`HR Recruiter`,
`Business Consultant`,
`Financial Planner`,
`Network Engineer`,
`Content Creator`,
`Quality Assurance Tester`,
`Public Relations Officer`,
`IT Administrator`,
`Compliance Officer`,
`Event Planner`,
`Legal Counsel`,
`Training Coordinator`,
];
const STATUS = ['active', 'pending', 'banned'];

View File

@@ -7,7 +7,6 @@ import prisma from '../../lib/prisma';
export async function GET(req: NextRequest, res: NextResponse) {
try {
const users = await prisma.user.findMany();
console.log({ users });
return response({ users }, STATUS.OK);
} catch (error) {

View File

@@ -0,0 +1,4 @@
###
GET http://localhost:7272/api/helloworld

View File

@@ -24,9 +24,7 @@ export async function GET(req: NextRequest) {
const products = _products();
// Accept search by name or sku
const results = products.filter(
({ name, sku }) => name.toLowerCase().includes(query) || sku?.toLowerCase().includes(query)
);
const results = products.filter(({ name, sku }) => name.toLowerCase().includes(query) || sku?.toLowerCase().includes(query));
logger('[Product] search-results', results.length);

View File

@@ -1,75 +0,0 @@
// src/app/api/product/createProduct/route.ts
//
// PURPOSE:
// create product to db
//
// RULES:
// T.B.A.
//
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* POST - Products
*************************************** */
export async function POST(req: NextRequest) {
// logger('[Product] list', products.length);
const { data } = await req.json();
const createForm: CreateProductData = data as unknown as CreateProductData;
console.log({ createForm });
try {
console.log({ data });
await prisma.productItem.create({ data: createForm });
return response({ hello: 'world' }, STATUS.OK);
} catch (error) {
console.log({ hello: 'world', data });
return handleError('Product - Create', error);
}
}
type CreateProductData = {
// 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;
inventoryType: string;
subDescription: string;
priceSale: number;
newLabel: {
content: string;
enabled: boolean;
};
saleLabel: {
content: string;
enabled: boolean;
};
// ratings: {
// name: string;
// starCount: number;
// reviewCount: number;
// }[];
};

View File

@@ -0,0 +1,53 @@
// src/app/api/user/createUser/route.ts
//
// PURPOSE:
// create user to db
//
// RULES:
// T.B.A.
//
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/**
***************************************
* POST - create User
***************************************
*/
export async function POST(req: NextRequest) {
// logger('[User] list', users.length);
const { data } = await req.json();
const createForm: CreateUserData = data as unknown as CreateUserData;
try {
const user = await prisma.userItem.create({ data: createForm });
return response({ user }, STATUS.OK);
} catch (error) {
return handleError('User - Create', error);
}
}
type CreateUserData = {
name: string;
city: string;
role: string;
email: string;
state: string;
status: string;
address: string;
country: string;
zipCode: string;
company: string;
avatarUrl: string;
phoneNumber: string;
isVerified: boolean;
//
username: string;
password: string;
};

View File

@@ -0,0 +1,4 @@
###
POST http://localhost:7272/api/user/createUser

View File

@@ -1,44 +0,0 @@
// src/app/api/product/deleteProduct/route.ts
//
// PURPOSE:
// delete product from db by id
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* handle Delete Products
*************************************** */
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
// RULES: productId must exist
const productId = searchParams.get('productId');
if (!productId) {
return response({ message: 'Product ID is required!' }, STATUS.BAD_REQUEST);
}
// NOTE: productId confirmed exist, run below
const product = await prisma.productItem.delete({ where: { id: productId } });
if (!product) {
return response({ message: 'Product not found!' }, STATUS.NOT_FOUND);
}
logger('[Product] details', product.id);
return response({ product }, STATUS.OK);
} catch (error) {
return handleError('Product - Get details', error);
}
}

View File

@@ -1,3 +0,0 @@
###
DELETE http://localhost:7272/api/product/deleteProduct?productId=e99f09a7-dd88-49d5-b1c8-1daf80c2d7b06

View File

@@ -0,0 +1,47 @@
// src/app/api/product/deleteUser/route.ts
//
// PURPOSE:
// delete product from db by id
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { logger } from 'src/utils/logger';
import { STATUS, response, handleError } from 'src/utils/response';
import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* handle Delete Users
*************************************** */
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
// RULES: userId must exist
const userId = searchParams.get('userId');
if (!userId) {
return response({ message: 'User ID is required!' }, STATUS.BAD_REQUEST);
}
// NOTE: userId confirmed exist, run below
const user = await prisma.userItem.delete({
//
where: { id: userId },
});
if (!user) {
return response({ message: 'User not found!' }, STATUS.NOT_FOUND);
}
logger('[User] details', user.id);
return response({ user }, STATUS.OK);
} catch (error) {
return handleError('User - Get details', error);
}
}

View File

@@ -0,0 +1,3 @@
###
DELETE http://localhost:7272/api/user/deleteUser?userId=3f431e6f-ad05-4d60-9c25-6a7e92a954ad

View File

@@ -1,7 +1,7 @@
// src/app/api/product/details/route.ts
//
// PURPOSE:
// save product to db by id
// read user from db by id
//
// RULES:
// T.B.A.
@@ -16,31 +16,31 @@ import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* GET Product detail
* GET User detail
*************************************** */
export async function GET(req: NextRequest) {
try {
const { searchParams } = req.nextUrl;
// RULES: productId must exist
const productId = searchParams.get('productId');
if (!productId) {
return response({ message: 'Product ID is required!' }, STATUS.BAD_REQUEST);
// RULES: userId must exist
const userId = searchParams.get('userId');
if (!userId) {
return response({ message: 'userId is required!' }, STATUS.BAD_REQUEST);
}
// NOTE: productId confirmed exist, run below
const product = await prisma.productItem.findFirst({
include: { reviews: true },
where: { id: productId },
// NOTE: userId confirmed exist, run below
const user = await prisma.userItem.findFirst({
// include: { reviews: true },
where: { id: userId },
});
if (!product) {
return response({ message: 'Product not found!' }, STATUS.NOT_FOUND);
if (!user) {
return response({ message: 'User not found!' }, STATUS.NOT_FOUND);
}
logger('[Product] details', product.id);
logger('[User] details', user.id);
return response({ product }, STATUS.OK);
return response({ user }, STATUS.OK);
} catch (error) {
return handleError('Product - Get details', error);
}

View File

@@ -0,0 +1,4 @@
###
GET http://localhost:7272/api/user/details?userId=1165ce3a-29b8-4e1a-9148-1ae08d7e8e01

View File

@@ -1,4 +1,3 @@
###
GET http://localhost:7272/api/user/list

View File

@@ -19,54 +19,40 @@ import prisma from '../../../lib/prisma';
*************************************** */
export async function POST(req: NextRequest) {
// logger('[Product] list', products.length);
const { searchParams } = req.nextUrl;
const userId = searchParams.get('userId');
// RULES: userId must exist
if (!userId) {
return response({ message: 'Product ID is required!' }, STATUS.BAD_REQUEST);
}
const { data } = await req.json();
try {
const products = await prisma.productItem.updateMany({
const user = await prisma.userItem.updateMany({
where: { id: userId },
data: {
status: data.status,
avatarUrl: data.avatarUrl,
isVerified: data.isVerified,
name: data.name,
sku: data.sku,
code: data.code,
price: data.price,
taxes: data.taxes,
tags: data.tags,
sizes: data.sizes,
publish: data.publish,
gender: data.gender,
coverUrl: data.coverUrl,
images: data.images,
colors: data.colors,
quantity: data.quantity,
category: data.category,
available: data.available,
totalSold: data.totalSold,
description: data.description,
totalRatings: data.totalRatings,
totalReviews: data.totalReviews,
inventoryType: data.inventoryType,
subDescription: data.subDescription,
priceSale: data.priceSale,
email: data.email,
phoneNumber: data.phoneNumber,
country: data.country,
state: data.state,
city: data.city,
address: data.address,
zipCode: data.zipCode,
company: data.company,
role: data.role,
//
newLabel: {
content: data.newLabel?.content || '',
enabled: data.newLabel?.enabled ?? false,
},
saleLabel: {
content: data.saleLabel?.content || '',
enabled: data.saleLabel?.enabled ?? false,
},
ratings: {
set: data.ratings.map((rating: { name: string; starCount: number; reviewCount: number }) => ({
name: rating.name,
starCount: rating.starCount,
reviewCount: rating.reviewCount,
})),
},
username: data.username,
password: data.password,
},
where: { id: data.id },
});
return response({ hello: 'world', data }, STATUS.OK);
return response({ user }, STATUS.OK);
} catch (error) {
console.log({ hello: 'world', data });
return handleError('Product - Get list', error);

View File

@@ -0,0 +1,3 @@
###
POST http://localhost:7272/api/user/list