# 错误示例与正确示例对比（Wrong vs Right Examples）

> **模块**: 05_AI - 错误示例与正确示例对比  
> **更新日期**: 2026-03-20  
> **用途**: 帮助 AI 快速识别错误代码模式并避免重复犯错

---

## 📋 使用说明

本文档通过对比错误示例和正确示例，帮助 AI：

1. **快速识别错误模式**
2. **理解正确实现方式**
3. **避免重复犯错**
4. **提高代码质量**

---

## 1️⃣ TypeScript 类型安全

### 1.1 禁止 any 类型

#### ❌ 错误示例

```typescript
// 错误：使用 any 类型
function handleData(data: any) {
  return data.name
}

function processUser(user: any) {
  console.log(user.email)
  return user.id
}

const userData: any = fetchUser()
```

#### ✅ 正确示例

```typescript
// 正确：使用 unknown + 类型守卫
function handleData(data: unknown) {
  if (typeof data === 'object' && data !== null && 'name' in data) {
    return (data as { name: string }).name
  }
  throw new Error('Invalid data')
}

// 正确：使用类型守卫函数
function isUser(data: unknown): data is User {
  return (
    typeof data === 'object' &&
    data !== null &&
    'id' in data &&
    'email' in data &&
    typeof (data as User).id === 'string' &&
    typeof (data as User).email === 'string'
  )
}

function processUser(data: unknown) {
  if (isUser(data)) {
    console.log(data.email)
    return data.id
  }
  throw new Error('Invalid user data')
}

// 正确：使用 Schema 验证
const userData = UserSchema.parse(fetchUser())
```

---

### 1.2 函数必须声明返回类型

#### ❌ 错误示例

```typescript
// 错误：未声明返回类型
function getUser(userId: string) {
  return userRepository.findById(userId)
}

function calculateTotal(items: Item[]) {
  return items.reduce((sum, item) => sum + item.price, 0)
}

async function fetchData(url: string) {
  const response = await fetch(url)
  return response.json()
}
```

#### ✅ 正确示例

```typescript
// 正确：声明返回类型
function getUser(userId: string): Promise<User | null> {
  return userRepository.findById(userId)
}

function calculateTotal(items: Item[]): number {
  return items.reduce((sum, item) => sum + item.price, 0)
}

async function fetchData<T>(url: string): Promise<T> {
  const response = await fetch(url)
  return response.json() as Promise<T>
}
```

---

### 1.3 API 必须定义类型

#### ❌ 错误示例

```typescript
// 错误：未定义类型
const response = await axios.get('/api/users')
const users = response.data

const createResponse = await axios.post('/api/users', userData)

const product = await fetch('/api/products/123').then(res => res.json())
```

#### ✅ 正确示例

```typescript
// 正确：定义请求和响应类型
interface ApiResponse<T> {
  success: boolean
  data: T
  message?: string
}

interface User {
  id: string
  name: string
  email: string
}

const response = await axios.get<ApiResponse<User[]>>('/api/users')
const users = response.data.data

const createResponse = await axios.post<ApiResponse<User>>('/api/users', userData)

const product = await fetch('/api/products/123')
  .then(res => res.json() as Promise<ApiResponse<Product>>)
  .then(data => data.data)
```

---

### 1.4 类型从 Schema 推导

#### ❌ 错误示例

```typescript
// 错误：手动定义类型
interface User {
  id: string
  name: string
  email: string
  age: number
}

interface Product {
  id: string
  name: string
  price: number
}

// 错误：类型和 Schema 不一致
const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email()
  // 缺少 age 字段
})

type User = z.infer<typeof UserSchema>
```

#### ✅ 正确示例

```typescript
// 正确：从 Schema 推导类型
import { z } from 'zod'

const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().positive()
})

type User = z.infer<typeof UserSchema>

const ProductSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(200),
  price: z.number().positive()
})

type Product = z.infer<typeof ProductSchema>
```

---

### 1.5 统一类型中心

#### ❌ 错误示例

```typescript
// 错误：各模块重复定义类型
// dashboard/src/pages/User/User.tsx
interface User {
  id: string
  name: string
}

// server/src/models/User.ts
interface User {
  id: string
  name: string
  email: string
}

// extension/src/types/User.ts
interface User {
  id: string
  name: string
  email: string
  role: string
}
```

#### ✅ 正确示例

