Skip to content

Latest commit

 

History

History
505 lines (369 loc) · 16 KB

File metadata and controls

505 lines (369 loc) · 16 KB

AGENTS.md - 代码规范与开发指南

本文档面向 AI 编码代理(如 GitHub Copilot、Cursor、OpenCode),提供项目的构建命令、代码风格和架构指南。

Code Generation Requirements

When generating code for this project, follow these strict guidelines:

  1. 绝对不要生成示例代码 - Never generate example code or usage examples
  2. 不要生成说明文档 - Do not generate documentation or explanation comments
  3. 除非明确说明,不要生成测试用例 - Do not generate test cases unless explicitly requested
  4. 优先使用 AskQuestions 工具 - If you need clarification, ask questions instead of making assumptions
  5. 执行 writing-plans 后,使用 AskQuestions 工具询问下一步动作 - After executing writing-plans, use the AskQuestions tool to inquire about the next steps

Focus solely on production code implementation without examples, documentation, or tests unless specifically requested.

1. 项目概述

这是一个基于 TypeScript/Node.js 构建的华为云 CodeArts 统计分析工具。

核心功能

  • 通过华为云 CodeArts API 获取 issue、人员、工时数据
  • 生成日报统计(每日工时、Bug 修复、工作进度)
  • 生成年度工时统计报表(按人员、领域分组)
  • 统计迭代中的产品缺陷率(按处理人分组)
  • 交互式修复当前用户的 bug,填写缺陷分析信息
  • Bug 列表查询与多维度 ECharts 可视化分析(生成 HTML 报告)
  • 支持 IAM Token 自动认证和缓存

技术栈

  • 语言: TypeScript 5.2+
  • 运行时: Node.js >= 20.19(20.19+/22.13+,依赖 require(esm) 加载 ESM-only 依赖)
  • HTTP 客户端: Axios
  • 测试框架: Jest + ts-jest
  • 代码检查: ESLint + Prettier

2. 构建与测试命令

基础命令

# 安装依赖
npm install

# 编译 TypeScript
npm run build

# CLI 命令方式(推荐)
codearts config                 # 交互式配置向导
codearts daily                # 运行日报统计(默认当天)
codearts work-hour            # 运行年度工时统计(当前年份)
codearts bug-rate "迭代1,迭代2"  # 统计指定迭代的产品缺陷率
codearts fix                  # 交互式修复当前用户的 bug,填写缺陷分析信息
codearts rebug                # Bug 列表查询与多维度可视化分析

# 本地开发
npm run dev                            # 本地执行命令

测试命令

# 运行所有测试
npm test

代码检查和格式化

# 运行 ESLint 检查
npx eslint src/**/*.ts

# 运行 Prettier 格式化
npx prettier --write "src/**/*.ts"

3. 项目架构

目录结构

src/
├── bin/                    # CLI 入口
│   └── cli.ts              # Commander.js CLI 定义
├── commands/               # 命令实现
│   ├── bug.command.ts     # 产品缺陷率统计命令逻辑
│   ├── config.command.ts     # 交互式配置向导
│   ├── daily.command.ts    # 日报命令逻辑
│   ├── fix.command.ts      # 交互式修复 bug 命令逻辑
│   ├── rebug.command.ts    # Bug 列表查询与可视化分析命令逻辑
│   ├── work-hour.command.ts# 工时统计命令逻辑
│   └── index.ts            # 命令导出
├── charts/                 # ECharts 图表模块
│   ├── chart.interface.ts  # ChartModule 接口定义
│   ├── renderer.ts         # HTML 页面生成器
│   ├── index.ts            # 导出所有图表模块数组
│   └── modules/            # 图表模块(每个分析维度一个文件)
│       ├── bug-by-defect-analysis.ts  # 按缺陷技术分析分布(饼图)
│       ├── bug-by-assignee.ts         # 按处理人分布(横向柱状图)
│       └── bug-by-module.ts           # 按模块分布(柱状图)
├── services/               # API 服务层
│   ├── api.service.ts      # 华为云基础 API 封装
│   └── business.service.ts # 业务场景 API 封装
├── utils/                  # 工具函数
│   ├── console.ts          # 统一打印工具
│   ├── csv-writer.ts       # CSV 写入工具
│   ├── config-loader.ts    # 配置加载器(CLI参数 > 环境变量)
│   └── logger.ts           # 日志工具(单例模式,支持多种输出格式)
├── config/
│   └── holidays.ts         # 节假日配置与工作日计算
└── types/
    └── index.ts            # TypeScript 类型定义(API 契约)
