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

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

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

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

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

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

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

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

30 KiB
Raw Blame History

Elysia 接口编写规范Elysia Interface Development Standards

目标 (Goal)

本规范旨在提供一套完整的 Elysia 接口开发标准,结合官方文档最佳实践、社区经验和项目实际需求,确保代码质量、类型安全和开发效率。

核心原则 (Core Principles)

1. 一切皆组件 (Everything is a Component)

  • 每个 Elysia 实例都是一个组件
  • 组件可以被插入到其他实例中
  • 强制将应用拆分为小块,便于添加或移除功能

2. 方法链式调用 (Method Chaining)

  • 必须始终使用方法链式调用
  • 确保类型完整性和推断
  • 每个方法返回新的类型引用

3. 类型安全优先 (Type Safety First)

  • 使用 Elysia 内置类型系统
  • 避免使用 any 类型
  • 单一数据源原则

项目结构规范 (Project Structure Standards)

推荐目录结构

src/
├── controllers/           # 控制器(路由与业务入口)
│   ├── auth/
│   │   └── index.ts      # 认证相关路由
│   └── user/
│       └── index.ts      # 用户相关路由
├── services/             # 业务逻辑服务层
│   ├── auth/
│   │   └── auth.service.ts
│   └── user/
│       └── user.service.ts
├── validators/           # 参数校验(按路由结构组织)
│   ├── global.response.ts
│   ├── auth/
│   │   ├── auth.validator.ts
│   │   └── auth.response.ts
│   └── user/
│       ├── user.validator.ts
│       └── user.response.ts
├── models/               # 数据模型
├── plugins/              # Elysia 插件
├── utils/                # 工具函数
├── config/               # 配置文件
├── type/                 # 类型定义文件
└── app.ts               # 应用入口

接口设计规范 (Interface Design Standards)

1. 控制器规范 (Controller Standards)

正确做法:使用 Elysia 实例作为控制器

/**
 * @file        用户认证控制器
 * @author      开发者姓名
 * @date        2024-01-01
 * @lastEditor  开发者姓名
 * @lastEditTime 2024-01-01
 * @description 用户认证相关接口包含登录、注册、token 验证等功能
 */

import { Elysia } from 'elysia';
import { jwtPlugin } from '@/plugins/jwt.plugins';
import { 
    loginBodySchema, 
    registerBodySchema,
    type LoginBody, 
    type RegisterBody 
} from '@/validators/auth/auth.validator';
import { 
    loginResponse200Schema, 
    loginResponse400Schema,
    registerResponse200Schema,
    registerResponse400Schema
} from '@/validators/auth/auth.response';
import { loginService, registerService } from '@/services/auth/auth.service';

/**
 * 认证控制器
 * @description 处理用户认证相关的 HTTP 请求
 */
export const authController = new Elysia({ prefix: '/api/auth' })
    .use(jwtPlugin)
    .post('/login', 
        ({ body, jwt, set }: { body: LoginBody; jwt: any; set: any }) => 
            loginService(body, jwt, set), 
        {
            body: loginBodySchema,
            detail: {
                tags: ['认证'],
                summary: '用户登录',
                description: '用户使用用户名和密码进行登录,成功后返回 JWT token',
            },
            response: {
                200: loginResponse200Schema,
                400: loginResponse400Schema,
            },
        }
    )
    .post('/register',
        ({ body, set }: { body: RegisterBody; set: any }) =>
            registerService(body, set),
        {
            body: registerBodySchema,
            detail: {
                tags: ['认证'],
                summary: '用户注册',
                description: '新用户注册账户',
            },
            response: {
                200: registerResponse200Schema,
                400: registerResponse400Schema,
            },
        }
    );

错误做法:创建单独的控制器类

// ❌ 不要这样做
abstract class AuthController {
    static login(context: Context) {
        return AuthService.login(context.body);
    }
}

new Elysia()
    .post('/login', AuthController.login);

2. 服务层规范 (Service Layer Standards)

非请求依赖服务 (Non-Request Dependent Service)

/**
 * @file        用户认证业务逻辑服务
 * @author      开发者姓名
 * @date        2024-01-01
 * @lastEditor  开发者姓名
 * @lastEditTime 2024-01-01
 * @description 处理用户认证相关的业务逻辑,与 HTTP 请求解耦
 */