```typescript
// 正确：从类型中心导入
// types/domain/User.ts
export const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  role: z.enum(['ADMIN', 'MANAGER', 'OPERATOR'])
})

export type User = z.infer<typeof UserSchema>

// dashboard/src/pages/User/User.tsx
import { User } from '@/types/domain/User'

// server/src/models/User.ts
import { User } from '@/types/domain/User'

// node-agent/src/index.ts
import { User } from '@/types/domain/User'
```

---

## 2️⃣ 逻辑集中化

### 2.1 Controller 层职责

#### ❌ 错误示例

```typescript
// 错误：Controller 中写业务逻辑
export class UserController {
  async createUser(req: Request, res: Response) {
    const { username, email, password } = req.body
    
    // 业务逻辑在 Controller 中
    if (!username || !email || !password) {
      return res.status(400).json({ error: 'Missing fields' })
    }
    
    if (password.length < 8) {
      return res.status(400).json({ error: 'Password too short' })
    }
    
    const hashedPassword = await bcrypt.hash(password, 10)
    
    const user = await this.userRepository.create({
      username,
      email,
      passwordHash: hashedPassword,
      role: 'OPERATOR',
      status: 'ACTIVE'
    })
    
    res.json(user)
  }
}
```

#### ✅ 正确示例

```typescript
// 正确：Controller 只负责请求/响应
export class UserController {
  constructor(private readonly userService: UserService) {}

  async createUser(req: Request, res: Response) {
    try {
      const userDTO = await this.userService.createUser(req.body)
      res.json(createSuccessResponse(userDTO))
    } catch (error) {
      if (error instanceof ValidationError) {
        res.status(400).json(createErrorResponse('VALIDATION_ERROR', error.message))
      } else {
        res.status(500).json(createErrorResponse('INTERNAL_ERROR', error.message))
      }
    }
  }
}

// 业务逻辑在 Service 层
export class UserService {
  async createUser(request: CreateUserRequest): Promise<UserDTO> {
    // 1. 验证请求数据
    const validatedRequest = CreateUserRequestSchema.parse(request)
    
    // 2. 业务逻辑处理
    const hashedPassword = await this.hashPassword(validatedRequest.password)
    
    // 3. 创建领域模型
    const user = UserSchema.parse({
      id: crypto.randomUUID(),
      username: validatedRequest.username,
      email: validatedRequest.email,
      passwordHash: hashedPassword,
      role: validatedRequest.role || 'OPERATOR',
      status: 'ACTIVE',
      createdAt: new Date(),
      updatedAt: new Date()
    })
    
    // 4. 保存到数据库
    const savedUser = await this.userRepository.create(user)
    
    // 5. 转换为 DTO
    return toUserDTO(savedUser)
  }
}
```

---

### 2.2 前端业务规则

#### ❌ 错误示例

```typescript
// 错误：前端直接写业务规则
function ProductCard({ product }: { product: Product }) {
  // 业务规则在前端
  const profitMargin = (product.price - product.cost) / product.price
  
  // 业务判断在前端
  const canSell = profitMargin >= 0.15
  
  // 状态判断在前端
  const statusText = product.status === 'ACTIVE' ? '可售' : '不可售'
  
  return (
    <div>
      <h3>{product.name}</h3>
      <p>利润率: {(profitMargin * 100).toFixed(2)}%</p>
      <p>状态: {statusText}</p>
      {canSell && <button>购买</button>}
    </div>
  )
}
```

#### ✅ 正确示例

```typescript
// 正确：前端只负责展示
function ProductCard({ product }: { product: ProductDTO }) {
  return (
    <div>
      <h3>{product.name}</h3>
      <p>利润率: {product.profitMargin}%</p>
      <p>状态: {product.statusText}</p>
      {product.canSell && <button onClick={() => handleBuy(product)}>购买</button>}
    </div>
  )
}

// 业务规则在 Service 层
export class ProductService {
  async getProduct(id: string): Promise<ProductDTO> {
    const product = await this.productRepository.findById(id)
    
    if (!product) {
      throw new NotFoundError('Product', id)
    }
    
    // 业务规则计算
    const profitMargin = this.calculateProfitMargin(product)
    const canSell = this.checkProfitMargin(profitMargin, product.businessType)
    const statusText = this.getStatusText(product.status)
    
    return {
      ...product,
      profitMargin: (profitMargin * 100).toFixed(2),
      canSell,
      statusText
    }
  }
  
  private calculateProfitMargin(product: Product): number {
    return (product.price - product.cost) / product.price
  }
  
  private checkProfitMargin(margin: number, businessType: 'B2B' | 'B2C'): boolean {
    const threshold = businessType === 'B2B' ? 0.15 : 0.20
    return margin >= threshold
  }
}
```

