From 7bc234b9f6e9363dfa598c9532d201c391698c50 Mon Sep 17 00:00:00 2001 From: kennethcheng Date: Mon, 27 Apr 2026 19:40:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(api):=20=E5=BB=BA=E7=AB=8B=20assets=20?= =?UTF-8?q?=E7=9A=84=20Server=20Actions=20=E9=98=B2=E8=85=90=E5=B1=82?= =?UTF-8?q?=E4=B8=8E=20Zod=20=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 8 ++++++++ package.json | 5 +++-- src/actions/asset.ts | 37 +++++++++++++++++++++++++++++++++++++ tsconfig.json | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 src/actions/asset.ts diff --git a/package-lock.json b/package-lock.json index 5f15805..8a29cc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ }, "devDependencies": { "@types/bcryptjs": "^2.4.6", + "@types/big.js": "^6.2.2", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", @@ -2151,6 +2152,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/big.js": { + "version": "6.2.2", + "resolved": "https://registry.npmmirror.com/@types/big.js/-/big.js-6.2.2.tgz", + "integrity": "sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", diff --git a/package.json b/package.json index 85fcaba..9ca5662 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,4 @@ -{ +{ "name": "temp-next", "version": "0.1.0", "private": true, @@ -22,6 +22,7 @@ }, "devDependencies": { "@types/bcryptjs": "^2.4.6", + "@types/big.js": "^6.2.2", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", @@ -31,4 +32,4 @@ "tsx": "^4.21.0", "typescript": "^5" } -} \ No newline at end of file +} diff --git a/src/actions/asset.ts b/src/actions/asset.ts new file mode 100644 index 0000000..183a314 --- /dev/null +++ b/src/actions/asset.ts @@ -0,0 +1,37 @@ +'use server'; + +import { db } from '@/db'; +import { assets, assetTypeEnum } from '@/db/schema'; +import { z } from 'zod'; + +const createAssetSchema = z.object({ + symbol: z.string().min(1, 'Symbol is required'), + type: z.enum(['STOCK', 'CRYPTO', 'CASH']), + baseCurrency: z.string().min(2).max(10), +}); + +export async function createAsset(params: z.infer) { + const validation = createAssetSchema.safeParse(params); + if (!validation.success) { + return { success: false, error: validation.error.issues[0].message }; + } + + try { + const [asset] = await db.insert(assets).values(params).returning(); + return { success: true, data: asset }; + } catch (error: unknown) { + if ( + error && + typeof error === 'object' && + 'code' in error && + (error as { code: string }).code === '23505' + ) { + return { success: false, error: 'Asset with this symbol already exists' }; + } + throw error; + } +} + +export async function getAssets() { + return db.select().from(assets); +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 3a13f90..cf9c65d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": ["./src/*"] } }, "include": [