import { hash, verify } from 'bun';
import { sign } from 'jsonwebtoken';
import type { LoginBody, RegisterBody } from '@/validators/auth/auth.validator';

/**
 * 认证服务类
 * @description 处理用户认证业务逻辑
 */
export abstract class AuthService {
    /**
     * 用户登录业务逻辑
     * @param body 登录请求体
     * @param jwt JWT 插件实例
     * @param set Elysia set 对象
     * @returns 登录响应
     * @modification 张三 2024-01-02 添加密码验证逻辑
     */
    static async login(
        body: LoginBody, 
        jwt: any, 
        set: any
    ) {
        const { username, password } = body;
        
        try {
            // 查询用户
            const user = await this.findUserByUsername(username);
            if (!user) {
                set.status = 400;
                return {
                    code: 400,
                    message: '用户名或密码错误',
                    data: null,
                };
            }

            // 验证密码
            const isValidPassword = await this.verifyPassword(password, user.password);
            if (!isValidPassword) {
                set.status = 400;
                return {
                    code: 400,
                    message: '用户名或密码错误',
                    data: null,
                };
            }

            // 生成 token
            const token = await jwt.sign({ 
                userId: user.id, 
                username: user.username 
            });

            return {
                code: 0,
                message: '登录成功',
                data: { 
                    token,
                    userInfo: {
                        id: user.id,
                        username: user.username,
                        email: user.email
                    }
                },
            };
        } catch (error) {
            set.status = 500;
            return {
                code: 500,
                message: '服务器内部错误',
                data: null,
            };
        }
    }

    /**
     * 用户注册业务逻辑
     * @param body 注册请求体
     * @param set Elysia set 对象
     * @returns 注册响应
     */
    static async register(body: RegisterBody, set: any) {
        const { username, email, password } = body;
        
        try {
            // 检查用户是否已存在
            const existingUser = await this.findUserByUsername(username);
            if (existingUser) {
                set.status = 400;
                return {
                    code: 400,
                    message: '用户名已存在',
                    data: null,
                };
            }

            // 检查邮箱是否已存在
            const existingEmail = await this.findUserByEmail(email);
            if (existingEmail) {
                set.status = 400;
                return {
                    code: 400,
                    message: '邮箱已被注册',
                    data: null,
                };
            }

            // 加密密码
            const hashedPassword = await this.hashPassword(password);

            // 创建用户
            const newUser = await this.createUser({
                username,
                email,
                password: hashedPassword
            });

            return {
                code: 0,
                message: '注册成功',
                data: {
                    userId: newUser.id,
                    username: newUser.username
                },
            };
        } catch (error) {
            set.status = 500;
            return {
                code: 500,
                message: '服务器内部错误',
                data: null,
            };
        }
    }

    /**
     * 根据用户名查找用户
     * @param username 用户名
     * @returns 用户信息或 null
     */
    private static async findUserByUsername(username: string) {
        // 实际项目中应该从数据库查询
        // 这里仅作示例
        return null;
    }

    /**
     * 根据邮箱查找用户
     * @param email 邮箱
     * @returns 用户信息或 null
     */
    private static async findUserByEmail(email: string) {
        // 实际项目中应该从数据库查询
        return null;
    }

    /**
     * 验证密码
     * @param plainPassword 明文密码
     * @param hashedPassword 加密后的密码
     * @returns 是否匹配
     */
    private static async verifyPassword(
        plainPassword: string, 
        hashedPassword: string
    ): Promise<boolean> {
        return await verify(plainPassword, hashedPassword);
    }

    /**
     * 密码加密
     * @param password 明文密码
     * @returns 加密后的密码
     */
    private static async hashPassword(password: string): Promise<string> {
        return await hash(password);
    }

    /**
     * 创建用户
     * @param userData 用户数据
     * @returns 创建的用户信息
     */
    private static async createUser(userData: {
        username: string;
        email: string;
        password: string;
    }) {
        // 实际项目中应该保存到数据库
        return {
            id: Math.random().toString(36),
            ...userData
        };
    }
}

请求依赖服务 (Request Dependent Service)

/**
 * 请求依赖的认证服务
 * @description 需要访问请求上下文的服务应该作为 Elysia 实例
 */