---

### 2.3 数据库操作

#### ❌ 错误示例

```typescript
// 错误：直接操作数据库
export class UserController {
  async getUser(req: Request, res: Response) {
    // 直接使用数据库连接
    const user = await db('users').where({ id: req.params.id }).first()
    res.json(user)
  }
}

// 错误：跨模块直接操作数据库
export class OrderService {
  async createOrder(orderData: OrderData) {
    // 直接操作商品表
    const product = await db('products').where({ id: orderData.productId }).first()
    
    // 直接更新库存
    await db('inventory').where({ product_id: orderData.productId }).decrement('quantity', orderData.quantity)
    
    // 直接创建订单
    const order = await db('orders').insert(orderData)
    
    return order
  }
}
```

#### ✅ 正确示例

```typescript
// 正确：通过 Repository 层操作数据库
export class UserController {
  constructor(
    private readonly userService: UserService
  ) {}

  async getUser(req: Request, res: Response) {
    const user = await this.userService.getUser(req.params.id)
    res.json(createSuccessResponse(user))
  }
}

// 正确：通过 Service 层协调多模块
export class OrderService {
  constructor(
    private readonly orderRepository: OrderRepository,
    private readonly productService: ProductService,
    private readonly inventoryService: InventoryService
  ) {}

  async createOrder(orderData: OrderData): Promise<Order> {
    // 通过 Service 获取商品信息
    const product = await this.productService.getProduct(orderData.productId)
    
    // 通过 Service 更新库存
    await this.inventoryService.decreaseStock(orderData.productId, orderData.quantity)
    
    // 通过 Repository 创建订单
    const order = await this.orderRepository.create(orderData)
    
    return order
  }
}
```

---

## 3️⃣ 数据安全

### 3.1 表命名规范

#### ❌ 错误示例

```typescript
// 错误：表名不以 cf_ 开头
await db.schema.createTable('users', (table) => {
  table.string('id').primary()
  table.string('name')
  table.string('email')
})

await db.schema.createTable('products', (table) => {
  table.string('id').primary()
  table.string('name')
  table.decimal('price')
})
```

#### ✅ 正确示例

```typescript
// 正确：表名以 cf_ 开头
await db.schema.createTable('cf_users', (table) => {
  table.string('id').primary()
  table.string('name')
  table.string('email')
})

await db.schema.createTable('cf_products', (table) => {
  table.string('id').primary()
  table.string('name')
  table.decimal('price', 10, 2) // 金额字段使用 decimal(10,2)
})
```

---

### 3.2 金额字段

#### ❌ 错误示例

```typescript
// 错误：金额字段使用 float/double
await db.schema.createTable('cf_orders', (table) => {
  table.string('id').primary()
  table.float('total_amount') // 错误
  table.double('subtotal') // 错误
})

// 错误：金额计算使用浮点数
const total = 10.5 + 20.3 // 30.800000000000004
const price = product.price * 1.1 // 浮点数精度问题
```

#### ✅ 正确示例

```typescript
// 正确：金额字段使用 decimal(10,2)
await db.schema.createTable('cf_orders', (table) => {
  table.string('id').primary()
  table.decimal('total_amount', 10, 2) // 正确
  table.decimal('subtotal', 10, 2) // 正确
})

// 正确：金额计算使用整数（分）或 decimal
const total = Math.round((10.5 + 20.3) * 100) / 100 // 30.80
const price = Math.round(product.price * 1.1 * 100) / 100

// 或使用 decimal.js
import Decimal from 'decimal.js'
const total = new Decimal(10.5).plus(20.3).toNumber() // 30.8
```

---

### 3.3 五元组

#### ❌ 错误示例

```typescript
// 错误：缺少五元组
async function processOrder(orderId: string) {
  const order = await orderRepository.findById(orderId)
  await orderService.process(order)
}

// 错误：五元组不完整
const log = {
  orderId: '123',
  action: 'process',
  timestamp: new Date()
}
```

#### ✅ 正确示例

