Explorar o código

♻️ refactor(stock): 分离股票数据的类型定义与实体类

- 将StockDataSchema、CreateStockDataDto和UpdateStockDataDto从entity文件迁移到独立的schema文件
- 更新API路由文件中的导入路径,指向新的schema文件
- 移除entity文件中的zod相关依赖和类型定义

✨ feat(stock): 增强股票数据验证规则

- 为StockDataSchema添加更严格的验证规则,包括整数和正整数检查
- 为code字段添加非空和长度限制验证
- 改进createdAt和updatedAt字段的日期格式验证
- 优化CreateStockDataDto和UpdateStockDataDto的结构,移除不必要的JSON转换逻辑
yourname hai 6 meses
pai
achega
efa50247cd

+ 1 - 1
src/server/api/stock-data/index.ts

@@ -1,7 +1,7 @@
 import { createCrudRoutes } from '@/server/utils/generic-crud.routes';
 import { OpenAPIHono } from '@hono/zod-openapi';
 import { StockData } from '@/server/modules/stock/stock-data.entity';
-import { StockDataSchema, CreateStockDataDto, UpdateStockDataDto } from '@/server/modules/stock/stock-data.entity';
+import { StockDataSchema, CreateStockDataDto, UpdateStockDataDto } from '@/server/modules/stock/stock-data.schema';
 import { authMiddleware } from '@/server/middleware/auth.middleware';
 import getStockHistoryRoute from './history/[code]/get';
 

+ 1 - 48
src/server/modules/stock/stock-data.entity.ts

@@ -1,5 +1,4 @@
 import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
-import { z } from '@hono/zod-openapi';
 
 @Entity('stock_data')
 export class StockData {
@@ -17,50 +16,4 @@ export class StockData {
 
   @Column({ name: 'updated_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP' })
   updatedAt!: Date;
-}
-
-export const StockDataSchema = z.object({
-  id: z.number().int().positive().openapi({ description: 'ID', example: 1 }),
-  code: z.string().max(255).openapi({ description: '股票代码', example: '001339' }),
-  data: z.record(z.any()).openapi({ 
-    description: '股票数据', 
-    example: { 
-      date: '2025-05-21', 
-      open: 15.68, 
-      close: 16.25, 
-      high: 16.50, 
-      low: 15.50, 
-      volume: 1250000 
-    } 
-  }),
-  createdAt: z.date().openapi({ description: '创建时间', example: '2025-05-21T16:44:36Z' }),
-  updatedAt: z.date().openapi({ description: '更新时间', example: '2025-05-21T21:22:06Z' })
-});
-
-export const CreateStockDataDto = StockDataSchema.omit({
-  id: true,
-  createdAt: true,
-  updatedAt: true
-}).partial().extend({
-  data: z.string().transform((val) => {
-    try {
-      return JSON.parse(val)
-    } catch (error) {
-      return {}
-    }
-  })
-});
-
-export const UpdateStockDataDto = StockDataSchema.omit({
-  id: true,
-  createdAt: true,
-  updatedAt: true
-}).partial().extend({
-  data: z.string().transform((val) => {
-    try {
-      return JSON.parse(val)
-    } catch (error) {
-      return {}
-    }
-  })
-});
+}

+ 73 - 0
src/server/modules/stock/stock-data.schema.ts

@@ -0,0 +1,73 @@
+import { z } from '@hono/zod-openapi';
+
+export const StockDataSchema = z.object({
+  id: z.number().int('必须是整数').positive('必须是正整数').openapi({
+    description: '股票数据ID',
+    example: 1
+  }),
+  
+  code: z.string().min(1, '股票代码不能为空').max(255, '股票代码最多255个字符').openapi({
+    description: '股票代码',
+    example: '000001'
+  }),
+  
+  data: z.record(z.string(), z.any()).openapi({
+    description: '股票数据',
+    example: {
+      price: 10.5,
+      volume: 1000,
+      open: 10.2,
+      close: 10.5,
+      high: 10.8,
+      low: 10.1
+    }
+  }),
+  
+  createdAt: z.coerce.date('创建时间格式不正确').openapi({
+    description: '创建时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  
+  updatedAt: z.coerce.date('更新时间格式不正确').openapi({
+    description: '更新时间',
+    example: '2024-01-01T12:00:00Z'
+  })
+});
+
+export const CreateStockDataDto = z.object({
+  code: z.string().min(1, '股票代码不能为空').max(255, '股票代码最多255个字符').openapi({
+    description: '股票代码',
+    example: '000001'
+  }),
+  
+  data: z.record(z.string(), z.any()).openapi({
+    description: '股票数据',
+    example: {
+      price: 10.5,
+      volume: 1000,
+      open: 10.2,
+      close: 10.5,
+      high: 10.8,
+      low: 10.1
+    }
+  })
+});
+
+export const UpdateStockDataDto = z.object({
+  code: z.string().min(1, '股票代码不能为空').max(255, '股票代码最多255个字符').optional().openapi({
+    description: '股票代码',
+    example: '000001'
+  }),
+  
+  data: z.record(z.string(), z.any()).optional().openapi({
+    description: '股票数据',
+    example: {
+      price: 10.5,
+      volume: 1000,
+      open: 10.2,
+      close: 10.5,
+      high: 10.8,
+      low: 10.1
+    }
+  })
+});