bin/
└── codearts                # CLI 可执行文件

架构设计

CLI 层(src/bin/cli.ts)

使用 Commander.js 框架构建命令行工具:

  • 定义全局选项(--role等)
  • 注册子命令(config, daily, work-hour, bug-rate, fix, rebug)
  • 处理命令行参数解析
  • 提供 --help 帮助信息

命令层(src/commands/)

每个命令一个独立模块:

  • config.command.ts: 交互式配置向导(使用 inquirer)
  • daily.command.ts: 日报统计命令实现
  • work-hour.command.ts: 年度工时统计命令实现
  • bug.command.ts: 产品缺陷率统计命令逻辑
  • fix.command.ts: 交互式修复 bug,填写缺陷分析信息(使用 inquirer)
  • rebug.command.ts: Bug 列表查询与多维度 ECharts 可视化分析
  • 命令函数接收可选参数,支持通过配置和 CLI 参数配置

配置加载层(src/utils/config-loader.ts)

负责配置合并逻辑:

  • 优先级:命令行参数 > 配置文件
  • 统一的配置加载接口
  • 类型安全的配置对象

服务层(src/services/)

提供 API 封装

关键文件说明

  • src/bin/cli.ts: CLI 入口,使用 Commander.js 定义命令和选项
  • src/commands/config.command.ts: 交互式配置向导,使用 inquirer 引导用户创建配置文件
  • src/commands/daily.command.ts: 日报统计核心逻辑(从 daily.ts 提取)
  • src/commands/work-hour.command.ts: 年度工时统计核心逻辑(从 workHour.ts 提取)
  • src/commands/bug.command.ts: 产品缺陷率统计命令逻辑
  • src/commands/fix.command.ts: 交互式修复 bug,引导用户填写缺陷技术分析等字段
  • src/commands/rebug.command.ts: Bug 列表查询与多维度 ECharts 可视化分析,生成 HTML 报告
  • src/charts/chart.interface.ts: ChartModule 接口定义
  • src/charts/renderer.ts: HTML 页面生成器,将 Bug 数据渲染为 ECharts 报告
  • src/charts/index.ts: 导出所有图表模块数组(allCharts)
  • src/utils/config-loader.ts: 配置加载器,合并 CLI 参数和配置文件
  • src/utils/logger.ts: 日志工具(单例模式,支持多种输出格式)
  • src/services/api.service.ts: 华为云基础 API 封装,包含 IAM Token 认证、项目管理、工作项查询、工时管理等接口
  • src/services/business.service.ts: 面向具体业务场景的 API 封装,例如通过角色获取人员列表、查询迭代内所有 issue、统计工时数据等
  • src/config/holidays.ts: 节假日配置与判断逻辑,用于计算年度应计工作日
  • src/types/index.ts: 华为云 CodeArts API 的 TypeScript 类型定义
  • bin/codearts: CLI 可执行文件包装器

4. 代码风格规范

4.1 命名约定

  • 文件名: 使用 kebab-case,例如 api.service.ts, business.service.ts
  • 类名: 使用 PascalCase,例如 ApiService, BusinessService
  • 函数/变量名: 使用 camelCase,例如 getMembersByRoleId, totalHours
  • 接口/类型名: 使用 PascalCase,例如 HuaweiCloudConfig, WorkHour
  • 常量: 使用 UPPER_SNAKE_CASE,根据语义决定

4.2 格式化规则(Prettier)

{
  "semi": true, // 语句末尾添加分号
  "singleQuote": true, // 使用单引号
  "trailingComma": "es5", // ES5 兼容的尾随逗号
  "printWidth": 100, // 每行最大 100 字符
  "tabWidth": 2, // 缩进 2 空格
  "useTabs": false, // 使用空格而非 Tab
  "arrowParens": "always", // 箭头函数总是使用括号
  "endOfLine": "lf", // 使用 LF 换行符
  "bracketSameLine": false // 标签闭合符号单独一行
}

4.3 TypeScript 配置要点

  • 严格模式: "strict": true(启用所有严格类型检查)
  • 目标版本: "target": "ES2020"
  • 模块系统: "module": "commonjs"
  • 类型声明: 所有导出的函数和类必须包含类型声明
  • 编译输出: "outDir": "./dist", "rootDir": "./src"

