本文档面向 AI 编码代理(如 GitHub Copilot、Cursor、OpenCode),提供项目的构建命令、代码风格和架构指南。
When generating code for this project, follow these strict guidelines:
- 绝对不要生成示例代码 - Never generate example code or usage examples
- 不要生成说明文档 - Do not generate documentation or explanation comments
- 除非明确说明,不要生成测试用例 - Do not generate test cases unless explicitly requested
- 优先使用 AskQuestions 工具 - If you need clarification, ask questions instead of making assumptions
- 执行 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.
这是一个基于 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
# 安装依赖
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"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 可执行文件
使用 Commander.js 框架构建命令行工具:
- 定义全局选项(--role等)
- 注册子命令(config, daily, work-hour, bug-rate, fix, rebug)
- 处理命令行参数解析
- 提供 --help 帮助信息
每个命令一个独立模块:
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 参数配置
负责配置合并逻辑:
- 优先级:命令行参数 > 配置文件
- 统一的配置加载接口
- 类型安全的配置对象
提供 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 可执行文件包装器
- 文件名: 使用
kebab-case,例如api.service.ts,business.service.ts - 类名: 使用
PascalCase,例如ApiService,BusinessService - 函数/变量名: 使用
camelCase,例如getMembersByRoleId,totalHours - 接口/类型名: 使用
PascalCase,例如HuaweiCloudConfig,WorkHour - 常量: 使用
UPPER_SNAKE_CASE,根据语义决定
{
"semi": true, // 语句末尾添加分号
"singleQuote": true, // 使用单引号
"trailingComma": "es5", // ES5 兼容的尾随逗号
"printWidth": 100, // 每行最大 100 字符
"tabWidth": 2, // 缩进 2 空格
"useTabs": false, // 使用空格而非 Tab
"arrowParens": "always", // 箭头函数总是使用括号
"endOfLine": "lf", // 使用 LF 换行符
"bracketSameLine": false // 标签闭合符号单独一行
}- 严格模式:
"strict": true(启用所有严格类型检查) - 目标版本:
"target": "ES2020" - 模块系统:
"module": "commonjs" - 类型声明: 所有导出的函数和类必须包含类型声明
- 编译输出:
"outDir": "./dist","rootDir": "./src"
- 使用
@typescript-eslint/parser解析器 - 集成 Prettier(
plugin:prettier/recommended) - 规则:
@typescript-eslint/no-explicit-any:warn(谨慎使用 any)no-unused-vars:off(由 TypeScript 处理)prettier/prettier:error(Prettier 格式错误视为 ESLint 错误)
- 所有 API 请求和响应必须定义 TypeScript 接口
- 类型定义统一放在
src/types/index.ts - 使用
export interface导出所有类型
- 函数参数必须明确类型
- 函数返回值必须明确类型(尤其是
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);
}- 使用
?表示可选属性 - 使用
??或||提供默认值 - 优先使用解构赋值提供默认值
示例:
export interface HuaweiCloudConfig {
domainName: string;
enableLogging?: boolean; // 可选属性
}
constructor(config: HuaweiCloudConfig) {
this.enableLogging = config.enableLogging ?? false; // 提供默认值
}- 自定义字段优先使用枚举
CustomFieldId,不要使用字符串 'custom_filedxx'
- 所有异步函数使用
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)}`);
}- 捕获错误时使用
unknown类型 - 使用类型守卫判断错误类型(如
axios.isAxiosError(error)) - 对未知错误使用
String(error)转换
项目使用统一的 Logger 工具(src/utils/logger.ts)进行日志输出。
重要原则:
- ⛔ 禁止使用
console.log、console.error、console.warn等原生方法 - ✅ 必须使用
logger工具的方法进行所有日志输出
错误处理中使用 logger.error:
try {
// 业务逻辑
} catch (error: unknown) {
logger.error(`操作失败: ${String(error)}`);
throw error;
}禁止使用 console.error:
// ❌ 错误示例
console.error('操作失败');
// ✅ 正确示例
logger.error('操作失败');- 公共 API 必须使用 JSDoc 注释
- 注释包括:功能说明、参数说明、返回值说明
示例:
/**
* 通过角色ID获取项目成员
* @param projectId 项目ID
* @param roleId 角色ID
* @returns 指定角色的成员列表
*/
async getMembersByRoleId(projectId: string, roleId: number): Promise<ProjectMember[]> {
// 实现代码
}- 不要生成示例代码 - 除非用户明确要求,否则不生成使用示例
- 不要生成说明文档 - 不要在代码中生成冗长的文档注释
- 不要生成测试用例 - 除非用户明确要求,否则不生成测试代码
- 注释应该解释"为什么"而不是"是什么"
- 复杂逻辑必须添加注释说明
- ApiService: 封装华为云 CodeArts 的原始 API 调用
- BusinessService: 封装面向业务场景的高级操作
- 统一使用
ApiResponse<T>包装响应 - 响应结构:
interface ApiResponse<T> { success: boolean; data: T | null; message?: string; error?: string; }
- 使用接口定义复杂参数(如查询参数、请求体)
- 可选参数使用
?标记
项目使用配置文件,位于用户主目录:~/.hecom-codearts/config.env
使用前必须先运行 codearts config 进行配置。
配置优先级:命令行参数 > 配置文件
为保证类型安全,所有配置项的键名使用 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',
}-
不可变配置(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
- IAM 认证相关:
-
可变配置(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 参数:
--role <ids>: 角色 ID(支持逗号分隔)
注意:只有可变配置才能通过 CLI 参数覆盖。不可变配置必须通过 codearts config 命令设置。
- 不要硬编码: 使用配置文件
- 避免重复代码: 提取公共逻辑到独立函数
- 保持函数简洁: 单个函数不超过 50 行(建议)
- 使用解构赋值: 简化对象和数组操作
- 优先使用箭头函数: 保持
this上下文清晰 - 使用可选链:
?.和??简化空值处理 - 遵循 DRY 原则: Don't Repeat Yourself
- 使用 logger 工具: 禁止使用
console.log、console.error等原生方法
本文档版本: 2026-03-27
适用于: AI 编码代理(GitHub Copilot, Cursor, OpenCode 等)