export const RequestAuthService = new Elysia({ name: 'Auth.Service' })
    .derive({ as: 'global' }, ({ cookie: { session } }) => ({
        Auth: {
            user: session.value
        }
    }))
    .macro(({ onBeforeHandle }) => ({
        /**
         * 检查用户是否已登录
         * @param value 是否需要登录
         */
        requireAuth(value: boolean) {
            if (value) {
                onBeforeHandle(({ Auth, status }) => {
                    if (!Auth?.user) {
                        return status(401, {
                            code: 401,
                            message: '请先登录',
                            data: null
                        });
                    }
                });
            }
        }
    }));

3. 参数校验规范 (Validation Standards)

/**
 * @file        认证接口参数校验规则
 * @author      开发者姓名
 * @date        2024-01-01
 * @lastEditor  开发者姓名
 * @lastEditTime 2024-01-01
 * @description 认证相关接口的参数校验规则,包含详细的验证规则和错误提示
 */

import { t } from 'elysia';
import type { Static } from 'elysia';

/**
 * 登录请求参数校验规则
 * @property {string} username - 用户名2-16位字符
 * @property {string} password - 密码6-32位字符
 */
export const loginBodySchema = t.Object({
    username: t.String({ 
        minLength: 2, 
        maxLength: 16,
        description: '用户名2-16位字符',
        examples: ['admin', 'user123']
    }),
    password: t.String({ 
        minLength: 6, 
        maxLength: 32,
        description: '密码6-32位字符'
    }),
}, {
    description: '用户登录请求参数'
});

/**
 * 注册请求参数校验规则
 * @property {string} username - 用户名2-16位字符
 * @property {string} email - 邮箱地址
 * @property {string} password - 密码6-32位字符
 * @property {string} confirmPassword - 确认密码
 */
export const registerBodySchema = t.Object({
    username: t.String({ 
        minLength: 2, 
        maxLength: 16,
        description: '用户名2-16位字符',
        pattern: '^[a-zA-Z0-9_]+$' // 只允许字母、数字、下划线
    }),
    email: t.String({ 
        format: 'email',
        description: '邮箱地址',
        examples: ['user@example.com']
    }),
    password: t.String({ 
        minLength: 6, 
        maxLength: 32,
        description: '密码6-32位字符至少包含字母和数字',
        pattern: '^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d@$!%*#?&]+$'
    }),
    confirmPassword: t.String({
        description: '确认密码,必须与密码一致'
    })
}, {
    description: '用户注册请求参数'
});

/**
 * 密码重置请求参数校验规则
 */
export const resetPasswordBodySchema = t.Object({
    email: t.String({ 
        format: 'email',
        description: '注册时使用的邮箱地址'
    }),
    newPassword: t.String({ 
        minLength: 6, 
        maxLength: 32,
        description: '新密码6-32位字符'
    }),
    verificationCode: t.String({
        minLength: 6,
        maxLength: 6,
        description: '6位数字验证码',
        pattern: '^\\d{6}$'
    })
});

/**
 * 查询参数校验规则
 */
export const userListQuerySchema = t.Object({
    page: t.Optional(t.Number({ 
        minimum: 1, 
        default: 1,
        description: '页码从1开始'
    })),
    pageSize: t.Optional(t.Number({ 
        minimum: 1, 
        maximum: 100, 
        default: 10,
        description: '每页数量1-100'
    })),
    keyword: t.Optional(t.String({
        maxLength: 50,
        description: '搜索关键词'
    }))
});

/**
 * 路径参数校验规则
 */
export const userParamsSchema = t.Object({
    id: t.String({
        minLength: 1,
        description: '用户ID'
    })
});

// 类型导出
export type LoginBody = Static<typeof loginBodySchema>;
export type RegisterBody = Static<typeof registerBodySchema>;
export type ResetPasswordBody = Static<typeof resetPasswordBodySchema>;
export type UserListQuery = Static<typeof userListQuerySchema>;
export type UserParams = Static<typeof userParamsSchema>;

4. 响应格式规范 (Response Format Standards)

/**
 * @file        认证接口响应格式定义
 * @author      开发者姓名
 * @date        2024-01-01
 * @lastEditor  开发者姓名
 * @lastEditTime 2024-01-01
 * @description 认证相关接口的响应格式定义,确保响应结构的一致性
 */

import { t } from 'elysia';

/**
 * 登录成功响应格式
 */
export const loginResponse200Schema = t.Object({
    code: t.Literal(0, {
        description: '成功响应码'
    }),
    message: t.String({
        description: '响应消息',
        examples: ['登录成功']
    }),
    data: t.Object({
        /** JWT token */
        token: t.String({
            description: 'JWT 访问令牌',
            examples: ['eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...']
        }),
        /** 用户信息 */
        userInfo: t.Object({
            id: t.String({
                description: '用户ID'
            }),
            username: t.String({
                description: '用户名'
            }),
            email: t.String({
                description: '邮箱地址'
            })
        })
    })
}, {
    description: '登录成功响应'
});

/**
 * 登录失败响应格式
 */
export const loginResponse400Schema = t.Object({
    code: t.Literal(400, {
        description: '客户端错误响应码'
    }),
    message: t.String({
        description: '错误消息',
        examples: ['用户名或密码错误', '参数验证失败']
    }),
    data: t.Null({
        description: '错误时数据为null'
    }),
}, {
    description: '登录失败响应'
});

/**
 * 注册成功响应格式
 */
export const registerResponse200Schema = t.Object({
    code: t.Literal(0),
    message: t.String({
        examples: ['注册成功']
    }),
    data: t.Object({
        userId: t.String({
            description: '新创建的用户ID'
        }),
        username: t.String({
            description: '用户名'
        })
    })
});

/**
 * 注册失败响应格式
 */
export const registerResponse400Schema = t.Object({
    code: t.Literal(400),
    message: t.String({
        examples: ['用户名已存在', '邮箱已被注册', '密码不符合要求']
    }),
    data: t.Null(),
});

/**
 * 通用未授权响应格式
 */
export const unauthorizedResponse401Schema = t.Object({
    code: t.Literal(401),
    message: t.String({
        examples: ['请先登录', 'Token已过期', 'Token无效']
    }),
    data: t.Null(),
});

/**
 * 用户列表响应格式
 */
export const userListResponse200Schema = t.Object({
    code: t.Literal(0),
    message: t.String(),
    data: t.Object({
        list: t.Array(t.Object({
            id: t.String(),
            username: t.String(),
            email: t.String(),
            createdAt: t.String({
                format: 'date-time',
                description: '创建时间'
            }),
            updatedAt: t.String({
                format: 'date-time',
                description: '更新时间'
            })
        })),
        pagination: t.Object({
            page: t.Number({
                description: '当前页码'
            }),
            pageSize: t.Number({
                description: '每页数量'
            }),
            total: t.Number({
                description: '总条数'
            }),
            totalPages: t.Number({
                description: '总页数'
            })
        })
    })
});

错误处理规范 (Error Handling Standards)

全局错误处理插件

/**
 * @file        全局错误处理插件
 * @author      开发者姓名
 * @date        2024-01-01
 * @description 统一处理应用中的错误,提供标准化的错误响应格式
 */

import { Elysia } from 'elysia';
import { logger } from '@/utils/logger';

/**
 * 错误响应接口
 */
interface ErrorResponse {
    code: number;
    message: string;
    data: null;
}

/**
 * 全局错误处理插件
 */
export const errorHandlerPlugin = new Elysia({ name: 'errorHandler' })
    .onError(({ code, error, set }) => {
        // 记录错误日志
        logger.error('API Error:', {
            code,
            error: error.message,
            stack: error.stack,
            timestamp: new Date().toISOString()
        });

        const response: ErrorResponse = {
            code: 500,
            message: '服务器内部错误',
            data: null
        };

        switch (code) {
            case 'VALIDATION':
                set.status = 400;
                response.code = 400;
                response.message = '请求参数验证失败:' + error.message;
                break;

            case 'NOT_FOUND':
                set.status = 404;
                response.code = 404;
                response.message = '请求的资源不存在';
                break;

            case 'PARSE':
                set.status = 400;
                response.code = 400;
                response.message = '请求数据格式错误';
                break;

            case 'UNAUTHORIZED':
                set.status = 401;
                response.code = 401;
                response.message = '未授权访问';
                break;

            case 'FORBIDDEN':
                set.status = 403;
                response.code = 403;
                response.message = '权限不足';
                break;

            default:
                set.status = 500;
                response.code = 500;
                response.message = '服务器内部错误';
                break;
        }

        return response;
    });

/**
 * 业务错误类
 * @description 用于抛出业务逻辑错误
 */
export class BusinessError extends Error {
    public code: number;
    
    constructor(code: number, message: string) {
        super(message);
        this.code = code;
        this.name = 'BusinessError';
    }
}

/**
 * 抛出业务错误的辅助函数
 * @param code 错误码
 * @param message 错误消息
 */
export function throwBusinessError(code: number, message: string): never {
    throw new BusinessError(code, message);
}

中间件与插件规范 (Middleware & Plugin Standards)

JWT 认证插件

/**
 * @file        JWT 认证插件
 * @author      开发者姓名
 * @date        2024-01-01
 * @description JWT 令牌处理插件,提供 token 生成和验证功能
 */

import { Elysia } from 'elysia';
import { jwt } from '@elysiajs/jwt';
import { jwtConfig } from '@/config/jwt.config';

/**
 * JWT 认证插件
 */
export const jwtPlugin = new Elysia({ name: 'jwt' })
    .use(jwt({
        name: 'jwt',
        secret: jwtConfig.secret,
        exp: jwtConfig.expiresIn
    }))
    .derive(({ jwt, headers }) => ({
        /**
         * 获取当前用户信息
         * @returns 用户信息或 null
         */
        getCurrentUser: async () => {
            try {
                const authorization = headers.authorization;
                if (!authorization?.startsWith('Bearer ')) {
                    return null;
                }

                const token = authorization.slice(7);
                const payload = await jwt.verify(token);
                return payload;
            } catch {
                return null;
            }
        }
    }))
    .macro(({ onBeforeHandle }) => ({
        /**
         * 权限验证宏
         * @param options 验证选项
         */
        auth(options: { required?: boolean } = {}) {
            const { required = true } = options;
            
            onBeforeHandle(async ({ getCurrentUser, status }) => {
                const user = await getCurrentUser();
                
                if (required && !user) {
                    return status(401, {
                        code: 401,
                        message: '请先登录',
                        data: null
                    });
                }
                
                return { user };
            });
        }
    }));

请求日志插件

/**
 * @file        请求日志插件
 * @author      开发者姓名
 * @date        2024-01-01
 * @description 记录 API 请求和响应的详细信息
 */

import { Elysia } from 'elysia';
import { logger } from '@/utils/logger';

/**
 * 请求日志插件
 */
export const requestLoggerPlugin = new Elysia({ name: 'requestLogger' })
    .onRequest(({ request, path }) => {
        const startTime = Date.now();
        
        logger.info('API Request', {
            method: request.method,
            url: request.url,
            path,
            userAgent: request.headers.get('user-agent'),
            ip: request.headers.get('x-forwarded-for') || 'unknown',
            timestamp: new Date().toISOString(),
            startTime
        });
        
        // 将开始时间存储在请求上下文中
        return { startTime };
    })
    .onAfterHandle(({ request, response, path, startTime }) => {
        const duration = Date.now() - (startTime || Date.now());
        
        logger.info('API Response', {
            method: request.method,
            path,
            status: response.status,
            duration: `${duration}ms`,
            timestamp: new Date().toISOString()
        });
    });

最佳实践示例 (Best Practice Examples)

完整的 CRUD 接口示例

/**
 * @file        用户管理完整示例
 * @author      开发者姓名
 * @date        2024-01-01
 * @description 展示完整的 CRUD 接口实现,包含分页、搜索、排序等功能
 */

import { Elysia, t } from 'elysia';
import { jwtPlugin } from '@/plugins/jwt.plugins';
import { errorHandlerPlugin } from '@/plugins/errorHandler.plugins';
import { UserService } from '@/services/user/user.service';

// 参数校验
const createUserSchema = t.Object({
    username: t.String({ minLength: 2, maxLength: 16 }),
    email: t.String({ format: 'email' }),
    password: t.String({ minLength: 6, maxLength: 32 }),
    role: t.Optional(t.Union([t.Literal('admin'), t.Literal('user')], { default: 'user' }))
});

const updateUserSchema = t.Object({
    username: t.Optional(t.String({ minLength: 2, maxLength: 16 })),
    email: t.Optional(t.String({ format: 'email' })),
    role: t.Optional(t.Union([t.Literal('admin'), t.Literal('user')]))
});

const userParamsSchema = t.Object({
    id: t.String({ minLength: 1 })
});

const userQuerySchema = t.Object({
    page: t.Optional(t.Number({ minimum: 1, default: 1 })),
    pageSize: t.Optional(t.Number({ minimum: 1, maximum: 100, default: 10 })),
    keyword: t.Optional(t.String({ maxLength: 50 })),
    role: t.Optional(t.Union([t.Literal('admin'), t.Literal('user')])),
    sortBy: t.Optional(t.Union([t.Literal('createdAt'), t.Literal('username')], { default: 'createdAt' })),
    sortOrder: t.Optional(t.Union([t.Literal('asc'), t.Literal('desc')], { default: 'desc' }))
});

// 响应格式
const userItemSchema = t.Object({
    id: t.String(),
    username: t.String(),
    email: t.String(),
    role: t.String(),
    isActive: t.Boolean(),
    createdAt: t.String({ format: 'date-time' }),
    updatedAt: t.String({ format: 'date-time' })
});

const successResponse = (data: any) => t.Object({
    code: t.Literal(0),
    message: t.String(),
    data
});

const errorResponse = (code: number) => t.Object({
    code: t.Literal(code),
    message: t.String(),
    data: t.Null()
});

/**
 * 用户管理控制器
 */
export const userController = new Elysia({ prefix: '/api/users' })
    .use(jwtPlugin)
    .use(errorHandlerPlugin)
    
    // 获取用户列表(支持分页、搜索、排序)
    .get('/', 
        async ({ query, getCurrentUser }) => {
            const currentUser = await getCurrentUser();
            return await UserService.getUserList(query, currentUser);
        },
        {
            query: userQuerySchema,
            detail: {
                tags: ['用户管理'],
                summary: '获取用户列表',
                description: '获取用户列表,支持分页、搜索和排序功能'
            },
            response: {
                200: successResponse(t.Object({
                    list: t.Array(userItemSchema),
                    pagination: t.Object({
                        page: t.Number(),
                        pageSize: t.Number(),
                        total: t.Number(),
                        totalPages: t.Number()
                    })
                })),
                401: errorResponse(401)
            },
            auth: { required: true }
        }
    )
    
    // 获取单个用户
    .get('/:id',
        async ({ params, getCurrentUser }) => {
            const currentUser = await getCurrentUser();
            return await UserService.getUserById(params.id, currentUser);
        },
        {
            params: userParamsSchema,
            detail: {
                tags: ['用户管理'],
                summary: '获取用户详情',
                description: '根据用户ID获取用户详细信息'
            },
            response: {
                200: successResponse(userItemSchema),
                404: errorResponse(404),
                401: errorResponse(401)
            },
            auth: { required: true }
        }
    )
    
    // 创建用户
    .post('/',
        async ({ body, getCurrentUser }) => {
            const currentUser = await getCurrentUser();
            return await UserService.createUser(body, currentUser);
        },
        {
            body: createUserSchema,
            detail: {
                tags: ['用户管理'],
                summary: '创建用户',
                description: '创建新用户账户'
            },
            response: {
                200: successResponse(userItemSchema),
                400: errorResponse(400),
                401: errorResponse(401),
                403: errorResponse(403)
            },
            auth: { required: true }
        }
    )
    
    // 更新用户
    .put('/:id',
        async ({ params, body, getCurrentUser }) => {
            const currentUser = await getCurrentUser();
            return await UserService.updateUser(params.id, body, currentUser);
        },
        {
            params: userParamsSchema,
            body: updateUserSchema,
            detail: {
                tags: ['用户管理'],
                summary: '更新用户',
                description: '更新用户信息'
            },
            response: {
                200: successResponse(userItemSchema),
                400: errorResponse(400),
                404: errorResponse(404),
                401: errorResponse(401),
                403: errorResponse(403)
            },
            auth: { required: true }
        }
    )
    
    // 删除用户
    .delete('/:id',
        async ({ params, getCurrentUser }) => {
            const currentUser = await getCurrentUser();
            return await UserService.deleteUser(params.id, currentUser);
        },
        {
            params: userParamsSchema,
            detail: {
                tags: ['用户管理'],
                summary: '删除用户',
                description: '删除指定用户'
            },
            response: {
                200: successResponse(t.Object({
                    deleted: t.Boolean()
                })),
                404: errorResponse(404),
                401: errorResponse(401),
                403: errorResponse(403)
            },
            auth: { required: true }
        }
    );

请严格遵守以上规范,确保 Elysia 接口的一致性、安全性和可维护性。