4.4 ESLint 规则

  • 使用 @typescript-eslint/parser 解析器
  • 集成 Prettier(plugin:prettier/recommended)
  • 规则:
    • @typescript-eslint/no-explicit-any: warn(谨慎使用 any)
    • no-unused-vars: off(由 TypeScript 处理)
    • prettier/prettier: error(Prettier 格式错误视为 ESLint 错误)

5. 类型系统规范

5.1 类型定义

  • 所有 API 请求和响应必须定义 TypeScript 接口
  • 类型定义统一放在 src/types/index.ts
  • 使用 export interface 导出所有类型

5.2 类型注解

  • 函数参数必须明确类型
  • 函数返回值必须明确类型(尤其是 async 函数)
  • 尽量避免使用 any,如有必要使用 unknown 替代

示例:

async getMembersByRoleId(projectId: string, roleId: number): Promise<ProjectMember[]> {
  const membersResponse = await this.apiService.getMembers(projectId);
  if (!membersResponse.success) {
    throw new Error(`获取成员列表失败: ${membersResponse.error || '未知错误'}`);
  }
  const allMembers = membersResponse.data?.members || [];
  return allMembers.filter((member) => member.role_id === roleId);
}

5.3 可选属性和默认值

  • 使用 ? 表示可选属性
  • 使用 ?? 或 || 提供默认值
  • 优先使用解构赋值提供默认值

示例:

export interface HuaweiCloudConfig {
  domainName: string;
  enableLogging?: boolean;  // 可选属性
}

constructor(config: HuaweiCloudConfig) {
  this.enableLogging = config.enableLogging ?? false;  // 提供默认值
}

5.4 内部类型约定

  • 自定义字段优先使用枚举CustomFieldId,不要使用字符串 'custom_filedxx'

6. 错误处理规范

6.1 异步错误处理

  • 所有异步函数使用 try-catch 包裹
  • 错误信息必须清晰、具体
  • 使用 throw new Error() 抛出错误

示例:

try {
  const response = await this.iamClient.post<IamTokenResponse>('/v3/auth/tokens', requestBody);
  return response.data;
} catch (error: unknown) {
  if (axios.isAxiosError(error)) {
    const errorMsg = error.response?.data?.error?.message || error.message;
    throw new Error(`获取IAM Token失败: ${errorMsg}`);
  }
  throw new Error(`获取IAM Token失败: ${String(error)}`);
}

6.2 类型安全的错误处理

  • 捕获错误时使用 unknown 类型
  • 使用类型守卫判断错误类型(如 axios.isAxiosError(error))
  • 对未知错误使用 String(error) 转换

7. 日志输出规范

7.1 Logger 工具

项目使用统一的 Logger 工具(src/utils/logger.ts)进行日志输出。

重要原则:

  • ⛔ 禁止使用 console.log、console.error、console.warn 等原生方法
  • ✅ 必须使用 logger 工具的方法进行所有日志输出

7.2 错误输出规范

错误处理中使用 logger.error:

try {
  // 业务逻辑
} catch (error: unknown) {
  logger.error(`操作失败: ${String(error)}`);
  throw error;
}

禁止使用 console.error:

// ❌ 错误示例
console.error('操作失败');

// ✅ 正确示例
logger.error('操作失败');

8. 注释与文档规范

8.1 函数注释

  • 公共 API 必须使用 JSDoc 注释
  • 注释包括:功能说明、参数说明、返回值说明

示例:

/**
 * 通过角色ID获取项目成员
 * @param projectId 项目ID
 * @param roleId 角色ID
 * @returns 指定角色的成员列表
 */
async getMembersByRoleId(projectId: string, roleId: number): Promise<ProjectMember[]> {
  // 实现代码
}

8.2 注释原则

  • 不要生成示例代码 - 除非用户明确要求,否则不生成使用示例
  • 不要生成说明文档 - 不要在代码中生成冗长的文档注释
  • 不要生成测试用例 - 除非用户明确要求,否则不生成测试代码
  • 注释应该解释"为什么"而不是"是什么"
  • 复杂逻辑必须添加注释说明

9. API 设计原则

9.1 服务分层

  • ApiService: 封装华为云 CodeArts 的原始 API 调用
  • BusinessService: 封装面向业务场景的高级操作