```typescript
// 正确：包含完整五元组
interface TaskContext {
  tenantId: string
  shopId: string
  taskId: string
  traceId: string
  businessType: 'TOC' | 'TOB'
}

async function processOrder(orderId: string, context: TaskContext) {
  const order = await orderRepository.findById(orderId)
  
  // 记录日志时包含五元组
  logger.info('Processing order', {
    ...context,
    orderId,
    action: 'process'
  })
  
  await orderService.process(order, context)
}

// 正确：五元组完整
const log = {
  tenantId: 'tenant-123',
  shopId: 'shop-456',
  taskId: 'task-789',
  traceId: 'trace-abc',
  businessType: 'TOC',
  orderId: '123',
  action: 'process',
  timestamp: new Date()
}
```

---

## 4️⃣ 业务规则

### 4.1 状态机流转

#### ❌ 错误示例

```typescript
// 错误：非法状态流转
async function updateOrderStatus(orderId: string, newStatus: string) {
  const order = await orderRepository.findById(orderId)
  
  // 直接修改状态，未检查流转规则
  order.status = newStatus
  await orderRepository.update(orderId, order)
}

// 错误：跳过状态
async function shipOrder(orderId: string) {
  const order = await orderRepository.findById(orderId)
  
  // 从 PENDING 直接跳到 SHIPPED，跳过 PAID 和 PROCESSING
  order.status = 'SHIPPED'
  await orderRepository.update(orderId, order)
}
```

#### ✅ 正确示例

```typescript
// 正确：通过 Service 层遵循状态机
export class OrderService {
  private readonly STATE_TRANSITIONS = {
    PENDING: ['PAID', 'CANCELLED'],
    PAID: ['PROCESSING', 'REFUNDED'],
    PROCESSING: ['SHIPPED', 'REFUNDED'],
    SHIPPED: ['COMPLETED', 'REFUNDED'],
    COMPLETED: [],
    CANCELLED: [],
    REFUNDED: []
  }

  async updateOrderStatus(
    orderId: string,
    newStatus: OrderStatus,
    context: TaskContext
  ): Promise<Order> {
    const order = await this.orderRepository.findById(orderId)
    
    if (!order) {
      throw new NotFoundError('Order', orderId)
    }
    
    // 检查状态流转是否合法
    if (!this.isValidTransition(order.status, newStatus)) {
      throw new Error(`Invalid state transition: ${order.status} -> ${newStatus}`)
    }
    
    // 更新状态
    order.status = newStatus
    order.updatedAt = new Date()
    
    const updatedOrder = await this.orderRepository.update(orderId, order)
    
    // 记录状态变更日志
    logger.info('Order status updated', {
      ...context,
      orderId,
      fromStatus: order.status,
      toStatus: newStatus
    })
    
    return updatedOrder
  }
  
  private isValidTransition(from: OrderStatus, to: OrderStatus): boolean {
    return this.STATE_TRANSITIONS[from]?.includes(to) || false
  }
}
```

---

### 4.2 权限校验

#### ❌ 错误示例

```typescript
// 错误：硬编码权限判断
async function deleteUser(userId: string, req: Request) {
  const user = req.user
  
  // 硬编码权限判断
  if (user.role !== 'ADMIN') {
    throw new Error('Permission denied')
  }
  
  await userRepository.delete(userId)
}

// 错误：跳过权限校验
async function getAllUsers() {
  return await userRepository.findAll()
}
```

#### ✅ 正确示例

```typescript
// 正确：使用 authorize 中间件
import { authorize } from '@/middleware/auth'

router.delete('/users/:id',
  authorize('user:delete'),
  userController.deleteUser
)

// 正确：Controller 中调用 Service
export class UserController {
  async deleteUser(req: Request, res: Response) {
    await this.userService.deleteUser(req.params.id)
    res.json(createSuccessResponse({ message: 'User deleted' }))
  }
}

// 正确：Service 层实现权限逻辑
export class UserService {
  async deleteUser(userId: string): Promise<void> {
    // 检查用户是否存在
    const user = await this.userRepository.findById(userId)
    if (!user) {
      throw new NotFoundError('User', userId)
    }
    
    // 执行删除
    await this.userRepository.delete(userId)
  }
}
```

---

### 4.3 利润红线

#### ❌ 错误示例

```typescript
// 错误：未检查利润红线
async function createQuote(productId: string, price: number) {
  const product = await productRepository.findById(productId)
  
  // 未检查利润率
  const quote = await quoteRepository.create({
    productId,
    price,
    status: 'ACTIVE'
  })
  
  return quote
}

// 错误：仅用售价 - 采购价判断
const profit = price - product.cost
if (profit > 0) {
  // 允许报价
}
```

#### ✅ 正确示例

```typescript
// 正确：使用 PricingService 检查利润红线
export class QuoteService {
  constructor(
    private readonly pricingService: PricingService,
    private readonly quoteRepository: QuoteRepository
  ) {}

  async createQuote(
    productId: string,
    price: number,
    businessType: 'B2B' | 'B2C'
  ): Promise<Quote> {
    const product = await this.productRepository.findById(productId)
    
    if (!product) {
      throw new NotFoundError('Product', productId)
    }
    
    // 计算净利率（含平台费/物流/税费/汇率/售后/广告摊销）
    const profitMargin = await this.pricingService.calculateProfitMargin({
      price,
      cost: product.cost,
      platform: product.platform,
      businessType
    })
    
    // 检查利润红线
    if (businessType === 'B2B' && profitMargin < 0.15) {
      throw new Error('B2B profit margin must be at least 15%')
    }
    
    if (businessType === 'B2C' && profitMargin < 0.20) {
      // 触发风控预警
      await this.riskAlertService.createAlert({
        type: 'LOW_PROFIT_MARGIN',
        productId,
        profitMargin,
        threshold: 0.20
      })
    }
    
    // 创建报价
    const quote = await this.quoteRepository.create({
      productId,
      price,
      profitMargin,
      status: 'ACTIVE'
    })
    
    return quote
  }
}
```

---

## 5️⃣ Mock 数据

### 5.1 硬编码 Mock 数据

#### ❌ 错误示例

```typescript
// 错误：在业务组件中硬编码 Mock 数据
function ProductList() {
  const products = [
    { id: 1, name: 'Mock商品1', price: 100 },
    { id: 2, name: 'Mock商品2', price: 200 }
  ]
  
  return (
    <div>
      {products.map(p => (
        <div key={p.id}>{p.name}</div>
      ))}
    </div>
  )
}

// 错误：通过 if 判断切换 Mock/真实数据
async function getProducts() {
  if (process.env.NODE_ENV === 'development') {
    return mockProducts
  }
  return await api.getProducts()
}
```

#### ✅ 正确示例

```typescript
// 正确：通过 DataSource 抽象层
// services/productDataSource.ts
import { ProductDTOSchema, type ProductDTO } from '@/types'

export const productDataSource = {
  async list(): Promise<ProductDTO[]> {
    if (process.env.REACT_APP_USE_MOCK === 'true') {
      const { mockProducts } = await import('@/mock/data/product.mock')
      return mockProducts.map(p => ProductDTOSchema.parse(p))
    }
    
    const response = await api.getProducts()
    return response.data.map(p => ProductDTOSchema.parse(p))
  }
}

// components/ProductList.tsx
function ProductList() {
  const { data: products } = useQuery({
    queryKey: ['products'],
    queryFn: () => productDataSource.list()
  })
  
  return (
    <div>
      {products?.map(p => (
        <div key={p.id}>{p.name}</div>
      ))}
    </div>
  )
}

// mock/data/product.mock.ts
/**
 * [MOCK] 商品 Mock 数据
 * AI注意: 这是Mock实现，不是真实业务逻辑
 * 仅在USE_MOCK=true时启用
 */
export const mockProducts = [
  { id: '1', name: '商品1', price: 100 },
  { id: '2', name: '商品2', price: 200 }
]
```

---

## 📊 总结

| 类别 | 常见错误 | 正确做法 |
|------|----------|----------|
| **TypeScript** | 使用 any、不声明返回类型 | 使用 unknown + 类型守卫、声明返回类型 |
| **逻辑集中化** | Controller 写业务逻辑 | 业务逻辑在 Service 层 |
| **数据安全** | 表名无前缀、金额用 float | 表名 cf_ 前缀、金额用 decimal(10,2) |
| **业务规则** | 非法状态流转、跳过权限校验 | 遵循状态机、使用 authorize 中间件 |
| **Mock 数据** | 硬编码 Mock、if 判断切换 | DataSource 抽象层、环境变量控制 |

---

*本文档持续更新，帮助 AI 避免常见错误。*
