cursor-init/.cursor/rules/api-development-standard.md
expressgy a23d336ebd refactor: 重构项目架构并标准化开发规范
- 重构项目结构:controllers/services -> modules模块化组织

- 新增Drizzle ORM集成和数据库schema定义

- 添加完整的开发规范文档(.cursor/rules/)

- 重新组织插件结构为子目录方式

- 新增用户模块和示例代码

- 更新类型定义并移除试验性代码

- 添加API文档和JWT使用示例

关联任务计划文档
2025-06-30 01:25:17 +08:00

175 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API 开发规范
## 文件结构
每个API模块必须包含以下文件
- `*.schema.ts` - 请求参数和数据结构定义 + TypeScript类型导出
- `*.response.ts` - 响应格式定义 + 响应类型导出
- `*.service.ts` - 业务逻辑实现(使用类型注解)
- `*.controller.ts` - 路由和控制器使用Schema验证
- `*.test.ts` - 测试用例(类型安全的测试数据)
## 开发流程
1. **Schema 定义** - 使用 TypeBox 定义请求参数和数据结构导出TypeScript类型
2. **Response 定义** - 基于全局响应格式定义各种场景的响应,导出响应类型
3. **Service 实现** - 编写业务逻辑,使用类型注解确保类型安全
4. **Controller 实现** - 集成JWT认证、Schema验证、错误处理
5. **测试编写** - 使用类型安全的测试数据,覆盖正常、异常、边界场景
## 必须遵循
### 1. 认证与授权
```typescript
// 需要认证的接口必须使用 jwtAuthPlugin
export const controller = new Elysia().use(jwtAuthPlugin).get('/protected-route', handler, options);
```
### 2. 参数验证与类型使用
```typescript
// example.schema.ts - 定义Schema和导出类型
import { t, type Static } from 'elysia';
export const GetUserByUsernameSchema = t.Object({
username: t.String({ minLength: 2, maxLength: 50 }),
});
// 导出TypeScript类型
export type GetUserByUsernameParams = Static<typeof GetUserByUsernameSchema>;
// example.service.ts - Service中使用类型
import type { GetUserByUsernameParams } from './example.schema';
export class ExampleService {
async getUserByUsername(params: GetUserByUsernameParams): Promise<UserInfo> {
const { username } = params; // 类型安全
// 业务逻辑...
}
}
// example.controller.ts - Controller中使用Schema验证
export const controller = new Elysia().use(jwtAuthPlugin).get('/user/:username', handler, {
params: GetUserByUsernameSchema, // 运行时验证
});
```
**要求:**
- ✅ 每个Schema必须导出对应的TypeScript类型
- ✅ Service方法必须使用类型注解
- ❌ 禁止行内定义任何参数Schema
### 3. 统一响应格式
```typescript
// 成功响应
return {
code: ERROR_CODES.SUCCESS,
message: '操作成功',
data: result,
};
// 错误响应
return {
code: ERROR_CODES.BUSINESS_ERROR,
message: '具体错误信息',
data: null,
};
```
- 响应内容的类型需要在.response.ts中定义
### 4. 错误处理
```typescript
try {
const result = await service.method();
return successResponse(result);
} catch (error) {
Logger.error(new Error(`操作失败: ${error}`));
const errorMessage = error instanceof Error ? error.message : '未知错误';
if (errorMessage.includes('特定错误')) {
set.status = 400;
return errorResponse(ERROR_CODES.BUSINESS_ERROR, '业务错误消息');
}
set.status = 500;
return errorResponse(ERROR_CODES.INTERNAL_ERROR, '服务器内部错误');
}
```
### 5. 文档配置
```typescript
{
detail: {
summary: '接口简要描述',
description: '接口详细描述',
tags: [tags.moduleName],
security: [{ bearerAuth: [] }], // 需要认证时添加
},
response: PredefinedResponses,
}
```
### 6. 日志记录
```typescript
// 接口调用日志
Logger.info(`接口被调用,参数: ${param}, 用户: ${JSON.stringify(user)}`);
// 成功日志
Logger.info(`操作成功,结果: ${result.id}`);
// 错误日志
Logger.error(new Error(`操作失败,错误: ${error}`));
```
### 7. 必要的注释
1. 接口名称注释
```typescript
export const controller = new Elysia()
.use(jwtAuthPlugin)
/**
* 根据用户名查询用户信息
* @route GET /api/sample/user/:username
* @description 通过用户名查询用户的详细信息需要JWT认证
* @param username 用户名路径参数长度2-50字符
* @returns 用户信息对象或错误响应
* @modification hotok 2025-06-29 初始实现
*/
.get('/protected-route', handler, options);
```
## 禁止事项
- ❌ 直接在 Controller 中写业务逻辑
- ❌ 不进行参数验证
- ❌ 返回非标准格式的响应
- ❌ 暴露敏感信息(如密码哈希)
- ❌ 缺少错误处理和日志记录
- ❌ 不编写测试用例
## 命名规范
- 文件名:`module.type.ts`(如:`user.controller.ts`
- Schema`GetUserByIdSchema`、`CreateUserSchema`
- Response`GetUserSuccessResponse`、`UserErrorResponse`
- Service 类:`UserService`、导出实例:`userService`
- Controller`userController`
## 测试要求
每个接口必须包含:
- ✅ 正常流程测试
- ✅ 参数验证边界测试(最短、最长、无效格式)
- ✅ 业务逻辑异常测试(不存在、权限不足等)
- ✅ 认证相关测试无Token、无效Token、过期Token
- ✅ 响应格式验证状态码、code、message、data结构