This commit is contained in:
louiscklaw
2025-05-28 21:06:12 +08:00
parent 4007227418
commit db805f23b6
61 changed files with 1279 additions and 494 deletions

9
03_source/cms_backend/dev.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env bash
while true; do
yarn --dev
yarn dev
echo "restarting..."
sleep 1
done

View File

@@ -0,0 +1 @@
helloworld

View File

@@ -23,6 +23,7 @@
"tsc:print": "npx tsc --showConfig",
"migrate": "npx prisma migrate dev --skip-seed",
"seed": "tsx ./prisma/seed.ts",
"seed:w": "npx nodemon --ext \"ts,tsx,json\" -w prisma --exec \"yarn seed\"",
"unseed": "tsx ./prisma/unseed.ts",
"db:generate": "prisma generate",
"db:push": "prisma db push --force-reset",
@@ -74,4 +75,4 @@
"typescript": "^5.8.2",
"typescript-eslint": "^8.28.0"
}
}
}

View File

@@ -860,6 +860,8 @@ model FileStore {
preview String
size Float
type String
//
content Bytes @db.ByteA
}
// invoice.ts

View File

@@ -21,6 +21,7 @@ import { superuserSeed } from './seeds/superuser';
import { userSeed } from './seeds/user';
import { ProductReview } from './seeds/productReview';
import { ProductItem } from './seeds/productItem';
import { FileStore } from './seeds/fileStore';
//
// import { Blog } from './seeds/blog';
// import { Mail } from './seeds/mail';
@@ -34,6 +35,7 @@ import { ProductItem } from './seeds/productItem';
await superuserSeed;
await userSeed;
await ProductReview;
await FileStore;
await ProductItem;
// await Blog;
// await Mail;

View File

@@ -0,0 +1,36 @@
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
const fs = require('fs');
const content = Buffer.from(fs.readFileSync('./helloworld.txt', 'utf-8'), 'utf-8');
async function fileStore() {
for (let i = 0; i < 2 + 1; i++) {
const temp = await prisma.fileStore.upsert({
where: { id: i },
update: {},
create: {
name: 'helloworld.txt',
path: './helloworld.txt',
preview: '',
size: content.byteLength,
type: 'txt',
content: content,
},
});
}
console.log('seed fileStore done');
}
const FileStore = fileStore()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
export { FileStore };

View File

@@ -0,0 +1,75 @@
// 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,44 @@
// 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

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

View File

@@ -1,4 +1,10 @@
// src/app/api/product/details/route.ts
//
// PURPOSE:
// save product to db by id
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
@@ -10,7 +16,7 @@ import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* Get product details
* GET Product detail
*************************************** */
export async function GET(req: NextRequest) {
try {

View File

@@ -0,0 +1,30 @@
// src/app/api/product/image/upload/route.ts
//
// PURPOSE:
// handle upload product image
//
// RULES:
// T.B.A.
import type { NextRequest } from 'next/server';
import { STATUS, response, handleError } from 'src/utils/response';
// import prisma from '../../../lib/prisma';
// ----------------------------------------------------------------------
/** **************************************
* GET - Products
*************************************** */
export async function POST(req: NextRequest) {
try {
const { data } = await req.json();
console.log('helloworld');
return response({ hello: 'world' }, STATUS.OK);
} catch (error) {
console.log({ hello: 'world' });
return handleError('Product - store product image', error);
}
}

View File

@@ -22,7 +22,7 @@ export async function POST(req: NextRequest) {
const { data } = await req.json();
try {
const products = await prisma.productItem.update({
const products = await prisma.productItem.updateMany({
data: {
name: data.name,
sku: data.sku,

View File

@@ -1,42 +1,54 @@
{
"compilerOptions": {
"allowJs": true,
/* Bundler */
"baseUrl": ".",
"module": "esnext",
"esModuleInterop": true,
"incremental": true,
"isolatedModules": true,
"jsx": "preserve",
"allowJs": true,
"resolveJsonModule": true,
/* Build */
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"module": "esnext",
"moduleResolution": "bundler",
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"incremental": true,
"skipLibCheck": true,
"esModuleInterop": true,
"isolatedModules": true,
/* Linting */
"strict": true,
"noEmit": true,
"strictNullChecks": true,
/* Plugins */
"plugins": [
{
"name": "next"
}
]
],
"resolveJsonModule": true,
"skipLibCheck": true,
/* Linting */
"strict": true,
"strictNullChecks": true,
/* Build */
"target": "ES2017",
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo"
},
"exclude": [
"node_modules",
".next",
//
"**/* copy *.tsx",
"**/* copy.tsx",
"**/*.bak",
"**/*.bak",
"**/*.bug",
"**/*.del",
"**/*.draft",
"**/*.log",
"**/*.tmp",
"**/*del"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}