From a89516a675dbd6805dfce97991b02c4821e4a0a4 Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 25 Aug 2025 13:57:34 +0800 Subject: [PATCH 1/2] + [misc] Init CLAUDE.md. --- CLAUDE.md | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..f3b9078d28 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,173 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Interactive +Always reply in Chinese. + +## Project Overview + +ZenTao is a comprehensive, open-source project management software written in PHP that covers the main PM process from product and project management to quality management, documentation management, organization management, and office management. It follows a modular MVC architecture pattern. + +## Architecture + +### Core Structure +- **framework/**: Core framework classes (control, model, router, helper) +- **module/**: Modular architecture with each module containing: + - `control.php` - Controller logic + - `model.php` - Data layer and business logic + - `zen.php` - New architecture layer (when present) + - `tao.php` - Extended business logic layer (when present) + - `config/` - Module-specific configuration + - `lang/` - Internationalization files + - `view/` - Traditional view templates + - `ui/` - Modern UI components + - `css/` and `js/` - Frontend assets +- **lib/**: Third-party libraries and utility classes +- **config/**: Global configuration files +- **www/**: Web entry point and public assets +- **db/**: Database schemas and migration scripts +- **extension/**: Extension system for customization + +### Database +- Uses MySQL/MariaDB with custom DAO layer in `lib/dao/` +- Database schemas in `db/` directory with versioned SQL files +- Supports multiple database engines including experimental DuckDB support + +### Frontend +- Mix of traditional PHP templates and modern UI components +- Uses ZUI framework (custom UI library) +- jQuery-based JavaScript +- CSS organized per module + +## Development Commands + +### Build System +```bash +# Full build process +make all + +# Clean build artifacts +make clean + +# Common build (core functionality) +make common + +# Package for distribution +make package + +# Create distribution packages +make pms # Standard package +make ci # CI build with all packages +``` + +### Testing +The project uses a custom testing framework located in `test/`: +```bash +# Run tests (navigate to test directory first) +cd test +php spider.php + +# UI testing configuration available in test/config/config.php +``` + +### Code Quality +- PHP compatibility checks via `misc/compatibility/` +- Downgrade scripts for PHP version compatibility in `misc/rector/` +- Code minification: `php misc/minifyfront.php` + +## Key Modules + +### Core Business Modules +- **product/**: Product management +- **project/**: Project management (includes execution/) +- **story/**: User story management +- **task/**: Task management +- **bug/**: Bug tracking +- **testcase/**: Test case management +- **build/**: Build management + +### Administrative Modules +- **user/**: User management +- **group/**: Permission groups +- **company/**: Organization management +- **dept/**: Department structure + +### Integration Modules +- **git/, gitlab/, gitea/, gogs/**: Source control integration +- **jenkins/**: CI/CD integration +- **api/**: API management +- **webhook/**: Webhook support + +### Reporting & Analytics +- **report/**: Standard reports +- **chart/**: Charting functionality +- **metric/**: Metrics calculation +- **bi/**: Business intelligence + +## Configuration + +### Database Configuration +- Main config: `config/config.php` +- Database settings typically in `config/my.php` (not tracked) + +### Extension System +- Custom extensions in `extension/custom/` +- Configuration extensions in `config/ext/` + +### Internationalization +- Language files in each module's `lang/` directory +- Supported languages: zh-cn, zh-tw, en, de, fr + +## File Patterns + +### Naming Conventions +- Controllers: `control.php` +- Models: `model.php` +- Views: `view/*.html.php` +- UI Components: `ui/*.html.php` +- Configurations: `config/*.php` +- Language files: `lang/{locale}.php` + +### Architecture Layers +- **zen.php**: New architecture implementation +- **tao.php**: Business logic extension layer +- Traditional MVC for legacy code + +## Development Notes + +### PHP Requirements +- Minimum PHP 5.6, supports up to PHP 8.1+ +- Uses strict types declaration in newer files +- Extensive use of custom framework classes + +### Security +- Custom authentication and authorization system +- Input filtering via `lib/filter/` +- SQL injection protection through DAO layer + +### Performance +- Built-in caching system in `lib/cache/` +- Database query optimization +- File-based session management + +## Common Tasks + +### Adding New Features +1. Create module directory structure in `module/` +2. Implement controller, model, and views +3. Add language files for internationalization +4. Configure routing if needed +5. Add database tables via SQL files in `db/` + +### Database Changes +1. Add migration SQL to `db/update*.sql` +2. Update schema in `db/zentao.sql` +3. Test with different database engines if needed + +### Testing Changes +1. Add test data to `test/data/` +2. Create test cases using the custom framework +3. Run compatibility checks for PHP versions + +This codebase represents a mature, enterprise-level project management system with extensive customization capabilities and multi-language support. From 1f6db9cd5e8ef268cb19b8a8d64176b004efd90c Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 25 Aug 2025 13:58:02 +0800 Subject: [PATCH 2/2] + [misc] Add 2 claude commands. --- .claude/commands/create-unit-test.md | 39 +++++++ .claude/commands/delete-view-files.md | 75 +++++++++++++ .claude/zendata.yaml | 150 ++++++++++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 .claude/commands/create-unit-test.md create mode 100644 .claude/commands/delete-view-files.md create mode 100644 .claude/zendata.yaml diff --git a/.claude/commands/create-unit-test.md b/.claude/commands/create-unit-test.md new file mode 100644 index 0000000000..a90f1dd82e --- /dev/null +++ b/.claude/commands/create-unit-test.md @@ -0,0 +1,39 @@ +请分析$ARGUMENTS[0]模块的$ARGUMENTS[1].php中的$ARGUMENTS[2]方法,帮我完善它的单元测试脚本。 +请遵循以下步骤: +1.当前的分支为开发分支。拉取开发分支的最新代码。 +2.使用测试分支完善单元测试脚本: + 2.1 测试分支命名规则为test/$ARGUMENTS[0]/$ARGUMENTS[1]/$ARGUMENTS[2]。 + 2.2 如果测试分支不存在则基于开发分支创建测试分支,如果测试分支存在则切换到测试分支。 + 2.3 后续工作全部在测试分支上完成。 +3.理解$ARGUMENTS[2]方法的业务逻辑。 +4.分析$ARGUMENTS[2]方法涉及的数据库表,获得每张表对应的字段和数据类型。表结构定义请参考db/zentao.sql。 +5.生成测试数据文件: + 5.1 测试数据文件使用yaml格式。 + 5.2 测试数据文件的语法定义请参考.claude/zendata.yaml。 + 5.3 测试数据文件的基本定义请参考test/data目录下的yaml文件。 + 5.4 生成测试数据文件时只需要定义必要的字段,测试框架会把生成的测试数据文件和基本定义文件合并。 + 5.5 测试数据文件生成到module/$ARGUMENTS[0]/test/$ARGUMENTS[1]/yaml/$ARGUMENTS[2]目录下。 + 5.6 测试数据文件的作者标记为Claude Code。 +6.生成测试数据: + 6.1 单元测试脚本中使用`zenData()->loadYaml()->gen()`加载测试数据文件来生成测试数据。 + 6.2 禁止使用调用zenData()方法返回PHP对象然后执行链式调用设置range的方式生成测试数据。 +7.生成单元测试步骤: + 7.1 使用r()、p()、e()方法生成单元测试步骤。 + 7.2 单元测试步骤要覆盖方法中的所有代码。 + 7.3 单元测试步骤不少于5条。 + 7.4 单元测试步骤的注释使用行尾注释。 +8.单元测试脚本保存路径为module/$ARGUMENTS[0]/test/$ARGUMENTS[1]/claude_$ARGUMENTS[2].php,文件名小写。 +9.生成单元测试脚本后使用php命令执行该脚本,如果有报错分析并修复。 +10.验证单元测试脚本: + 10.1 使用test/runtime/ztf执行脚本。 + 10.2 执行后输出结果通过数为1,失败数和忽略数为0表示单元测试通过。 + 10.3 如果单元测试没通过根据输出结果修复。 + 10.4 重复上述步骤直到单元测试通过。 +11.提交代码: + 11.1 单元测试脚本验证通过后提交代码到本地仓库。 + 11.2 提交代码时使用英文生成提交信息。 + 11.3 提交信息以"symbol [misc] "开头,如果本次提交只新增代码则symbol为+,只删除代码则symbol为-,否则为\*。 + 11.2 拉取开发分支的最新代码。 + 11.3 把测试分支变基到开发分支。 + 11.4 推送测试分支到远程仓库。 + 11.5 切换回开发分支。 diff --git a/.claude/commands/delete-view-files.md b/.claude/commands/delete-view-files.md new file mode 100644 index 0000000000..627a030714 --- /dev/null +++ b/.claude/commands/delete-view-files.md @@ -0,0 +1,75 @@ +## 角色定义 + +你是一个软件开发工程师,禅道项目管理软件的核心开发者。禅道项目管理软件经过一个大的重构,现在你将删除重构后不再需要保留的文件。 + +## 处理流程 + +1.编写一个php脚本处理这些工作。 +2.module目录下的每个一级目录代表一个模块。 +3.不处理ai、common、file、search和transfer模块。 +4.检查每个模块下是否同时存在view目录和ui目录,如果没有同时存在则不处理。 +5.检查每个模块下的view目录里的文件是否在当前模块下的ui目录中存在同名文件,如果存在则删除view目录下的文件。注意:sendmail.html.php文件除外。 +6.如果view目录里的文件被全部删除则删除view目录。 +7.解析模块名和方法名的中文名称: +- 目录名代表模块名,文件名中除去.html.php外的部分代表方法名。 +- 读取common目录下的lang目录中的zh-cn.php文件的内容。 +- 读取每一个目录下的lang目录中的zh-cn.php文件的内容。 +- 读取文件时可能遇到一些未知的PHP变量,下面是一部分参考: + - $lang->ERCommon = '业务需求' + - $lang->URCommon = '用户需求' + - $lang->SRCommon = '软件需求' + - $lang->productCommon = '产品' + - $lang->projectCommon = '项目' + - $lang->executionCommon = '执行' + - $lang->execution->common = '执行' + - $lang->mr->common = '合并请求' + - $lang->common->story = '需求' +- 模块名的中文名称在语言文件中的定义为'$lang->模块名->common'。 +- 方法名的中文名称在语言文件中的定义为'$lang->模块名->方法名'。 +- 把读取到的语言项定义转换为小写后和文件名比对,两者一致时语言项定义即为方法名的中文名称。 +- 以task模块为例: + - 模块名为'task',在common/lang/zh-cn.php中存在定义"$lang->task->common = '任务';",则模块名的中文名称为'任务'。 + - view目录下的文件名为'create.html.php',则方法名为'create',在task/lang/zh-cn.php中存在定义'$lang->task->create = "建任务";',则方法名的中文名称为'建任务'。 + - view目录下的文件名为'batchcreate.html.php',则方法名为'batchcreate',在task/lang/zh-cn.php中存在定义'$lang->task->batchCreate = "批量创建";',则方法名的中文名称为'批量创建'。 +- block模块以block结尾的方法名需要特殊处理: + - block模块lang目录下的zh-cn.php中定义了数组$lang->block->default。 + - 提取该数组每一行定义的元素的title和code。 + - 把code和'block'拼接后和方法名匹配,如果匹配成功以title作为方法名的中文名称。 + - 以block模块view目录下的projectdynamicblock.html.php文件为例: + - 方法名为'projectdynamicblock'。 + - 在block/lang/zh-cn.php中存在定义"$lang->block->default['waterfallproject'][] = array('title' => '最新动态', 'module' => 'waterfallproject', 'code' => 'projectdynamic', 'width' => '1');",提取到title='最新动态',code='projectdynamic'。 + - code和'block'拼接后和方法名一致,则方法名的中文名称为'最新动态'。 +- 如果没有解析到模块名和方法名的中文名称,需要询问我如何处理。 +8.输出一个csv文件到/tmp目录下: +- 文件内容支持中文显示,文件名以'YYYYmmdd_HHiiss'格式包含当前日期和时间。 +- 分别列出删除的模块名、方法名、模块名的中文名称、方法名的中文名称和被删除文件在本项目中的相对路径。 +- 文件内容中如存在以下内容需要替换: + - '$lang->SRCommon'替换为软件需求'。 + - '$lang->productCommon'替换为'产品'。 + - '$lang->executionCommon'替换为'执行'。 + - '$lang->execution->common'替换为'执行'。 + - '$lang->URCommon'替换为'用户需求'。 + - '$lang->mr->common'替换为'合并请求'。 + - '$lang->projectCommon'替换为'项目'。 + - '{'、'}'、' '、'.'、'"'和"'"替换为空。 +9.输出php脚本的路径和csv文件的路径。 + +## 调试模式 + +在脚本中添加详细的调试输出,显示解析过程 + +## 测试验证 + +在生成最终报告前,先测试几个已知模块的解析结果 + +## 错误处理 + +当解析失败时提供更清晰的错误信息 + +## 日志记录 + +记录解析过程中的异常情况 + +## 清除临时文件 + +处理过程中生成的脚本和csv文件可以保留,其他临时文件应该删除。 diff --git a/.claude/zendata.yaml b/.claude/zendata.yaml new file mode 100644 index 0000000000..a64d8cd5b2 --- /dev/null +++ b/.claude/zendata.yaml @@ -0,0 +1,150 @@ +title: zendata数据配置语法说明 +desc: + +# 文件组成 + +# zendata以yaml格式的文件来定义各个字段的格式。 +# yaml文件整体由文件说明和字段定义两部分组成。 + +# 文件说明 + +# title: 标题,可以用简短的文字概要描述该文件定义的数据类型。 +# desc: 描述,可以用多行文本来详细描述该文件定义的数据类型,非必选项。 +# author: 作者,非必选项。 +# version:版本号,非必选项。 + +# 字段列表 + +# 字段定义部分都放在fields这个定义里面。 +# 一个yaml文件可以包含一个或者多个字段。 +# 字段列表以-field定义开始。 +# 一个字段可以通过fields属性定义它的子字段。 + +# 字段定义 + +# field: 字段名,仅支持英文、数字、下换线和. +# range: 列表范围,最重要的定义。 +# loop: 循环次数,可以定义某一字段循环多少次。 +# loopfix: 每一次循环时的连接符。 + +# format: 支持格式化输出。 + +# prefix: 该字段的前缀。 +# postfix: 该字段的后缀。 + +# length: 该字段的长度。如果不通过分隔符区分,则需要指定字段长度,单位是字节。 +# leftpad: 左填充的字符。如果长度不够,可指定左填充的字符。默认是以空格左填充。 +# rightpad: 右填充的字符。如果长度不够,可指定右填充的字符。 + +# config: 可以引用另外一个文件里面的定义。 + +# from: 引用某一个定义文件。 +# use: 使用被引用文件中定义的若干实例。all代表使用所有。 +# select: 如果引用的文件是excel表,可以查询里面的某一个字段。 +# where: 如果引用的文件是excel表,可以使用查询条件。 + +# loop定义 + +# 可以使用一个数字来指定字段循环的次数,比如loop:2。 +# 可以使用区间来定义字段循环的次数。比如loop:2-10。 + +# range定义 + +# 使用逗号连接不同的元素。比如 range: 1,2,3。 +# 元素也可以是一个区间。比如 range:1-10, A-Z。 +# 区间可以通过冒号:来指定步长。比如 range:1-10:2。 +# 步长可以是小数。比如 range: 1-10:0.1。 +# 步长可以是负数。比如 range:100-1:-1。 +# 区间可以通过R来指定随机。比如 range: 1-10:R,随机和步长只能二选一。 +# 可以通过一个文件来指定列表。比如range: list.txt。文件名是相对路径时,以配置文件为基准计算。 +# 可以通过{n}的方式来重复某一个元素。比如 range: user1{100},user2{100} +# 如果区间或者几个元素需要重复,需要用[]括起来。比如 range: [user1,user2,user3]{100} + +author: zentao +version: 1.0 + +fields: + + - field: field_common # 默认的列表类型,通过逗号隔成若干区间。 + range: 1-10, 20-25, 27, 29, 30 # 1,2,3...,10,20,21,22...,25,27,29.30 + prefix: "" # 前缀 + postfix: "\t" # 后缀,特殊字符加引号,否则无法解析。 + + - field: field_step # 区间指定步长。 + range: 1-10:2, 1-2:0.1 # 1,3,5,7,9,1, 1.1,1.2...,2 + postfix: "\t" + + - field: field_random # 区间指定随机。随机属性R同步长不能同时出现。 + range: 1-10:R # 1,5,8... + postfix: "\t" + + - field: field_loop # 自循环的字段。 + range: a-z # a|b|c ... + loop: 3 # 循环三次 + loopfix: _ # 每次循环的连接符。 + postfix: "\t" + + - field: field_repeat # 通过{}定义重复的元素。 + range: user-1{3},[user2,user3]{2} # user-1,user-1,user-1,user2,user2,user3,user3 + postfix: "\t" + + - field: field_format # 通过格式化字符串输出。 + range: 1-10 # passwd 1,passwd 2,passwd 3 ... passwd10。 + format: "passwd%02d" # 用%02d补零,使密码整体保持8位。 + postfix: "\t" + + - field: field_length # 指定宽度。 + range: 1-99 # 01\t,02\t,03\t..., 99\t + length: 3 # 包含前后缀的宽度。 + leftpad: 0 # 宽度不够时,补充的字符。 + postfix: "\t" + + - field: field_text # 从一个文件中随机读取。 + range: users.txt:R # 相对当前文件路径。 + postfix: "\t" + + - field: field_yaml # 引用其他的定义文件整体内容。 + range: test/test-nested2.yaml{3} # 相对当前文件路径。 + postfix: "\t" + + - field: field_use_config # 引用其他的config定义文件。 + config: number.yaml # 相对当前文件路径,config内包含单个字段。 + postfix: "\t" + + - field: field_use_ranges # 引用內置的定义文件,该文件定义了多个range,他们共享了一些field层面的属性。 + from: zentao.number.v1.yaml # 引用yaml/zentao/number/v1.yaml文件里面的ranges定义。 + use: medium # 使用该文件中定义的medium分组。 + postfix: "\t" + + - field: field_use_instance # 引用其他的定义文件,该文件定义了多个实例。 + from: ip.v1.yaml # yaml/ip/v1.yaml + use: privateC,privateB # 使用该文件中定义的privateC和privateB两个实例。 + postfix: "\t" + + - field: field_use_excel # 从excel数据源里面取数据。 + from: address.cn.v1.china # 从data/address/v1.xlsx文件中读取名为china的工作簿。 + select: city # 查询city字段。 + where: state like '%山东%' # 条件是省份包含山东。 + rand: true # 随机取数据 + postfix: "\t" + + - field: field_with_children # 字段多层嵌套 + fields: + - field: child1 + range: a-z + prefix: part1_ + postfix: '|' + + - field: child2 + range: A-Z + prefix: part2_ + postfix: '|' + + - field: child_with_child + prefix: part3_ + postfix: + fields: + - field: field_grandson + prefix: int_ + range: 10-20 + postfix: