Skill: zuoanco/fullstack-dev-engineer (version 0.0.1)

--- name: fullstack-dev-engineer description: 提供全栈开发架构设计、技术栈选型、前端开发、后端开发、运维部署指导；当用户需要架构设计、技术选型、前端开发、后端开发、运维部署或最佳实践咨询时使用 --- # 全栈全能开发工程师 ## 任务目标 - 本 Skill 用于：协助用户完成从架构设计、前端开发、后端开发到运维部署的全栈开发任务 - 能力包含：系统架构设计、技术栈选型、前端开发、后端开发、项目规划、代码生成、运维部署、最佳实践指导 - 触发条件：用户需要设计系统架构、选择技术方案、开发前端/后端项目、部署应用、生成代码或咨询开发最佳实践 ## 前置准备 本 Skill 无需额外依赖，所有能力通过智能体的语言理解和代码生成能力实现。 ## 操作步骤 ### 1. 需求分析 - 理解用户的业务需求和功能需求 - 明确系统的非功能性需求（性能、可扩展性、安全性、维护性） - 识别技术约束和环境限制（部署环境、团队技能、预算） ### 2. 架构设计 - 参考架构模式：查阅 [architecture-patterns.md](references/architecture-patterns.md) 选择合适的架构模式 - 设计系统模块划分和组件关系 - 明确数据流和接口设计 - 生成架构设计文档和架构图描述 ### 3. 技术栈选型 - 参考技术对比：查阅 [tech-stack-comparison.md](references/tech-stack-comparison.md) 进行技术栈对比 - 根据项目需求选择合适的前端、后端、数据库、中间件 - 考虑技术成熟度、社区活跃度、学习曲线和团队匹配度 - 提供技术选型说明和备选方案 ### 4. 项目规划 - 制定开发计划和里程碑 - 设计项目目录结构 - 规划开发环境和部署流程 - 定义代码规范和协作流程 ### 5. 代码实现 - 参考最佳实践：查阅 [best-practices.md](references/best-practices.md) 遵循开发最佳实践 - 参考代码规范：查阅 [code-standards.md](references/code-standards.md) 保持代码质量 - 生成模块代码和核心功能实现 - 编写单元测试和集成测试 - 生成API文档和使用说明 ### 6. 前端开发 - 参考前端指南：查阅 [frontend-guide.md](references/frontend-guide.md) 了解前端开发实践 - 选择前端技术栈（React/Vue/Angular） - 设计组件架构和状态管理方案 - 实现响应式布局和交互功能 - 优化前端性能和用户体验 - 编写前端测试（单元测试、E2E测试） ### 7. 运维部署 - 参考运维指南：查阅 [devops-guide.md](references/devops-guide.md) 了解运维实践 - 配置容器化环境（Docker/Kubernetes） - 设计CI/CD流水线 - 配置监控和告警系统 - 设置日志收集和分析 - 制定备份和灾难恢复方案 - 实施安全加固措施 ### 8. 交付与优化 - 代码审查和优化建议 - 性能优化和安全加固 - 部署文档和运维指南 - 后续迭代和维护建议 ## 资源索引 - 架构模式参考：[architecture-patterns.md](references/architecture-patterns.md)（设计系统架构时参考） - 技术栈对比：[tech-stack-comparison.md](references/tech-stack-comparison.md)（选择技术方案时参考） - 前端开发指南：[frontend-guide.md](references/frontend-guide.md)（前端开发时参考） - 运维实践指南：[devops-guide.md](references/devops-guide.md)（运维部署时参考） - 最佳实践：[best-practices.md](references/best-practices.md)（开发过程中参考） - 代码规范：[code-standards.md](references/code-standards.md)（编写代码时参考） ## 注意事项 - 充分利用智能体的代码理解和生成能力，避免为简单任务编写脚本 - 优先推荐成熟、稳定、有良好社区支持的技术栈 - 在架构设计时平衡当前需求和未来扩展性 - 生成的代码应遵循清晰、可维护、可测试的原则 - 根据项目实际复杂度调整设计复杂度，避免过度设计 ## 使用示例 ### 示例1：设计电商平台架构 **功能说明**：为中小型电商平台设计整体架构方案 **执行方式**：智能体基于架构模式参考进行设计指导 **关键要点**： 1. 分析电商核心功能：商品管理、订单处理、支付系统、用户中心 2. 选择微服务架构，拆分为商品服务、订单服务、支付服务、用户服务 3. 技术栈：前端React + Node.js后端 + MySQL + Redis + Nginx 4. 设计服务间通信和API网关 ### 示例2：技术栈选型 **功能说明**：为实时协作应用选择技术栈 **执行方式**：智能体基于技术对比提供选型建议 **关键要点**： 1. 核心需求：实时性、多用户并发、数据一致性 2. 前端：Vue.js + WebSocket（实时通信） 3. 后端：Node.js + Socket.io（高并发处理） 4. 数据库：PostgreSQL + Redis（缓存） 5. 备选方案：Go + gRPC（性能优化） ### 示例3：生成后端API代码 **功能说明**：生成用户认证模块的RESTful API代码 **执行方式**：智能体基于代码规范直接生成代码 **关键要点**： 1. 定义API接口：注册、登录、登出、刷新Token 2. 选择技术栈：Node.js + Express + JWT + bcrypt 3. 生成路由、控制器、中间件代码 4. 添加输入验证和错误处理 5. 编写单元测试用例 ### 示例4：前端React项目开发 **功能说明**：开发React前端项目，实现用户管理界面 **执行方式**：智能体基于前端指南生成前端代码 **关键要点**： 1. 选择技术栈：React + TypeScript + Vite + Tailwind CSS 2. 设计组件架构：页面组件、业务组件、通用组件 3. 实现状态管理：使用Zustand或Redux Toolkit 4. 实现路由和导航 5. 添加性能优化：代码分割、懒加载、缓存策略 ### 示例5：Kubernetes部署配置 **功能说明**：为应用配置Kubernetes部署环境 **执行方式**：智能体基于运维指南生成K8s配置 **关键要点**： 1. 创建Deployment配置，设置资源限制和健康检查 2. 配置Service和Ingress，实现服务暴露和负载均衡 3. 配置ConfigMap和Secret，管理配置和敏感信息 4. 设置Horizontal Pod Autoscaler，实现自动扩缩容 5. 配置NetworkPolicy，实现网络安全隔离

path: references/architecture-patterns.md
content: # 架构模式参考

## 目录
- [单体架构](#单体架构)
- [微服务架构](#微服务架构)
- [分层架构](#分层架构)
- [事件驱动架构](#事件驱动架构)
- [Serverless架构](#serverless架构)
- [领域驱动设计](#领域驱动设计)
- [架构模式选择指南](#架构模式选择指南)

## 单体架构

### 适用场景
- 项目规模较小（团队<10人）
- 业务逻辑相对简单
- 快速开发和原型验证
- 初创项目或MVP阶段

### 架构特点
- 所有功能模块部署在同一应用中
- 共享同一数据库
- 部署简单，运维成本低
- 代码耦合度较高，扩展性受限

### 技术栈示例
- 前端：React/Vue/Angular
- 后端：Node.js/Express 或 Java/Spring Boot 或 Python/Django
- 数据库：MySQL/PostgreSQL
- 部署：Docker + Nginx

### 优缺点
**优点**：
- 开发和部署简单快速
- 调试方便，易于追踪问题
- 适合小团队快速迭代

**缺点**：
- 单一故障点
- 技术栈受限
- 难以独立扩展
- 代码维护成本随规模增长

## 微服务架构

### 适用场景
- 大型复杂系统（团队>20人）
- 需要独立部署和扩展不同模块
- 多团队协作开发
- 高并发和高可用要求

### 架构特点
- 服务拆分为独立部署的小服务
- 每个服务专注单一业务领域
- 服务间通过API或消息队列通信
- 支持不同技术栈

### 技术栈示例
- 服务通信：RESTful API / gRPC
- 服务发现：Consul / Eureka
- API网关：Kong / Nginx / Spring Cloud Gateway
- 消息队列：RabbitMQ / Kafka
- 服务追踪：Jaeger / Zipkin
- 配置中心：Apollo / Consul

### 优缺点
**优点**：
- 独立部署和扩展
- 技术栈灵活
- 故障隔离
- 适合团队协作

**缺点**：
- 系统复杂度高
- 分布式事务处理困难
- 运维和监控成本高
- 服务间调用延迟

## 分层架构

### 适用场景
- 中等规模应用
- 业务逻辑清晰可分层
- 需要良好的代码组织结构
- 团队规模5-15人

### 架构特点
- 按功能职责分层：表现层、业务层、数据层
- 层与层之间通过接口通信
- 每层独立变化，降低耦合
- 易于测试和维护

### 典型分层
```
├── Presentation Layer (表现层)
│   ├── Web/Mobile界面
│   └── API接口
├── Business Layer (业务层)
│   ├── 业务逻辑
│   └── 领域服务
├── Data Access Layer (数据访问层)
│   ├── ORM/DAO
│   └── 数据库操作
└── Infrastructure Layer (基础设施层)
    ├── 日志、缓存
    └── 外部服务集成
```

### 技术栈示例
- 后端框架：Spring Boot / Django / NestJS
- ORM：Hibernate / SQLAlchemy / TypeORM
- 数据库：MySQL / PostgreSQL / MongoDB

### 优缺点
**优点**：
- 结构清晰，职责明确
- 易于测试和维护
- 适合中大型项目

**缺点**：
- 层次过多可能影响性能
- 开发复杂度适中
- 需要良好的接口设计

## 事件驱动架构

### 适用场景
- 高并发异步处理场景
- 实时数据处理
- 解耦复杂业务流程
- 微服务间的异步通信

### 架构特点
- 基于事件的松耦合设计
- 通过事件总线或消息队列通信
- 支持异步处理和最终一致性
- 适合复杂业务流程编排

### 技术栈示例
- 消息中间件：Kafka / RabbitMQ / RocketMQ
- 事件流处理：Apache Flink / Spark Streaming
- CQRS模式：Command / Query分离
- Event Sourcing：事件溯源

### 优缺点
**优点**：
- 高并发处理能力强
- 松耦合，易于扩展
- 适合异步处理

**缺点**：
- 最终一致性带来的复杂性
- 调试和监控困难
- 消息重复和顺序问题

## Serverless架构

### 适用场景
- 事件驱动型应用
- 间歇性或突发性负载
- 快速开发和迭代
- 降低运维成本

### 架构特点
- 无需管理服务器
- 按使用量计费
- 自动扩展和收缩
- 函数即服务

### 技术栈示例
- 函数计算：AWS Lambda / Azure Functions / 阿里云函数计算
- API网关：AWS API Gateway / API Gateway
- 数据库：Serverless DB / DynamoDB
- 对象存储：S3 / OSS

### 优缺点
**优点**：
- 无需运维
- 自动扩展
- 成本效益高

**缺点**：
- 冷启动延迟
- 执行时间限制
- 调试困难

## 领域驱动设计（DDD）

### 适用场景
- 复杂业务领域
- 需要深度业务建模
- 大型项目长期维护
- 多领域专家协作

### 核心概念
- 领域模型：映射业务概念
- 聚合根：一致性边界
- 值对象：不可变对象
- 领域服务：业务逻辑封装
- 仓储模式：数据访问抽象

### 分层结构
```
├── User Interface Layer (用户界面层)
├── Application Layer (应用层)
├── Domain Layer (领域层)
│   ├── Entities (实体)
│   ├── Value Objects (值对象)
│   ├── Aggregates (聚合)
│   └── Domain Services (领域服务)
└── Infrastructure Layer (基础设施层)
```

### 优缺点
**优点**：
- 业务逻辑清晰
- 易于维护和扩展
- 团队沟通效率高

**缺点**：
- 学习曲线陡峭
- 初期设计成本高
- 需要深入理解业务

## 架构模式选择指南

### 决策树

```
项目规模
  │
  ├─ 小型项目（团队<5人）
  │   └─ 单体架构
  │
  ├─ 中型项目（团队5-15人）
  │   ├─ 业务简单 → 单体架构
  │   └─ 业务复杂 → 分层架构 / DDD
  │
  └─ 大型项目（团队>15人）
      ├─ 高并发需求 → 微服务 / 事件驱动
      ├─ 快速迭代 → Serverless
      └─ 稳定业务 → 微服务 + 分层架构
```

### 选择建议

1. **初创项目**：优先选择单体架构，快速验证和迭代
2. **成长期项目**：根据业务复杂度选择分层架构或DDD
3. **成熟期项目**：考虑微服务架构，支持独立扩展和团队协作
4. **特殊场景**：
   - 实时数据处理 → 事件驱动架构
   - 间歇性负载 → Serverless架构
   - 复杂业务逻辑 → DDD

### 架构演进路径
```
单体架构 → 分层架构 → 微服务架构 → 事件驱动架构
     ↓
  Serverless（云原生方向）
```

### 技术债务管理
- 定期评估架构是否满足业务需求
- 识别架构瓶颈和性能热点
- 规划架构重构和演进路径
- 保持架构的简单性和可维护性


path: references/best-practices.md
content: # 开发最佳实践

## 目录
- [代码组织](#代码组织)
- [错误处理](#错误处理)
- [安全性实践](#安全性实践)
- [性能优化](#性能优化)
- [测试策略](#测试策略)
- [API设计](#api设计)
- [数据库最佳实践](#数据库最佳实践)
- [日志和监控](#日志和监控)

## 代码组织

### 项目目录结构

#### 前端项目（React）
```
src/
├── assets/           # 静态资源
├── components/       # 可复用组件
│   ├── common/      # 通用组件
│   └── business/    # 业务组件
├── pages/           # 页面组件
├── hooks/           # 自定义Hooks
├── services/        # API服务
├── stores/          # 状态管理
├── utils/           # 工具函数
├── types/           # TypeScript类型定义
├── constants/       # 常量定义
├── config/          # 配置文件
└── styles/          # 全局样式
```

#### 后端项目（Node.js/NestJS）
```
src/
├── modules/         # 业务模块
│   ├── user/
│   │   ├── controllers/
│   │   ├── services/
│   │   ├── dto/
│   │   └── entities/
├── common/          # 通用模块
│   ├── filters/    # 异常过滤器
│   ├── guards/     # 守卫
│   ├── interceptors/# 拦截器
│   ├── decorators/ # 装饰器
│   └── utils/      # 工具函数
├── config/          # 配置文件
├── database/        # 数据库配置
└── main.ts
```

#### 后端项目（Java/Spring Boot）
```
src/
├── main/
│   ├── java/
│   │   └── com/example/
│   │       ├── controller/
│   │       ├── service/
│   │       ├── repository/
│   │       ├── entity/
│   │       ├── dto/
│   │       ├── config/
│   │       └── exception/
│   └── resources/
│       ├── application.yml
│       └── mapper/
└── test/
```

### 命名规范

#### 通用原则
- **文件名**：小写字母+连字符（kebab-case），如 `user-service.ts`
- **类名**：帕斯卡命名（PascalCase），如 `UserService`
- **函数/变量**：驼峰命名（camelCase），如 `getUserInfo`
- **常量**：大写字母+下划线，如 `MAX_RETRY_COUNT`
- **私有成员**：下划线前缀，如 `_privateMethod`

#### 目录命名
- 统一使用小写字母和连字符
- 避免使用缩写，保持语义清晰
- 例如：`user-management` 而非 `usr-mgmt`

### 代码注释规范

#### 函数注释（JSDoc/TSDoc）
```javascript
/**
 * 根据用户ID获取用户信息
 * @param {string} userId - 用户ID
 * @param {boolean} includeProfile - 是否包含详细资料
 * @returns {Promise<User>} 用户信息对象
 * @throws {NotFoundError} 用户不存在时抛出
 */
async getUserById(userId: string, includeProfile = false): Promise<User> {
  // 实现代码
}
```

#### 复杂逻辑注释
```javascript
// 使用双因子认证进行安全验证
// 流程：
// 1. 验证密码正确性
// 2. 检查是否开启2FA
// 3. 如果开启，验证OTP码
if (is2FAEnabled) {
  const isValidOTP = await verifyOTP(user.otpSecret, otpCode);
  if (!isValidOTP) {
    throw new UnauthorizedError('Invalid OTP code');
  }
}
```

## 错误处理

### 统一错误处理

#### 后端错误分类
```typescript
// 错误类型定义
export class AppError extends Error {
  constructor(
    public statusCode: number,
    public message: string,
    public code?: string
  ) {
    super(message);
    this.name = this.constructor.name;
  }
}

export class NotFoundError extends AppError {
  constructor(message: string = 'Resource not found') {
    super(404, message, 'NOT_FOUND');
  }
}

export class UnauthorizedError extends AppError {
  constructor(message: string = 'Unauthorized') {
    super(401, message, 'UNAUTHORIZED');
  }
}

export class ValidationError extends AppError {
  constructor(message: string = 'Validation failed') {
    super(400, message, 'VALIDATION_ERROR');
  }
}
```

#### 全局异常处理器
```typescript
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    let status = 500;
    let message = 'Internal server error';
    let code = 'INTERNAL_ERROR';

    if (exception instanceof AppError) {
      status = exception.statusCode;
      message = exception.message;
      code = exception.code;
    }

    response.status(status).json({
      success: false,
      error: {
        code,
        message,
        timestamp: new Date().toISOString(),
      },
    });
  }
}
```

### 错误日志记录
```typescript
// 记录错误上下文
logger.error('Failed to process payment', {
  userId,
  orderId,
  error: exception.message,
  stack: exception.stack,
  timestamp: new Date(),
});
```

## 安全性实践

### 认证授权

#### JWT认证
```typescript
// 生成JWT Token
function generateToken(user: User): string {
  const payload = {
    userId: user.id,
    email: user.email,
    role: user.role,
  };

  return jwt.sign(payload, JWT_SECRET, {
    expiresIn: '7d',
  });
}

// 验证JWT Token
function verifyToken([REDACTED_SECRET]): JwtPayload {
  try {
    return jwt.verify(token, JWT_SECRET) as JwtPayload;
  } catch (error) {
    throw new UnauthorizedError('Invalid token');
  }
}
```

#### RBAC权限控制
```typescript
// 权限装饰器
export const RequirePermissions = (...permissions: string[]) => {
  return applyDecorators(
    UseGuards(JwtAuthGuard, PermissionsGuard),
    SetMetadata('permissions', permissions)
  );
};

// 使用示例
@Post('admin/users')
@RequirePermissions('user:create')
async createUser(@Body() dto: CreateUserDto) {
  // 只有拥有 user:create 权限的用户可以访问
}
```

### 数据验证

#### 输入验证
```typescript
import { z } from 'zod';

// 定义验证schema
const CreateUserSchema = z.object({
  email: z.string().email('Invalid email format'),
  [REDACTED_SECRET])
    .min(8, 'Password must be at least 8 characters')
    .regex(/[A-Z]/, 'Password must contain uppercase letter')
    .regex(/[0-9]/, 'Password must contain number'),
  name: z.string().min(2, 'Name must be at least 2 characters'),
});

// 使用验证
function validateUserData(data: unknown) {
  return CreateUserSchema.parse(data);
}
```

#### SQL注入防护
```typescript
// 使用参数化查询
async getUserByEmail(email: string) {
  const query = 'SELECT * FROM users WHERE email = $1';
  const result = await this.db.query(query, [email]);
  return result.rows[0];
}

// 使用ORM
async getUserByEmail(email: string) {
  return this.userRepository.findOne({ where: { email } });
}
```

### 敏感数据处理

#### 密码加密
```typescript
import bcrypt from 'bcrypt';

// 加密密码
async function hashPassword([REDACTED_SECRET]): Promise<string> {
  const saltRounds = 10;
  return bcrypt.hash(password, saltRounds);
}

// 验证密码
async function verifyPassword(
  [REDACTED_SECRET],
  hashedPassword: string
): Promise<boolean> {
  return bcrypt.compare(password, hashedPassword);
}
```

#### 敏感数据脱敏
```typescript
// 日志脱敏
function sanitizeForLogging(data: any): any {
  const sensitiveFields = ['password', 'token', 'secret', 'apiKey'];
  const sanitized = { ...data };

  sensitiveFields.forEach(field => {
    if (sanitized[field]) {
      sanitized[field] = '***REDACTED***';
    }
  });

  return sanitized;
}
```

## 性能优化

### 数据库优化

#### 索引优化
```sql
-- 为常用查询字段添加索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_id ON orders(user_id);

-- 复合索引（注意顺序）
CREATE INDEX idx_orders_status_created ON orders(status, created_at);
```

#### 查询优化
```typescript
// 避免N+1查询
async getUsersWithOrders() {
  // 错误方式：N+1查询
  const users = await this.userRepository.find();
  for (const user of users) {
    user.orders = await this.orderRepository.find({ user: user.id });
  }

  // 正确方式：使用JOIN
  return this.userRepository
    .createQueryBuilder('user')
    .leftJoinAndSelect('user.orders', 'orders')
    .getMany();
}
```

#### 分页查询
```typescript
async getUsers(page: number, pageSize: number) {
  const skip = (page - 1) * pageSize;

  return this.userRepository.find({
    skip,
    take: pageSize,
    order: { createdAt: 'DESC' },
  });
}
```

### 缓存策略

#### Redis缓存
```typescript
async getUserById(userId: string): Promise<User> {
  const cacheKey = `user:${userId}`;

  // 尝试从缓存获取
  const cached = await this.redis.get(cacheKey);
  if (cached) {
    return JSON.parse(cached);
  }

  // 从数据库获取
  const user = await this.userRepository.findOne({ where: { id: userId } });

  // 写入缓存（5分钟过期）
  if (user) {
    await this.redis.setex(cacheKey, 300, JSON.stringify(user));
  }

  return user;
}
```

#### 缓存失效策略
```typescript
async updateUser(userId: string, data: UpdateUserDto): Promise<User> {
  // 更新数据库
  const user = await this.userRepository.save({ id: userId, ...data });

  // 删除缓存
  const cacheKey = `user:${userId}`;
  await this.redis.del(cacheKey);

  return user;
}
```

### 前端性能优化

#### 代码分割
```typescript
// 路由懒加载
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}
```

#### 图片优化
```typescript
// 使用懒加载
import { LazyLoadImage } from 'react-lazy-load-image-component';

<LazyLoadImage
  src={imageSrc}
  alt="Description"
  effect="blur"
  width={300}
  height={200}
/>
```

## 测试策略

### 单元测试

#### Jest测试示例
```typescript
describe('UserService', () => {
  let service: UserService;
  let mockRepository: jest.Mocked<UserRepository>;

  beforeEach(() => {
    mockRepository = createMockRepository();
    service = new UserService(mockRepository);
  });

  it('should return user when exists', async () => {
    const mockUser = { id: '1', name: 'John' };
    mockRepository.findOne.mockResolvedValue(mockUser);

    const result = await service.getUserById('1');

    expect(result).toEqual(mockUser);
    expect(mockRepository.findOne).toHaveBeenCalledWith({ where: { id: '1' } });
  });

  it('should throw NotFoundError when user not exists', async () => {
    mockRepository.findOne.mockResolvedValue(null);

    await expect(service.getUserById('999')).rejects.toThrow(NotFoundError);
  });
});
```

### 集成测试

#### API集成测试
```typescript
describe('UserController (e2e)', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleFixture = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    app = moduleFixture.createNestApplication();
    await app.init();
  });

  it('/users (POST)', () => {
    return request(app.getHttpServer())
      .post('/users')
      .send({ name: 'John', email: '[REDACTED_SECRET]' })
      .expect(201)
      .expect((res) => {
        expect(res.body).toHaveProperty('id');
        expect(res.body.name).toBe('John');
      });
  });
});
```

### 测试覆盖率

- 目标覆盖率：80%以上
- 核心业务逻辑：90%以上
- 工具函数：95%以上

## API设计

### RESTful API规范

#### 资源命名
```
GET    /users          # 获取用户列表
GET    /users/:id      # 获取单个用户
POST   /users          # 创建用户
PUT    /users/:id      # 完整更新用户
PATCH  /users/:id      # 部分更新用户
DELETE /users/:id      # 删除用户
```

#### 响应格式
```json
// 成功响应
{
  "success": true,
  "data": {
    "id": "123",
    "name": "John",
    "email": "[REDACTED_SECRET]"
  }
}

// 错误响应
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Email is required",
    "details": [
      {
        "field": "email",
        "message": "Email is required"
      }
    ]
  }
}
```

### API版本控制
```typescript
// URL版本控制
@Controller('api/v1/users')
export class UserControllerV1 {
  // V1实现
}

@Controller('api/v2/users')
export class UserControllerV2 {
  // V2实现
}
```

## 数据库最佳实践

### 数据库设计原则

#### 表设计
```sql
-- 使用蛇形命名
CREATE TABLE user_profiles (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  first_name VARCHAR(50) NOT NULL,
  last_name VARCHAR(50) NOT NULL,
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- 添加索引
CREATE INDEX idx_user_profiles_user_id ON user_profiles(user_id);
CREATE INDEX idx_user_profiles_created_at ON user_profiles(created_at DESC);
```

#### 软删除
```sql
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP;

-- 查询时排除已删除
SELECT * FROM users WHERE deleted_at IS NULL;
```

### 数据库迁移

#### 版本控制
```typescript
// 迁移文件示例
export async function up(queryRunner: QueryRunner): Promise<void> {
  await queryRunner.query(`
    CREATE TABLE users (
      id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
      email VARCHAR(255) UNIQUE NOT NULL,
      password VARCHAR(255) NOT NULL,
      created_at TIMESTAMP NOT NULL DEFAULT NOW()
    )
  `);
}

export async function down(queryRunner: QueryRunner): Promise<void> {
  await queryRunner.query(`DROP TABLE users`);
}
```

## 日志和监控

### 日志规范

#### 日志级别
```typescript
logger.debug('Debug information'); // 调试信息
logger.info('User logged in', { userId }); // 一般信息
logger.warn('API rate limit approaching'); // 警告
logger.error('Database connection failed', { error }); // 错误
```

#### 结构化日志
```typescript
logger.info('Order processed', {
  orderId,
  userId,
  amount,
  paymentMethod,
  processingTime: Date.now() - startTime,
});
```

### 监控指标

#### 关键指标
- **性能指标**：响应时间、吞吐量、错误率
- **业务指标**：DAU、转化率、订单量
- **系统指标**：CPU使用率、内存使用率、磁盘IO

#### 健康检查
```typescript
@Get('health')
healthCheck() {
  return {
    status: 'ok',
    timestamp: new Date(),
    services: {
      database: this.checkDatabase(),
      redis: this.checkRedis(),
      externalApi: this.checkExternalApi(),
    },
  };
}
```

### 告警规则
```yaml
# Prometheus告警规则示例
groups:
  - name: api_alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m
        annotations:
          summary: "High error rate detected"

      - alert: SlowResponseTime
        expr: histogram_quantile(0.95, rate(http_request_duration_seconds[5m])) > 1
        for: 10m
        annotations:
          summary: "95th percentile response time exceeds 1s"
```


path: references/code-standards.md
content: # 代码规范指南

## 目录
- [JavaScript/TypeScript规范](#javascripttypescript规范)
- [Python代码规范](#python代码规范)
- [Java代码规范](#java代码规范)
- [Go代码规范](#go代码规范)
- [SQL代码规范](#sql代码规范)
- [Git提交规范](#git提交规范)

## JavaScript/TypeScript规范

### 命名规范

#### 变量和函数
```typescript
// 变量：驼峰命名
let userName = 'John';
let isLoggedIn = true;

// 函数：驼峰命名，动词开头
function getUserInfo() {}
function validateEmail() {}
function fetchData() {}

// 常量：大写字母+下划线
const MAX_RETRY_COUNT = 3;
const API_BASE_URL = 'https://api.example.com';

// 类：帕斯卡命名
class UserService {}
class HttpClient {}

// 私有成员：下划线前缀
class UserService {
  private _cache: Map<string, any>;

  private _formatUser(user: User) {
    // ...
  }
}
```

#### 文件命名
```typescript
// 组件文件：PascalCase
// UserProfile.ts
// ButtonGroup.ts

// 工具文件：camelCase
// apiClient.ts
// dateUtils.ts

// 类型定义文件：.types.ts
// user.types.ts
// api.types.ts
```

### 代码格式

#### 使用Prettier
```json
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 80,
  "arrowParens": "avoid"
}
```

#### 使用ESLint
```javascript
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react/recommended',
    'prettier'
  ],
  rules: {
    'no-console': 'warn',
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/explicit-function-return-type': 'off'
  }
};
```

### TypeScript类型规范

#### 类型定义
```typescript
// 接口：用于对象结构
interface User {
  id: string;
  name: string;
  email: string;
  createdAt: Date;
}

// 类型别名：用于联合类型、交叉类型
type UserRole = 'admin' | 'user' | 'guest';
type UserID = string;

// 泛型：可复用类型
interface ApiResponse<T> {
  success: boolean;
  data: T;
  error?: string;
}

// 使用示例
type UserResponse = ApiResponse<User>;
```

#### 类型导出
```typescript
// 统一导出类型
export type { User, UserRole, UserResponse };
export interface { UserService };
```

### 函数规范

#### 函数定义
```typescript
// 使用类型注解
function calculateSum(a: number, b: number): number {
  return a + b;
}

// 异步函数
async function fetchUserData(userId: string): Promise<User> {
  const response = await fetch(`/api/users/${userId}`);
  return response.json();
}

// 默认参数
function greet(name: string, greeting: string = 'Hello'): string {
  return `${greeting}, ${name}!`;
}

// 可选参数
function createUser(data: UserDto, options?: CreateUserOptions): User {
  // ...
}
```

#### 单一职责原则
```typescript
// ❌ 错误：函数做太多事情
function processUserData(data: any) {
  // 验证数据
  if (!data.email) throw new Error('Email required');
  // 转换数据
  const formatted = { ...data, email: data.email.toLowerCase() };
  // 保存到数据库
  await db.save(formatted);
  // 发送邮件
  await emailService.send(formatted.email);
  // 返回结果
  return formatted;
}

// ✅ 正确：拆分为多个函数
async function createUser(data: UserDataDto): Promise<User> {
  const validated = validateUserData(data);
  const formatted = formatUserData(validated);
  const user = await saveUser(formatted);
  await sendWelcomeEmail(user.email);
  return user;
}

function validateUserData(data: any): UserDataDto {
  if (!data.email) throw new Error('Email required');
  return data;
}

function formatUserData(data: UserDataDto): FormattedUserDto {
  return { ...data, email: data.email.toLowerCase() };
}

async function saveUser(data: FormattedUserDto): Promise<User> {
  return db.save(data);
}

async function sendWelcomeEmail(email: string): Promise<void> {
  await emailService.send(email);
}
```

### React组件规范

#### 组件定义
```typescript
import { useState, useEffect } from 'react';

interface Props {
  userId: string;
  onUpdate?: (user: User) => void;
}

export const UserProfile: React.FC<Props> = ({ userId, onUpdate }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    async function loadUser() {
      try {
        setLoading(true);
        const data = await fetchUser(userId);
        setUser(data);
      } catch (err) {
        setError('Failed to load user');
      } finally {
        setLoading(false);
      }
    }

    loadUser();
  }, [userId]);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  if (!user) return null;

  return (
    <div className="user-profile">
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
};
```

#### Hooks规范
```typescript
// 自定义Hook：以use开头
function useUserData(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchUser(userId).then(setUser).finally(() => setLoading(false));
  }, [userId]);

  return { user, loading };
}

// 使用Hook
function UserProfile({ userId }: { userId: string }) {
  const { user, loading } = useUserData(userId);

  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}
```

## Python代码规范

### 命名规范（PEP 8）

```python
# 变量和函数：蛇形命名
user_name = "John"
is_logged_in = True

def get_user_info():
    pass

def validate_email():
    pass

# 常量：大写字母+下划线
MAX_RETRY_COUNT = 3
API_BASE_URL = "https://api.example.com"

# 类：帕斯卡命名
class UserService:
    pass

class HttpClient:
    pass

# 私有成员：下划线前缀
class UserService:
    def __init__(self):
        self._cache = {}

    def _format_user(self, user):
        pass
```

### 类型注解

```python
from typing import List, Optional, Dict, Any
from dataclasses import dataclass
from datetime import datetime

# 使用类型注解
def get_user_by_id(user_id: str) -> Optional[User]:
    pass

async def fetch_user_data(user_id: str) -> User:
    pass

def calculate_sum(a: int, b: int) -> int:
    return a + b

# 类型别名
UserID = str
UserRole = "admin" | "user" | "guest"

# 使用dataclass
@dataclass
class User:
    id: UserID
    name: str
    email: str
    role: UserRole
    created_at: datetime
```

### 函数定义

```python
def process_data(
    data: Dict[str, Any],
    *,
    validate: bool = True,
    format_output: bool = False
) -> Dict[str, Any]:
    """
    处理用户数据

    Args:
        data: 输入数据
        validate: 是否验证数据
        format_output: 是否格式化输出

    Returns:
        处理后的数据

    Raises:
        ValueError: 数据验证失败
    """
    if validate:
        if not data.get("email"):
            raise ValueError("Email is required")

    result = {**data}

    if format_output:
        result["email"] = result["email"].lower()

    return result
```

### 异步编程

```python
import asyncio
from typing import List

async def fetch_user(user_id: str) -> User:
    """获取单个用户"""
    pass

async def fetch_multiple_users(user_ids: List[str]) -> List[User]:
    """并发获取多个用户"""
    tasks = [fetch_user(uid) for uid in user_ids]
    return await asyncio.gather(*tasks)
```

## Java代码规范

### 命名规范

```java
// 类：帕斯卡命名
public class UserService {
    // 常量：大写字母+下划线
    private static final int MAX_RETRY_COUNT = 3;
    private static final String API_BASE_URL = "https://api.example.com";

    // 变量：驼峰命名
    private String userName;
    private boolean isLoggedIn;

    // 方法：驼峰命名，动词开头
    public User getUserInfo() {
        return null;
    }

    public boolean validateEmail() {
        return false;
    }

    // 私有方法
    private void formatUserData(User user) {
    }
}
```

### 类定义

```java
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String name;
    private String email;
    private String role;
    private LocalDateTime createdAt;
}
```

### Service层

```java
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;
    private final EmailService emailService;

    @Transactional
    public User createUser(CreateUserDto dto) {
        // 验证
        validateUserDto(dto);

        // 创建用户
        User user = User.builder()
            .name(dto.getName())
            .email(dto.getEmail())
            .role("USER")
            .createdAt(LocalDateTime.now())
            .build();

        // 保存
        User savedUser = userRepository.save(user);

        // 发送欢迎邮件
        emailService.sendWelcomeEmail(savedUser.getEmail());

        return savedUser;
    }

    private void validateUserDto(CreateUserDto dto) {
        if (StringUtils.isEmpty(dto.getEmail())) {
            throw new ValidationException("Email is required");
        }
    }
}
```

### Controller层

```java
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/{id}")
    public ApiResponse<User> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return ApiResponse.success(user);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ApiResponse<User> createUser(@Valid @RequestBody CreateUserDto dto) {
        User user = userService.createUser(dto);
        return ApiResponse.success(user);
    }
}
```

## Go代码规范

### 命名规范

```go
// 包名：小写，简短
package user

// 导出标识符：帕斯卡命名
type UserService struct {
    cache map[string]any
}

// 未导出标识符：驼峰命名
type internalConfig struct {
    maxRetries int
}

// 接口：以-er结尾
type Reader interface {
    Read(p []byte) (n int, err error)
}

// 常量：驼峰命名
const (
    MaxRetryCount = 3
    APIBaseURL    = "https://api.example.com"
)

// 函数：驼峰命名
func GetUserInfo(id string) (*User, error) {
    return nil, nil
}
```

### 错误处理

```go
import (
    "errors"
    "fmt"
)

// 定义错误
var (
    ErrUserNotFound = errors.New("user not found")
    ErrInvalidInput = errors.New("invalid input")
)

// 函数返回错误
func GetUser(id string) (*User, error) {
    if id == "" {
        return nil, ErrInvalidInput
    }

    user, err := repository.FindByID(id)
    if err != nil {
        return nil, fmt.Errorf("failed to find user: %w", err)
    }

    return user, nil
}

// 使用错误
user, err := GetUser("123")
if err != nil {
    if errors.Is(err, ErrUserNotFound) {
        // 处理用户不存在
    }
    return err
}
```

### 结构体和方法

```go
type User struct {
    ID        string    `json:"id"`
    Name      string    `json:"name"`
    Email     string    `json:"email"`
    CreatedAt time.Time `json:"created_at"`
}

type UserService struct {
    repo *UserRepository
}

func NewUserService(repo *UserRepository) *UserService {
    return &UserService{repo: repo}
}

// 方法接收者：如果是小结构体，用值；大结构体，用指针
func (s *UserService) GetUser(id string) (*User, error) {
    return s.repo.FindByID(id)
}

func (u User) String() string {
    return fmt.Sprintf("User{id=%s, name=%s}", u.ID, u.Name)
}
```

## SQL代码规范

### 命名规范

```sql
-- 表名：蛇形命名，复数形式
CREATE TABLE users (
    id UUID PRIMARY KEY,
    user_name VARCHAR(100),
    created_at TIMESTAMP
);

CREATE TABLE user_profiles (
    id UUID PRIMARY KEY,
    user_id UUID REFERENCES users(id),
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);

-- 字段名：蛇形命名
-- user_name, created_at, updated_at

-- 索引名：idx_表名_字段名
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created_at ON users(created_at DESC);

-- 外键名：fk_表名_字段名
ALTER TABLE user_profiles
ADD CONSTRAINT fk_user_profiles_user_id
FOREIGN KEY (user_id) REFERENCES users(id);
```

### 查询规范

```sql
-- 使用格式化
SELECT
    u.id,
    u.user_name,
    u.email,
    COUNT(o.id) AS order_count
FROM
    users u
LEFT JOIN
    orders o ON u.id = o.user_id
WHERE
    u.created_at >= '2024-01-01'
    AND u.is_active = true
GROUP BY
    u.id, u.user_name, u.email
ORDER BY
    order_count DESC
LIMIT 10;
```

## Git提交规范

### Commit Message格式

```
<type>(<scope>): <subject>

<body>

<footer>
```

### Type类型

- `feat`: 新功能
- `fix`: 修复bug
- `docs`: 文档更新
- `style`: 代码格式调整（不影响功能）
- `refactor`: 重构
- `perf`: 性能优化
- `test`: 测试相关
- `chore`: 构建/工具链相关

### 示例

```bash
# 新功能
feat(user): add user registration feature

Implement user registration with email validation
and welcome email sending.

Closes #123

# 修复bug
fix(auth): resolve token expiration issue

The JWT token was not properly refreshed when expired.
Now it's handled correctly with proper error messages.

# 文档更新
docs(readme): update installation instructions

Added Docker deployment guide and updated requirements.

# 重构
refactor(user): extract validation logic to separate service

Move user validation logic from controller to dedicated
validation service for better separation of concerns.
```

### 分支规范

```bash
# 主分支
main/master
develop

# 功能分支
feature/user-authentication
feature/payment-gateway

# 修复分支
bugfix/login-error
hotfix/security-patch

# 发布分支
release/v1.0.0
```


path: references/devops-guide.md
content: # 运维实践指南

## 目录
- [容器化部署](#容器化部署)
- [CI/CD流水线](#cicd流水线)
- [监控与告警](#监控与告警)
- [日志管理](#日志管理)
- [故障排查](#故障排查)
- [性能优化](#性能优化)
- [安全加固](#安全加固)
- [灾难恢复](#灾难恢复)

## 容器化部署

### Docker最佳实践

#### Dockerfile优化
```dockerfile
# 多阶段构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 生产镜像
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

EXPOSE 3000
USER node
CMD ["node", "dist/main.js"]
```

#### Docker Compose配置
```yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
    depends_on:
      - db
      - redis
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=pass
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - app
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:
```

### Kubernetes部署

#### Deployment配置
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: myapp-secrets
              key: database-url
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
```

#### Service配置
```yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer
```

#### Ingress配置
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: myapp-tls
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80
```

## CI/CD流水线

### GitHub Actions

#### 自动化测试和部署
```yaml
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x, 20.x]

    steps:
    - uses: actions/checkout@v3

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

    - name: Install dependencies
      run: npm ci

    - name: Run linter
      run: npm run lint

    - name: Run tests
      run: npm run test:coverage

    - name: Upload coverage
      uses: codecov/codecov-action@v3

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
    - uses: actions/checkout@v3

    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2

    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: |
          myapp:latest
          myapp:${{ github.sha }}
        cache-from: type=registry,ref=myapp:latest
        cache-to: type=inline

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
    - uses: actions/checkout@v3

    - name: Configure kubectl
      uses: azure/k8s-set-context@v3
      with:
        method: kubeconfig
        kubeconfig: ${{ secrets.KUBE_CONFIG }}

    - name: Deploy to Kubernetes
      run: |
        kubectl set image deployment/myapp \
          myapp=myapp:${{ github.sha }} \
          --namespace=production

        kubectl rollout status deployment/myapp \
          --namespace=production
```

### GitLab CI/CD

```yaml
stages:
  - test
  - build
  - deploy

variables:
  DOCKER_IMAGE: myapp

test:
  stage: test
  image: node:20
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run lint
    - npm run test:coverage
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'

build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE:$CI_COMMIT_SHA .
    - docker push $DOCKER_IMAGE:$CI_COMMIT_SHA
  only:
    - main

deploy_staging:
  stage: deploy
  image:
    name: bitnami/kubectl:latest
  script:
    - kubectl config use-context staging
    - kubectl set image deployment/myapp myapp=$DOCKER_IMAGE:$CI_COMMIT_SHA
    - kubectl rollout status deployment/myapp
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - main

deploy_production:
  stage: deploy
  image:
    name: bitnami/kubectl:latest
  script:
    - kubectl config use-context production
    - kubectl set image deployment/myapp myapp=$DOCKER_IMAGE:$CI_COMMIT_SHA
    - kubectl rollout status deployment/myapp
  environment:
    name: production
    url: https://example.com
  when: manual
  only:
    - main
```

## 监控与告警

### Prometheus配置

#### prometheus.yml
```yaml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - alertmanager:9093

rule_files:
  - "alerts.yml"

scrape_configs:
  - job_name: 'myapp'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - production
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
```

#### 告警规则（alerts.yml）
```yaml
groups:
  - name: myapp_alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate detected"
          description: "Error rate is {{ $value }} for {{ $labels.instance }}"

      - alert: HighLatency
        expr: |
          histogram_quantile(0.95,
            sum(rate(http_request_duration_seconds_bucket[5m])) by (le, instance)
          ) > 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High latency detected"
          description: "95th percentile latency is {{ $value }}s"

      - alert: PodNotReady
        expr: kube_pod_status_ready{condition="true"} == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Pod is not ready"
          description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} is not ready"

      - alert: DatabaseConnectionPoolExhausted
        expr: |
          pg_stat_activity_count{datname="myapp"} / pg_settings_max_connections > 0.9
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Database connection pool nearly exhausted"
          description: "{{ $value | humanizePercentage }} of connections used"
```

### Grafana仪表盘

#### 关键指标面板
```json
{
  "dashboard": {
    "title": "Application Performance",
    "panels": [
      {
        "title": "Request Rate",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total[5m])) by (method, path)"
          }
        ]
      },
      {
        "title": "Error Rate",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) / sum(rate(http_requests_total[5m]))"
          }
        ]
      },
      {
        "title": "Response Time (95th percentile)",
        "targets": [
          {
            "expr": "histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))"
          }
        ]
      },
      {
        "title": "CPU Usage",
        "targets": [
          {
            "expr": "100 * (1 - avg(rate(node_cpu_seconds_total{mode=\"idle\"}[5m])))"
          }
        ]
      },
      {
        "title": "Memory Usage",
        "targets": [
          {
            "expr": "100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)"
          }
        ]
      }
    ]
  }
}
```

## 日志管理

### ELK Stack配置

#### Logstash配置
```conf
input {
  beats {
    port => 5044
  }
}

filter {
  if [kubernetes][namespace] == "production" {
    grok {
      match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message}" }
    }

    date {
      match => [ "timestamp", "ISO8601" ]
    }

    # 添加应用元数据
    mutate {
      add_field => {
        "environment" => "production"
        "app_name" => "%{[kubernetes][labels][app]}"
      }
    }
  }
}

output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "myapp-%{+YYYY.MM.dd}"
  }
}
```

#### 日志查询示例
```json
// Kibana查询语法
// 1. 查看错误日志
level: "ERROR"

// 2. 查看特定用户的请求
user_id: "123" AND level: "INFO"

// 3. 查看慢查询
message: *slow* AND duration:>1000

// 4. 查看最近1小时的错误
@timestamp:[now-1h TO now] AND level: "ERROR"

// 5. 统计错误类型
aggs: {
  "error_types": {
    "terms": {
      "field": "error_type.keyword",
      "size": 10
    }
  }
}
```

## 故障排查

### 常见问题诊断

#### Pod无法启动
```bash
# 查看Pod状态
kubectl describe pod <pod-name> -n <namespace>

# 查看日志
kubectl logs <pod-name> -n <namespace>

# 查看事件
kubectl get events -n <namespace> --sort-by='.lastTimestamp'

# 进入Pod调试
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
```

#### 服务不可用
```bash
# 检查Service
kubectl get svc -n <namespace>

# 检查Endpoint
kubectl get endpoints <service-name> -n <namespace>

# 测试服务连通性
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -O- http://<service-name>.<namespace>.svc.cluster.local

# 检查Ingress
kubectl describe ingress <ingress-name> -n <namespace>
```

#### 性能问题
```bash
# 查看资源使用
kubectl top pods -n <namespace>
kubectl top nodes

# 查看Pod资源限制
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 "Limits"

# 查看容器资源使用
kubectl exec <pod-name> -n <namespace> -- top
```

### 故障排查流程

```bash
#!/bin/bash
# 故障排查脚本

NAMESPACE=${1:-production}

echo "=== 检查Pod状态 ==="
kubectl get pods -n $NAMESPACE

echo -e "\n=== 检查最近的事件 ==="
kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp' --field-selector type!=Normal | tail -20

echo -e "\n=== 检查资源使用 ==="
kubectl top pods -n $NAMESPACE

echo -e "\n=== 检查Service状态 ==="
kubectl get svc -n $NAMESPACE

echo -e "\n=== 检查Ingress状态 ==="
kubectl get ingress -n $NAMESPACE

echo -e "\n=== 检查PVC状态 ==="
kubectl get pvc -n $NAMESPACE
```

## 性能优化

### 应用层优化

#### Node.js性能调优
```javascript
// cluster模式
const cluster = require('cluster');
const os = require('os');

if (cluster.isMaster) {
  const cpuCount = os.cpus().length;
  console.log(`Master ${process.pid} is running`);

  for (let i = 0; i < cpuCount; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  require('./app');
}
```

#### 数据库连接池配置
```javascript
// PostgreSQL连接池
const pool = new Pool({
  host: process.env.DB_HOST,
  port: 5432,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  [REDACTED_SECRET],
  max: 20, // 最大连接数
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});
```

### 系统层优化

#### Nginx配置优化
```nginx
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # 开启gzip
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript;

    # 连接优化
    keepalive_timeout 65;
    keepalive_requests 100;

    # 缓存配置
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;

    upstream myapp {
        least_conn;
        server app1:3000 weight=3;
        server app2:3000 weight=2;
        server app3:3000 backup;
        keepalive 32;
    }

    server {
        listen 80;
        server_name myapp.example.com;

        location / {
            proxy_pass http://myapp;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_cache my_cache;
            proxy_cache_valid 200 10m;
        }
    }
}
```

## 安全加固

### 容器安全

#### 最小权限原则
```yaml
# SecurityContext配置
apiVersion: v1
kind: Pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: myapp
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
```

#### 镜像扫描
```bash
# 使用Trivy扫描镜像
trivy image myapp:latest

# 使用Clair扫描
clairctl analyze myapp:latest

# 集成到CI/CD
- name: Scan Docker image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: myapp:latest
    format: 'sarif'
    output: 'trivy-results.sarif'
```

### 网络安全

#### NetworkPolicy配置
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp-network-policy
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: nginx
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
```

### 密钥管理

#### Secret管理
```bash
# 创建Secret
kubectl create secret generic myapp-secrets \
  --from-literal=database-url='postgresql://user:pass@db:5432/myapp' \
  --from-literal=[REDACTED_SECRET]' \
  -n production

# 使用Sealed Secrets加密Secret
kubeseal -f secret.yaml -w sealed-secret.yaml

# 或使用External Secrets Operator引用外部密钥管理器
```

## 灾难恢复

### 备份策略

#### 数据库备份
```bash
#!/bin/bash
# PostgreSQL备份脚本

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/postgres"
RETENTION_DAYS=7

# 创建备份
pg_dump -h $DB_HOST -U $DB_USER -d $DB_NAME | gzip > $BACKUP_DIR/myapp_$DATE.sql.gz

# 清理旧备份
find $BACKUP_DIR -name "myapp_*.sql.gz" -mtime +$RETENTION_DAYS -delete

# 上传到S3
aws s3 cp $BACKUP_DIR/myapp_$DATE.sql.gz s3://my-backups/postgres/
```

#### Kubernetes资源备份
```bash
# 使用Velero备份
velero backup create myapp-backup \
  --include-namespaces production \
  --selector app=myapp \
  --ttl 72h

# 定时备份
velero schedule create daily-backup \
  --schedule="0 2 * * *" \
  --include-namespaces production \
  --ttl 168h
```

### 恢复流程

```bash
#!/bin/bash
# 恢复脚本

echo "=== 停止应用 ==="
kubectl scale deployment myapp --replicas=0 -n production

echo "=== 恢复数据库 ==="
aws s3 cp s3://my-backups/postgres/myapp_20240106_020000.sql.gz - | gunzip | psql -h $DB_HOST -U $DB_USER -d $DB_NAME

echo "=== 启动应用 ==="
kubectl scale deployment myapp --replicas=3 -n production

echo "=== 等待Pod就绪 ==="
kubectl rollout status deployment/myapp -n production

echo "=== 验证服务 ==="
curl -f http://myapp.example.com/health || exit 1

echo "=== 恢复完成 ==="
```


path: references/frontend-guide.md
content: # 前端开发指南

## 目录
- [前端工程化](#前端工程化)
- [React深度实践](#react深度实践)
- [Vue深度实践](#vue深度实践)
- [性能优化](#性能优化)
- [状态管理](#状态管理)
- [组件设计模式](#组件设计模式)
- [前端测试](#前端测试)
- [前端安全](#前端安全)

## 前端工程化

### 项目脚手架

#### React + Vite
```bash
# 创建项目
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install

# 目录结构
src/
├── assets/          # 静态资源
├── components/      # 通用组件
│   ├── common/     # UI组件（Button、Input等）
│   └── business/   # 业务组件（UserCard、OrderList等）
├── pages/          # 页面组件
├── hooks/          # 自定义Hooks
├── services/       # API服务
├── stores/         # 状态管理
├── utils/          # 工具函数
├── types/          # TypeScript类型
├── constants/      # 常量
├── config/         # 配置
└── styles/         # 全局样式
```

#### Vue 3 + Vite
```bash
# 创建项目
npm create vue@latest my-app
cd my-app
npm install

# 目录结构
src/
├── assets/          # 静态资源
├── components/      # 组件
├── views/           # 页面视图
├── composables/     # 组合式函数
├── stores/          # Pinia状态管理
├── router/          # 路由配置
├── api/             # API服务
├── utils/           # 工具函数
└── styles/          # 全局样式
```

### 代码规范配置

#### ESLint + Prettier
```json
// .eslintrc.cjs
module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'prettier',
  ],
  rules: {
    'react/react-in-jsx-scope': 'off',
    '@typescript-eslint/no-explicit-any': 'warn',
    '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
  },
};
```

```json
// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 80,
  "arrowParens": "avoid"
}
```

### 环境变量管理
```typescript
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  define: {
    'import.meta.env.VITE_API_URL': JSON.stringify(process.env.VITE_API_URL),
  },
});
```

```bash
# .env
VITE_API_URL=https://api.example.com
VITE_APP_TITLE=My App
```

## React深度实践

### Hooks最佳实践

#### 自定义Hook封装
```typescript
import { useState, useEffect, useCallback } from 'react';

interface UseAsyncResult<T> {
  data: T | null;
  loading: boolean;
  error: Error | null;
  refetch: () => Promise<void>;
}

export function useAsync<T>(
  asyncFn: () => Promise<T>,
  dependencies: any[] = []
): UseAsyncResult<T> {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  const fetchData = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const result = await asyncFn();
      setData(result);
    } catch (err) {
      setError(err as Error);
    } finally {
      setLoading(false);
    }
  }, [asyncFn]);

  useEffect(() => {
    fetchData();
  }, [fetchData, ...dependencies]);

  return { data, loading, error, refetch: fetchData };
}
```

#### 使用示例
```typescript
// 获取用户数据
function UserProfile({ userId }: { userId: string }) {
  const { data: user, loading, error } = useAsync(
    () => fetchUser(userId),
    [userId]
  );

  if (loading) return <Spinner />;
  if (error) return <ErrorMessage error={error} />;

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}
```

### 组件设计模式

#### 容器组件 vs 展示组件
```typescript
// 展示组件（纯UI，无业务逻辑）
interface UserCardProps {
  name: string;
  email: string;
  avatar?: string;
  onClick?: () => void;
}

export function UserCard({ name, email, avatar, onClick }: UserCardProps) {
  return (
    <div className="user-card" onClick={onClick}>
      <img src={avatar || '/default-avatar.png'} alt={name} />
      <h3>{name}</h3>
      <p>{email}</p>
    </div>
  );
}

// 容器组件（业务逻辑，数据获取）
export function UserCardContainer({ userId }: { userId: string }) {
  const { data: user, loading } = useAsync(() => fetchUser(userId), [userId]);

  if (loading) return <Skeleton />;
  if (!user) return null;

  const handleClick = () => {
    router.push(`/users/${userId}`);
  };

  return <UserCard {...user} onClick={handleClick} />;
}
```

#### 高阶组件（HOC）
```typescript
// 高阶组件：添加加载状态
function withLoading<P extends object>(
  Component: React.ComponentType<P>
): React.FC<P & { loading: boolean }> {
  return ({ loading, ...props }) => {
    if (loading) {
      return <Spinner />;
    }
    return <Component {...(props as P)} />;
  };
}

// 使用
const UserList = withLoading(({ users }: { users: User[] }) => {
  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} {...user} />
      ))}
    </div>
  );
});
```

### Context API使用

```typescript
// 1. 创建Context
interface AuthContextType {
  user: User | null;
  login: (credentials: LoginCredentials) => Promise<void>;
  logout: () => void;
}

const AuthContext = React.createContext<AuthContextType | null>(null);

// 2. 提供Provider
export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);

  const login = async (credentials: LoginCredentials) => {
    const user = await authService.login(credentials);
    setUser(user);
  };

  const logout = () => {
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

// 3. 创建自定义Hook
export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within AuthProvider');
  }
  return context;
}

// 4. 使用
function Dashboard() {
  const { user, logout } = useAuth();

  return (
    <div>
      <h1>Welcome, {user.name}</h1>
      <button onClick={logout}>Logout</button>
    </div>
  );
}
```

## Vue深度实践

### Composition API

#### 组合式函数
```typescript
// composables/useUser.ts
import { ref, computed } from 'vue';
import { fetchUser as apiFetchUser } from '@/api/user';

export function useUser(userId: Ref<string>) {
  const user = ref<User | null>(null);
  const loading = ref(false);
  const error = ref<Error | null>(null);

  const fetchUser = async () => {
    try {
      loading.value = true;
      error.value = null;
      user.value = await apiFetchUser(userId.value);
    } catch (err) {
      error.value = err as Error;
    } finally {
      loading.value = false;
    }
  };

  // 自动获取
  watch(userId, fetchUser, { immediate: true });

  return {
    user,
    loading,
    error,
    fetchUser,
    userName: computed(() => user.value?.name ?? ''),
  };
}
```

#### 使用示例
```vue
<template>
  <div>
    <div v-if="loading">Loading...</div>
    <div v-else-if="error">Error: {{ error.message }}</div>
    <div v-else>
      <h1>{{ user.name }}</h1>
      <p>{{ user.email }}</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useUser } from '@/composables/useUser';

const userId = ref('123');
const { user, loading, error } = useUser(userId);
</script>
```

### Pinia状态管理

```typescript
// stores/user.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    currentUser: null as User | null,
    [REDACTED_SECRET]'token') || '',
  }),

  getters: {
    isAuthenticated: (state) => !!state.token,
    userName: (state) => state.currentUser?.name ?? '',
  },

  actions: {
    async login(credentials: LoginCredentials) {
      const { user, token } = await authService.login(credentials);
      this.currentUser = user;
      this.token = token;
      localStorage.setItem('token', token);
    },

    logout() {
      this.currentUser = null;
      this.token = '';
      localStorage.removeItem('token');
    },
  },
});
```

## 性能优化

### 代码分割

#### 路由懒加载
```typescript
// React Router
import { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}
```

#### Vue Router懒加载
```typescript
const routes = [
  {
    path: '/dashboard',
    component: () => import('@/views/Dashboard.vue'),
  },
  {
    path: '/settings',
    component: () => import('@/views/Settings.vue'),
  },
];
```

### 组件优化

#### React.memo
```typescript
export const ExpensiveComponent = React.memo(
  ({ data, onUpdate }: { data: Item[]; onUpdate: (item: Item) => void }) => {
    return (
      <div>
        {data.map(item => (
          <div key={item.id}>{item.name}</div>
        ))}
      </div>
    );
  },
  (prevProps, nextProps) => {
    // 自定义比较逻辑
    return prevProps.data.length === nextProps.data.length;
  }
);
```

#### Vue computed缓存
```vue
<script setup lang="ts">
import { computed } from 'vue';

const items = ref<Item[]>([]);

// 计算属性会自动缓存
const expensiveValue = computed(() => {
  return items.value.reduce((sum, item) => sum + item.value, 0);
});
</script>
```

### 资源优化

#### 图片懒加载
```typescript
import { LazyLoadImage } from 'react-lazy-load-image-component';

<LazyLoadImage
  src={imageSrc}
  alt="Description"
  effect="blur"
  width={300}
  height={200}
/>
```

#### WebP格式支持
```typescript
// 图片组件
function OptimizedImage({ src, alt, ...props }: ImageProps) {
  const webpSrc = src.replace(/\.(jpg|png)$/, '.webp');

  return (
    <picture>
      <source srcSet={webpSrc} type="image/webp" />
      <img src={src} alt={alt} {...props} loading="lazy" />
    </picture>
  );
}
```

## 状态管理

### Redux Toolkit

```typescript
// store/userSlice.ts
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { userService } from '@/services/user';

export const fetchUser = createAsyncThunk(
  'user/fetchUser',
  async (userId: string) => {
    return await userService.getUser(userId);
  }
);

const userSlice = createSlice({
  name: 'user',
  initialState: {
    user: null,
    loading: false,
    error: null,
  } as UserState,
  reducers: {
    clearError: (state) => {
      state.error = null;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUser.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchUser.fulfilled, (state, action) => {
        state.loading = false;
        state.user = action.payload;
      })
      .addCase(fetchUser.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  },
});
```

### Zustand（轻量级）

```typescript
import { create } from 'zustand';

interface UserStore {
  user: User | null;
  loading: boolean;
  setUser: (user: User) => void;
  clearUser: () => void;
}

export const useUserStore = create<UserStore>((set) => ({
  user: null,
  loading: false,
  setUser: (user) => set({ user }),
  clearUser: () => set({ user: null }),
}));
```

## 前端测试

### 单元测试（Jest + React Testing Library）

```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { UserCard } from './UserCard';

describe('UserCard', () => {
  const mockUser = {
    id: '1',
    name: 'John Doe',
    email: '[REDACTED_SECRET]',
  };

  it('renders user information', () => {
    render(<UserCard {...mockUser} />);
    expect(screen.getByText('John Doe')).toBeInTheDocument();
    expect(screen.getByText('[REDACTED_SECRET]')).toBeInTheDocument();
  });

  it('calls onClick when clicked', () => {
    const handleClick = jest.fn();
    render(<UserCard {...mockUser} onClick={handleClick} />);
    fireEvent.click(screen.getByText('John Doe'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});
```

### E2E测试（Playwright）

```typescript
import { test, expect } from '@playwright/test';

test('user login flow', async ({ page }) => {
  await page.goto('http://localhost:3000/login');

  await page.fill('input[name="email"]', '[REDACTED_SECRET]');
  await page.fill('input[name="password"]', 'password123');
  await page.click('button[type="submit"]');

  await expect(page).toHaveURL('http://localhost:3000/dashboard');
  await expect(page.locator('h1')).toContainText('Welcome');
});
```

## 前端安全

### XSS防护
```typescript
// 使用DOMPurify清理HTML
import DOMPurify from 'dompurify';

function sanitizeHtml(html: string): string {
  return DOMPurify.sanitize(html);
}

// React自动转义，但dangerouslySetInnerHTML需要谨慎
function renderUserContent(content: string) {
  return (
    <div
      dangerouslySetInnerHTML={{ __html: sanitizeHtml(content) }}
    />
  );
}
```

### CSRF防护
```typescript
// axios拦截器添加CSRF Token
axios.interceptors.request.use((config) => {
  const csrfToken = getCookie('csrf_token');
  if (csrfToken) {
    config.headers['X-CSRF-Token'] = csrfToken;
  }
  return config;
});
```

### 敏感信息保护
```typescript
// 避免在前端存储敏感信息
// ❌ 错误：localStorage存储Token
localStorage.setItem('token', token);

// ✅ 正确：使用HttpOnly Cookie
// Token由后端设置HttpOnly Cookie，前端无法访问

// ✅ 或使用短期Token + Refresh Token机制
```


path: references/tech-stack-comparison.md
content: # 技术栈对比指南

## 目录
- [前端技术栈](#前端技术栈)
- [后端技术栈](#后端技术栈)
- [数据库技术栈](#数据库技术栈)
- [中间件技术栈](#中间件技术栈)
- [DevOps工具栈](#devops工具栈)
- [技术栈选择决策](#技术栈选择决策)

## 前端技术栈

### React 生态
**适用场景**：
- 大型企业应用
- 组件化开发需求强
- 需要灵活的状态管理

**核心库**：
- UI框架：React 18+
- 路由：React Router 6
- 状态管理：Redux Toolkit / Zustand / Recoil
- UI组件库：Ant Design / Material-UI
- 构建工具：Vite / Next.js
- TypeScript推荐

**优势**：
- 生态成熟，社区活跃
- 灵活性高，学习曲线适中
- 适合大型项目
- 性能优秀（虚拟DOM）

**劣势**：
- 需要额外状态管理库
- 过度灵活可能带来代码不一致

### Vue 生态
**适用场景**：
- 中小型项目
- 快速开发
- 团队前端基础较弱

**核心库**：
- UI框架：Vue 3 + Composition API
- 路由：Vue Router 4
- 状态管理：Pinia / Vuex
- UI组件库：Element Plus / Naive UI
- 构建工具：Vite / Nuxt 3

**优势**：
- 学习曲线平缓，易于上手
- 渐进式框架，灵活性强
- 官方支持完善，文档优秀
- 性能优秀，包体积小

**劣势**：
- 生态相比React略小
- 大型企业应用实践相对较少

### Angular 生态
**适用场景**：
- 大型企业级应用
- 需要完整框架约束
- 强类型要求高

**核心库**：
- 框架：Angular 17+
- UI组件库：Angular Material / PrimeNG
- 状态管理：NgRx / Akita
- 构建工具：Angular CLI

**优势**：
- 完整的企业级解决方案
- TypeScript原生支持
- 依赖注入，模块化设计
- 长期支持和稳定性

**劣势**：
- 学习曲线陡峭
- 框架较重，包体积大
- 灵活性相对较低

### 其他选择
- **Svelte**：编译型框架，性能优秀，生态较小
- **Solid**：类似React但更细粒度响应式，新兴框架
- **Preact**：React轻量替代，适合性能敏感场景

## 后端技术栈

### Node.js
**适用场景**：
- 高并发IO密集型应用
- 实时应用（聊天、协作）
- 全栈JavaScript开发

**技术栈**：
- 运行时：Node.js 20+
- Web框架：Express / Fastify / Koa / NestJS
- ORM：Prisma / TypeORM / Sequelize
- 验证：Zod / Joi / class-validator
- 测试：Jest / Mocha / Supertest

**优势**：
- 异步非阻塞，高并发处理
- JavaScript全栈
- 生态丰富，npm包庞大
- 快速开发

**劣势**：
- CPU密集型任务性能有限
- 单线程，稳定性需关注
- 回调地狱（async/await解决）

### Java
**适用场景**：
- 大型企业应用
- 高并发、高可用系统
- 需要强类型和稳定性的项目

**技术栈**：
- 框架：Spring Boot 3.x
- ORM：Spring Data JPA / MyBatis
- 安全：Spring Security
- 消息：RabbitMQ / Kafka
- 缓存：Redis / Caffeine

**优势**：
- 企业级稳定性
- 强类型，编译期检查
- 生态成熟
- 适合大型团队

**劣势**：
- 启动慢，内存占用高
- 开发效率相对较低
- 语法相对繁琐

### Python
**适用场景**：
- 快速开发和原型
- 数据处理和AI应用
- 中小型Web应用

**技术栈**：
- 框架：Django / FastAPI / Flask
- ORM：Django ORM / SQLAlchemy
- 异步：asyncio / aiohttp
- 数据处理：Pandas / NumPy

**优势**：
- 语法简洁，易于学习
- 生态丰富（AI/数据）
- 快速开发
- 社区活跃

**劣势**：
- 性能相对较低
- GIL限制并行
- 部署相对复杂

### Go
**适用场景**：
- 高性能后端服务
- 微服务架构
- 云原生应用

**技术栈**：
- Web框架：Gin / Echo / Fiber
- ORM：GORM / Ent
- 并发：Goroutine + Channel
- gRPC支持

**优势**：
- 性能优秀，接近C++
- 原生并发支持
- 编译为单一可执行文件
- 部署简单

**劣势**：
- 生态相对较小
- 错误处理繁琐
- 泛型支持较新

### 其他选择
- **Rust**：高性能，内存安全，学习曲线陡峭
- **C# (.NET)**：企业级，性能优秀，跨平台支持
- **PHP**：快速开发，Web开发成熟，适合中小项目

## 数据库技术栈

### 关系型数据库

#### MySQL / PostgreSQL
**MySQL优势**：
- 最流行的开源数据库
- 性能优秀，简单易用
- 社区支持强大
- 云服务支持完善

**PostgreSQL优势**：
- 功能最强大（JSON、GIS、全文检索）
- 符合SQL标准
- 可扩展性强
- ACID严格

**选择建议**：
- 通用场景 → MySQL
- 复杂查询/JSON数据/地理信息 → PostgreSQL
- 云服务优先考虑

#### SQL Server / Oracle
**适用场景**：
- 大型企业
- Windows环境
- 需要商业支持

### NoSQL数据库

#### MongoDB
**适用场景**：
- 文档型数据
- 灵活的数据结构
- 快速迭代

**优势**：
- Schema灵活
- 查询能力强
- 水平扩展
- 文档丰富

#### Redis
**适用场景**：
- 缓存
- 会话存储
- 实时计数器
- 消息队列

**优势**：
- 高性能（内存存储）
- 丰富的数据结构
- 持久化支持
- 主从复制

#### 其他NoSQL
- **Cassandra**：大规模分布式数据
- **Elasticsearch**：全文检索、日志分析
- **Neo4j**：图数据库，社交网络
- **InfluxDB**：时序数据库，监控数据

## 中间件技术栈

### 消息队列
- **RabbitMQ**：功能完善，中小规模场景
- **Kafka**：高吞吐，大数据场景
- **RocketMQ**：阿里开源，稳定性强
- **Redis Stream**：轻量级，简单场景

### 缓存
- **Redis**：通用缓存，分布式锁
- **Memcached**：简单缓存，性能极致
- **CDN**：静态资源缓存

### 搜索引擎
- **Elasticsearch**：全文检索，日志分析
- **Solr**：企业级搜索
- **MeiliSearch**：轻量级搜索

## DevOps工具栈

### 容器化
- **Docker**：容器运行时
- **Kubernetes**：容器编排
- **Docker Compose**：本地开发

### CI/CD
- **GitHub Actions**：GitHub原生
- **GitLab CI**：GitLab集成
- **Jenkins**：老牌工具，灵活强大
- **ArgoCD**：GitOps

### 监控告警
- **Prometheus**：监控数据采集
- **Grafana**：可视化面板
- **ELK Stack**：日志分析
- **Sentry**：错误追踪

### 云平台
- **AWS**：功能最全
- **Azure**：企业集成
- **Google Cloud**：AI/ML优势
- **阿里云**：国内稳定

## 技术栈选择决策

### 决策因素

1. **团队能力**
   - 团队熟悉的技术栈优先
   - 考虑学习曲线和培训成本

2. **项目需求**
   - 并发量、性能要求
   - 数据复杂度
   - 实时性要求

3. **时间成本**
   - 开发速度 vs 性能优化
   - MVP vs 成熟产品

4. **维护成本**
   - 长期维护考虑
   - 技术债务积累

5. **社区和生态**
   - 成熟度和稳定性
   - 问题解决速度

### 典型组合

#### 全栈JavaScript方案
```
前端：React + TypeScript
后端：Node.js + NestJS
数据库：PostgreSQL + Redis
部署：Docker + K8s
```

#### Java企业级方案
```
前端：Vue 3 + TypeScript
后端：Spring Boot + MyBatis
数据库：MySQL + Redis
消息：RabbitMQ
部署：Docker + Jenkins
```

#### Python快速开发方案
```
前端：React + Next.js
后端：FastAPI + SQLAlchemy
数据库：PostgreSQL
部署：Docker + GitHub Actions
```

#### Go高性能方案
```
前端：React
后端：Go + Gin + GORM
数据库：PostgreSQL + Redis
消息：Kafka
部署：K8s + ArgoCD
```

### 技术栈评估表

| 技术栈 | 学习成本 | 开发速度 | 运维成本 | 社区活跃度 | 适用场景 |
|--------|---------|---------|---------|-----------|---------|
| React | 中 | 快 | 低 | 高 | 大型应用 |
| Vue | 低 | 快 | 低 | 高 | 中小型应用 |
| Node.js | 低 | 快 | 中 | 高 | 高并发IO |
| Java | 高 | 中 | 中 | 高 | 企业级应用 |
| Python | 低 | 快 | 中 | 高 | 快速开发 |
| Go | 中 | 中 | 低 | 中 | 高性能服务 |
| MySQL | 低 | - | 低 | 高 | 通用场景 |
| PostgreSQL | 中 | - | 中 | 高 | 复杂场景 |
| MongoDB | 低 | - | 中 | 高 | 文档数据 |
| Redis | 低 | - | 低 | 高 | 缓存 |

### 选择建议

1. **小型项目**（MVP/原型）：
   - 前端：Vue 3
   - 后端：FastAPI / Node.js
   - 数据库：PostgreSQL

2. **中型项目**（5-15人团队）：
   - 前端：React / Vue 3
   - 后端：Spring Boot / NestJS
   - 数据库：MySQL + Redis

3. **大型项目**（15+人团队）：
   - 前端：React + TypeScript
   - 后端：Spring Boot / Go微服务
   - 数据库：MySQL + Redis + Elasticsearch

4. **高并发场景**：
   - 后端：Go / Node.js
   - 数据库：Redis + 分库分表
   - 消息：Kafka

5. **快速验证**：
   - 前端：Vite + React
   - 后端：FastAPI
   - 部署：Vercel / Railway


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)