9.2 响应格式

  • 统一使用 ApiResponse<T> 包装响应
  • 响应结构:
    interface ApiResponse<T> {
      success: boolean;
      data: T | null;
      message?: string;
      error?: string;
    }

9.3 参数传递

  • 使用接口定义复杂参数(如查询参数、请求体)
  • 可选参数使用 ? 标记

10. 配置管理

配置方式

项目使用配置文件,位于用户主目录:~/.hecom-codearts/config.env

使用前必须先运行 codearts config 进行配置。

配置优先级:命令行参数 > 配置文件

配置键枚举(ConfigKey)

为保证类型安全,所有配置项的键名使用 ConfigKey 枚举定义(src/types/index.ts):

export enum ConfigKey {
  // 不可变配置(只能通过 config 命令设置)
  HUAWEI_CLOUD_IAM_ENDPOINT = 'HUAWEI_CLOUD_IAM_ENDPOINT',
  HUAWEI_CLOUD_REGION = 'HUAWEI_CLOUD_REGION',
  HUAWEI_CLOUD_USERNAME = 'HUAWEI_CLOUD_USERNAME',
  HUAWEI_CLOUD_PASSWORD = 'HUAWEI_CLOUD_PASSWORD',
  HUAWEI_CLOUD_DOMAIN = 'HUAWEI_CLOUD_DOMAIN',
  CODEARTS_BASE_URL = 'CODEARTS_BASE_URL',
  PROJECT_ID = 'PROJECT_ID',

  // 可变配置(可以通过命令行参数覆盖)
  ROLE_ID = 'ROLE_ID',
}

配置分类

  1. 不可变配置(Immutable Config):只能通过 codearts config 命令设置

    • IAM 认证相关:HUAWEI_CLOUD_IAM_ENDPOINT, HUAWEI_CLOUD_REGION, HUAWEI_CLOUD_USERNAME, HUAWEI_CLOUD_PASSWORD, HUAWEI_CLOUD_DOMAIN
    • CodeArts 基础配置:CODEARTS_BASE_URL, PROJECT_ID
  2. 可变配置(Mutable Config):可以通过命令行参数覆盖

    • ROLE_ID:角色 ID(支持逗号分隔的多个角色)

类型安全的配置访问

使用枚举访问配置,避免字符串拼写错误:

import { ConfigKey, ConfigMap } from '../types';

// ✅ 正确:使用枚举
const projectId = config[ConfigKey.PROJECT_ID];
const roleId = config[ConfigKey.ROLE_ID];

// ❌ 错误:不要使用字符串字面量
const projectId = config['PROJECT_ID']; // 类型错误

配置文件

创建配置文件:

codearts config

配置文件位置:~/.hecom-codearts/config.env

配置示例:

HUAWEI_CLOUD_IAM_ENDPOINT=https://iam.cn-north-4.myhuaweicloud.com
HUAWEI_CLOUD_REGION=cn-north-4
HUAWEI_CLOUD_USERNAME=your-iam-username
HUAWEI_CLOUD_PASSWORD=your-iam-password
HUAWEI_CLOUD_DOMAIN=your-domain-name
CODEARTS_BASE_URL=https://projectman-ext.cn-north-4.myhuaweicloud.cn
PROJECT_ID=your-project-id
ROLE_ID=1,2,3  # 逗号分隔的多个角色ID

CLI 参数优先级

配置加载优先级:命令行参数 > 配置文件

目前支持的 CLI 参数:

  • --role <ids>: 角色 ID(支持逗号分隔)

注意:只有可变配置才能通过 CLI 参数覆盖。不可变配置必须通过 codearts config 命令设置。


11. 编码最佳实践

  1. 不要硬编码: 使用配置文件
  2. 避免重复代码: 提取公共逻辑到独立函数
  3. 保持函数简洁: 单个函数不超过 50 行(建议)
  4. 使用解构赋值: 简化对象和数组操作
  5. 优先使用箭头函数: 保持 this 上下文清晰
  6. 使用可选链: ?. 和 ?? 简化空值处理
  7. 遵循 DRY 原则: Don't Repeat Yourself
  8. 使用 logger 工具: 禁止使用 console.log、console.error 等原生方法

本文档版本: 2026-03-27
适用于: AI 编码代理(GitHub Copilot, Cursor, OpenCode 等)