Merge remote-tracking branch 'origin/dev-v3' into dev-v3
This commit is contained in:
193
AGENTS.md
Normal file
193
AGENTS.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# DataEase 开发规范
|
||||
|
||||
本文件适用于整个工作区,供开发者和编码代理共同遵守。子目录存在更具体的 `AGENTS.md` 时,优先遵循其局部约定;用户当前明确的任务范围优先。默认使用中文沟通,保留代码中的既有命名。
|
||||
|
||||
## 0. 产品版本、开源边界与协作分支
|
||||
|
||||
- 当前工作区是 DataEase 产品 **V3** 源码,以下仓库属性和协作规则由项目维护者明确指定。
|
||||
- 主仓库:`https://github.com/dataease/dataease`,是开源项目;遵循根目录 `LICENSE`,不要将其简化描述为没有附加条件的 GPLv3。
|
||||
- 子模块:`https://github.com/dataease/de-xpack`,**不是开源项目**。本地可见、存在 GitHub 地址或可作为插件加载,均不表示可以将其实现公开。
|
||||
- 不把 XPack 实现源码、专有资源或内部差异复制到开源主仓库、公开 PR/Issue 或公开文档;跨仓库协作通过必要的公共契约和兼容性说明完成,不能为解决构建缺失直接搬运专有实现。
|
||||
- 两个仓库的开发目标分支均为 `dev-v3`。主仓库通过 PR 合入,XPack 按维护者指定流程直接推送;具体步骤见第 8 节。旧文档中的 `dev-v2` 目标不适用于本工作区。
|
||||
|
||||
## 1. 工作原则
|
||||
|
||||
- 开始前读取相关代码及 `git status --short`,确认已有修改。只处理本次任务,不覆盖、回退、暂存或提交他人的改动。
|
||||
- 用户要求分析、审查或只读时,仅执行读取操作;不执行安装、格式化、构建、启动应用或可能写数据库的命令。
|
||||
- 沿现有调用链修复问题,优先最小且完整的改动。不顺带升级依赖、大范围重命名、格式化或抽象重构。
|
||||
- 先定位真实入口和所有调用方,再修改公共契约。不要根据目录名、旧文档或其他 DataEase 版本推断当前实现。
|
||||
- 版本、脚本、Profile、端口以当前 `pom.xml`、`package.json` 和配置文件为准;旧文档中的版本、完整构建说明和默认分支不作为事实依据。
|
||||
- 不读取或输出与任务无关的密码、Token、密钥、真实连接信息;日志和交付说明中的敏感信息应脱敏。
|
||||
- 普通局部开发按既有模式自行推进;涉及破坏性数据变更、范围不明的外部操作时,先说明具体影响并取得必要授权。不得擅自执行安装器、发布或部署。
|
||||
|
||||
## 2. 项目地图与依赖边界
|
||||
|
||||
| 位置 | 职责与修改边界 |
|
||||
| --- | --- |
|
||||
| `core/core-frontend` | Vue 3 / TypeScript / Vite 主前端,多页面与嵌入库入口 |
|
||||
| `core/core-backend` | Java 21 / Spring Boot 核心应用,业务编排与查询执行 |
|
||||
| `sdk/common` | 公共实体、认证基础、缓存、异常、响应、日志、国际化、迁移接口 |
|
||||
| `sdk/api/api-base` | 核心业务 API、DTO、请求和响应模型 |
|
||||
| `sdk/api/api-permissions` | 权限契约 |
|
||||
| `sdk/api/api-sync` | 同步契约 |
|
||||
| `sdk/extensions` | 图表、数据源、填报和同步扩展契约 |
|
||||
| `de-xpack/xpack-permissions` | 用户、组织、认证、资源权限、数据集权限等实现 |
|
||||
| `de-xpack/xpack-base` | 电子表格、报表、填报、阈值、日志等扩展功能 |
|
||||
| `de-xpack/xpack-sync` | 数据同步实现 |
|
||||
| `de-xpack/xpack-frontend*` | 扩展前端实现,是否参与构建以其 POM 为准 |
|
||||
| `installer`、`Dockerfile` | 安装、部署、容器编排和配置模板 |
|
||||
| `drivers`、`mapFiles`、`staticResource` | 驱动、地图及静态资源 |
|
||||
|
||||
- SDK 承载共享契约,不依赖 `core-backend` 的实现类;核心与 XPack 尽量通过既有 API/扩展契约协作,避免形成循环依赖。
|
||||
- `de-xpack` 是独立 Git 子模块。涉及它时,额外检查 `git -C de-xpack status --short` 和其差异;不要把子模块修改当成主仓库普通文件,也不要自动更新子模块指针或切换版本。
|
||||
- 根 Maven 当前只聚合 `sdk`;`core/pom.xml` 聚合前后端,`de-xpack/pom.xml` 单独聚合扩展。根目录 Maven 构建不代表整个产品构建完成。
|
||||
- `.gitignore` 包含后端、测试、文档和锁文件等路径,但其中部分文件已受 Git 跟踪。先用 `git ls-files` 核对;普通 `rg` 未找到时,在明确的源码目录使用 `rg --no-ignore`,并排除 `target`、`node_modules`、`dist` 等产物。
|
||||
- 不手工修改 `target/`、`dist/`、`.flattened-pom.xml`、生成的 QueryDSL Q 类或后端打包生成的 `resources/static/`。应修改生成它们的源码或构建配置。
|
||||
|
||||
## 3. 后端分层与接口规范
|
||||
|
||||
典型调用方向:`sdk API → server → manage → Repository / Provider`。
|
||||
|
||||
- `server/` 实现 SDK API,负责 HTTP 边界、参数校验和调用编排;可复用业务规则放入 `manage/` 或现有业务服务。
|
||||
- `dao/auto/`、`dao/ext/` 放持久化和查询相关代码。部分 `mapper` 目录实际使用 JPA,不得仅因目录名新增 MyBatis 实现。
|
||||
- 新增或修改接口时,同步检查 SDK 方法、请求/响应模型、实现类、前端封装、权限注解及扩展实现;保持现有路径和序列化兼容性。
|
||||
- 复用已有 `DEException`、错误码、统一响应和国际化机制,不新增平行的响应包装。不通过捕获所有异常并返回成功或空数据隐藏业务失败。
|
||||
- 数据库实体与 API 模型各司其职;避免直接暴露包含内部状态或敏感字段的实体。
|
||||
- 新增 Java 代码采用 4 空格缩进,沿用所在模块的注入与命名风格;JPA、Servlet、Validation 等使用 `jakarta.*`。不要批量替换所有 `javax.*`:JCache 当前仍使用 `javax.cache`,JDK 中的 `javax.sql` 等也不属于 Jakarta 迁移范围。
|
||||
- 对跨多次写入的业务操作明确事务边界;不要让外部数据源查询、网络调用和长时间导出无必要地占用元数据库事务。
|
||||
- JDBC 连接、结果集、文件流等资源必须可靠关闭;异步任务复用现有调度与生命周期管理机制。
|
||||
- 异步调用按需显式传递用户、组织及审计上下文,不假定请求上下文自动跨线程传播。使用 `IPUtils`、`CommunityUtils` 等 ThreadLocal 时,按现有生命周期在 `finally` 中清理,避免线程池复用串用上下文。
|
||||
|
||||
## 4. 持久化、字段更新与迁移
|
||||
|
||||
- 系统元数据主要使用 Spring Data JPA / QueryDSL。新逻辑沿用 JPA Repository、Specification 或 QueryDSL,不引入另一套 ORM。
|
||||
- 实体使用 `jakarta.persistence`,优先 `@Getter` / `@Setter`,避免对 JPA 实体直接使用可能引入关联递归的 `@Data`。新增表和字段补充含义、长度、可空性及必要注释。
|
||||
- 业务资源 ID 遵循现有 `Long` / `SnowflakeUtil` 约定,不擅自改为数据库自增。版本记录等特殊实体沿用自身规则。
|
||||
- 修改保存逻辑前阅读 `core/core-backend/src/main/java/io/dataease/config/JpaUpdateNonNullAspect.java`:它拦截 `save`、`saveAndFlush`、`saveAll`、`saveAllAndFlush`,对已存在实体合并非空属性。
|
||||
- 不假设向 `save()` 传 `null` 就能清空字段。需要清空时,用明确的 QueryDSL 更新或带 `@Modifying` 的 JPQL 等现有可控方式,在事务中执行,并验证持久化上下文和后续读取结果。区分“未提供字段”和“显式清空”。
|
||||
- 非空合并切面不等于并发控制或完整的 PATCH 语义;受管实体脏检查、批量更新和绕过 Repository 的路径需分别验证。`saveAll` 也会逐项尝试读取旧实体,批量操作应检查查询次数,不能直接假定只有一次批量 SQL。
|
||||
- 查询兼顾项目支持的数据库,留意大小写、保留字、布尔值、分页、日期和空值语义。数据库特有 SQL 必须进入现有方言/Provider 分支,不散落在通用业务代码中。
|
||||
- 数据库变更同时检查实体、QueryDSL 使用处和版本化 `SqlBlock`。`InitSqlListener` 会执行迁移,部分配置启用 `ddl-auto: update`;不能据此省略历史数据迁移和兼容设计。
|
||||
- 新迁移应具备安全重试能力,检查版本组、执行顺序、默认值和存量数据;不要改写已执行迁移来替代新增迁移。
|
||||
- 启动应用可能执行迁移并写入配置或业务数据。验证前确认使用隔离的开发/测试环境,不能为代码验证直接连接并改动生产或用户业务数据。
|
||||
|
||||
## 5. 数据查询、图表与权限
|
||||
|
||||
核心业务链:`数据源 → 数据集 → 图表 → 仪表板/大屏`。
|
||||
|
||||
图表取数阅读入口:
|
||||
|
||||
1. `core/core-frontend/src/api/chart.ts` 的 `getData()`。
|
||||
2. SDK `ChartDataApi` 与后端 `ChartDataServer`。
|
||||
3. `ChartDataManage.calcData()`:字段、数据集权限、行列权限、筛选和钻取编排。
|
||||
4. `chart/charts/` 中的 Handler、`engine/` 中的 SQL 转换逻辑及数据源 Provider。
|
||||
5. 前端 `views/chart/components/js/panel/` 中的渲染实现。
|
||||
|
||||
- 区分元数据持久化和分析数据查询;分析数据走既有 Provider / Calcite / JDBC 链路,不用元数据库 Repository 替代。
|
||||
- 图表类型专属计算优先放入对应 Handler;方言和连接相关行为放入对应 Provider;不要持续向公共编排方法堆叠类型分支。
|
||||
- 修改数据查询时保留字段编解码、计算字段、筛选、排序、聚合、钻取、行列权限和脱敏语义。导出、预览、嵌入与分享是否受影响必须检查。
|
||||
- SQL 值优先参数化;表名、字段名、排序等不能绑定的结构输入,应通过已有元数据、白名单和方言转义构造,不能直接拼接未校验输入。
|
||||
- 前端隐藏菜单或按钮不等于鉴权。后端必须检查实际资源、操作和访问身份;复用 `DePermit`、`DeLinkPermit` 及既有权限管理逻辑。
|
||||
- 权限变更同时审查 SDK 契约、核心调用、`substitute/permissions` 和 XPack 实现。保留条件 Bean 与版本差异,禁止用替补实现或默认放行掩盖权限失败。
|
||||
- 分享链接、嵌入 Token、管理员代理等访问上下文沿用现有传递与校验方式;缓存键应保留所需用户、组织、权限和筛选维度,防止跨身份复用结果。
|
||||
- 缓存复用 `DECacheService` / `CacheUtils`,检查写入后的失效路径及配置选用的实现。当前 JCache 在建缓存时设置过期策略,`expTime <= 0` 默认一分钟;Redis 按键设置过期,`expTime <= 0` 不设过期。不要假设两者 TTL 或对象引用语义相同;修改缓存对象前检查是否需要复制,缓存行为改动应覆盖实际支持的实现。
|
||||
- 资源 ID、权限编码、组件配置和图表类型属于持久化契约。修改时考虑旧仪表板、模板、复制和导入导出的兼容性。
|
||||
|
||||
## 6. 前端开发规范
|
||||
|
||||
- 使用 Vue 3 Composition API 和 TypeScript,沿用附近组件结构;复用现有组件、hooks、类型和工具,不为局部功能引入新的 UI 或状态管理体系。
|
||||
- 遵循前端 `.editorconfig`、`prettier.config.js` 和 ESLint 配置:2 空格缩进、单引号、不加尾分号。仅格式化本次改动范围。
|
||||
- UI 依赖沿用 `element-plus-secondary`,内部导入优先使用已有 `@/` 别名。不要无关替换路由包、UI 包或图表库。
|
||||
- HTTP 调用通过 `src/api/` 和 `src/config/axios/`,保留已有认证、HMAC、语言、分享/嵌入 Token、取消和错误处理;组件不另建绕过拦截器的 Axios 实例。
|
||||
- 跨页面共享状态放入既有 Pinia Store;局部临时状态留在组件或 composable。编辑器改动检查快照、撤销/重做、复制、组合、图层和锁定行为。
|
||||
- 编辑器区分需要重新取数的 `calcData` 和只需重绘的 `renderChart` 快照通知;沿用 `snapshot.ts` 的记录与刷新机制,避免样式变更引发无谓取数或绕过撤销/重做。
|
||||
- 新接口和复杂业务对象优先补齐类型;不要为消除报错扩大 `any` 或关闭类型检查。后端 `Long` ID 沿用既有传输和处理方式,避免未经确认转换成可能丢精度的 JavaScript 数字。
|
||||
- 新文案复用国际化机制并补充相关语言资源;不要在 i18n 尚未初始化的模块求值阶段捕获翻译函数。
|
||||
- 新增路由/菜单检查 `src/permission.ts`、权限 Store 和动态路由生成逻辑,不只修改静态路由表。
|
||||
- 修改共享页面或组件时,按影响范围核对主应用、`panel`、移动端和 `lib` 嵌入入口。
|
||||
- `config/pagesConfig.ts` 自动扫描非 `lib` 页面目录,多页面构建还需要对应 HTML 入口;新增页面时一起检查。`config/lib.ts` 将 Vue 设为外部依赖,嵌入库修改需验证宿主兼容性,不擅自打包第二份 Vue。
|
||||
- XPack 前端通过 `PluginComponent.vue` 等加载和桥接。修改组件映射、`jsname`、共享全局对象或调用方法时,同步核对扩展导出,并验证加载失败、无授权与加载完成前的方法调用;不能只验证开发模式下的一条加载路径。
|
||||
- JSON 行为以 `sdk/common` 的 `JacksonConfig` 和字段注解为准:当前默认保留空值,部分 ID 使用字段级字符串序列化。不得假设全局 Long 都转字符串,或为单个接口改动全局空值/数字规则。
|
||||
- 图表视觉改动在实际渲染层验证:尺寸、长文本、空数据、图例筛选、重复更新/缩放、事件解绑及销毁。不能仅凭配置对象正确就认定效果正确。
|
||||
- 渲染不可信富文本、URL 或 HTML 时复用现有净化机制;不得为展示效果关闭过滤。
|
||||
|
||||
## 7. 构建与验证
|
||||
|
||||
先选择最小但有意义的验证,再根据依赖影响扩大范围。纯文档或低风险样式改动不要求新增测试;查询、权限、迁移、字段更新等行为改动应尽量增加能复现问题的回归验证。
|
||||
|
||||
### 前端
|
||||
|
||||
以下命令在 `core/core-frontend` 执行,依赖需已安装:
|
||||
|
||||
| 命令 | 用途与边界 |
|
||||
| --- | --- |
|
||||
| `npm run ts:check` | TypeScript 检查;若存在基线问题,区分与本次改动的关系 |
|
||||
| `./node_modules/.bin/eslint <改动文件路径>` | 定向 lint,不加 `--fix`;占位符需替换为实际文件 |
|
||||
| `npm run dev` | 开发服务;当前配置端口 7070,代理后端 8100 |
|
||||
| `npm run build:base` | base 模式构建 |
|
||||
| `npm run build:distributed` | distributed 模式构建 |
|
||||
| `npm run build:lib` | 嵌入库构建 |
|
||||
|
||||
- `npm run lint` 和 `npm run lint:stylelint` 带自动修复,不能作为只读检查命令;避免造成无关文件改动。
|
||||
- `build:base` / `build:distributed` 会继续执行 `build:flush`,其中包含子目录依赖安装和文件生成。执行前确认副作用与任务范围一致。
|
||||
- 前端没有统一 `test` 脚本。饼图标签相关改动可按 `tests/pie-label-overflow/README.md` 使用现有 Vite 页面和 Playwright 验证;它不等于完整产品回归。
|
||||
- 不自动升级依赖或重建全部锁文件;新增依赖需说明必要性,并检查许可证、体积和实际跟踪的锁文件。
|
||||
|
||||
### 后端与整包
|
||||
|
||||
- 根目录 `mvn install` 用于当前聚合的 SDK 及父 POM;不会自动构建 `core` 和 XPack。
|
||||
- 完整核心应用可在依赖就绪后使用 `mvn -f core/pom.xml package -Pstandalone` 或任务所需的其他 Profile;这会触发前端构建及资源处理,不能用作轻量或只读检查。
|
||||
- 后端局部编译可使用 `mvn -f core/core-backend/pom.xml compile -Pstandalone`,前提是父 POM、SDK 和所需前端产物已就绪。Maven 生命周期可能复制资源、生成 Q 类和 flattened POM;它不是无副作用的语法检查。
|
||||
- `standalone` 默认启用;`desktop` 使用桌面配置;`distributed` 需要相应依赖并排除替补权限代码。以实际 POM 为准,不使用未定义的 Profile。
|
||||
- 前端 Maven 当前固定执行 `build:distributed`,不要认为后端 `-Pdesktop` 或 `-Pstandalone` 会自动切换前端模式。
|
||||
- 后端 Surefire 当前有显式 `<skip>true</skip>`。普通 `mvn test` 成功不代表测试执行;必须核对有效配置、实际日志和本次生成的测试报告。不要假定添加 `-DskipTests=false` 就能覆盖该配置。
|
||||
- 行为测试需要启用时,先确认可行的项目测试入口;若需调整构建配置,保持改动明确且符合任务范围。无法执行时说明原因,不把编译结果写成测试通过。
|
||||
- 不默认执行 `mvn clean`:前端 Maven clean 会清理依赖和锁文件,后端部分 Profile 会清理生成的静态资源。只在确实需要清理时使用。
|
||||
- 不直接修改已有 SDK 二进制或生成类来绕过编译错误;修复源码及依赖关系后重新生成。
|
||||
|
||||
### 验证覆盖选择
|
||||
|
||||
| 改动类型 | 优先验证 |
|
||||
| --- | --- |
|
||||
| API / DTO | 请求与响应兼容性、前端调用、核心和扩展实现编译 |
|
||||
| 权限 | 允许/拒绝、不同用户或组织、相关分享/嵌入路径、导出路径 |
|
||||
| 查询 / 图表计算 | 空值、筛选、排序、聚合、行列权限及受影响的数据源方言 |
|
||||
| JPA 更新 / 迁移 | 保留未提交字段、显式清空、事务失败、存量升级与失败重试 |
|
||||
| 编辑器 / 图表 UI | 实际渲染、重复交互、保存重开、相关移动端或嵌入入口 |
|
||||
| 部署 / Profile | 构建产物、资源位置、外置配置与目标运行模式 |
|
||||
|
||||
只声明实际验证过的环境和行为;未覆盖的数据库、入口或 Profile 明确列为限制。
|
||||
|
||||
## 8. Git、提交与交付
|
||||
|
||||
### DataEase 主仓库:PR 合入 dev-v3
|
||||
|
||||
- 开发目标为 `dev-v3`,交付时使用任务分支创建 PR,不直接推送主仓库 `dev-v3`。
|
||||
- 任务分支沿用维护者命名:`pr@dev-v3@fix_something`、`pr@dev-v3@perf_something`、`pr@dev-v3@chore_something`,后缀描述实际任务。PR base 明确为 `dev-v3`。
|
||||
- 提交消息遵循 `.github/PULL_REQUEST_TEMPLATE.md` 要求的 Conventional Commits,例如 `fix(chart): 修复标签越界`。分支命名与提交消息格式是两个不同约定。
|
||||
- 在已有工作区准备 PR 时,保留用户未提交/已暂存的内容;按具体路径选择本次修改,不使用全量暂存把无关变更带入 PR。
|
||||
|
||||
### de-xpack:直接同步 dev-v3
|
||||
|
||||
- 维护者已指定 XPack 可直接推送 `dev-v3`,不要求套用主仓库 PR 流程。在任务明确进入提交/推送阶段时按此执行,无需仅因“直推”再次征求相同许可;纯分析或规范维护任务不会因此自动触发 Git 发布。
|
||||
- 先检查子仓库分支、状态和本地待推送提交;确认本次代码已验证并提交、工作区适合 rebase、不会夹带其他任务的提交。不要擅自 stash、丢弃用户修改或在 detached HEAD 上盲目执行。
|
||||
- 在主仓库根目录依次执行以下命令;第一条成功且冲突已解决、验证完成后,才执行第二条:
|
||||
|
||||
```sh
|
||||
git -C de-xpack pull origin dev-v3 --rebase
|
||||
git -C de-xpack push origin dev-v3
|
||||
```
|
||||
|
||||
- rebase 冲突按双方业务意图解决,不机械采用整边覆盖。推送遇到非快进时重新同步并检查结果,不使用强制推送绕过远端更新;认证或网络错误应报告实际原因。
|
||||
- 本地 `origin` 可能采用 `fit2cloud.github.com` 等 SSH Host 别名;核对仓库身份即可,不为统一 URL 形式擅自改 remote。
|
||||
|
||||
### 跨仓库交付与检查
|
||||
|
||||
- 同时修改 SDK/主程序和 XPack 时,检查接口新旧版本兼容性,按依赖关系安排交付;XPack 直推与主仓库 PR 合并不是原子操作,不能让尚未合入的契约变更无说明地破坏另一仓库。
|
||||
- 需要更新主仓库的子模块指针时,先确认目标 XPack 提交已推送可获取,再将指针更新纳入主仓库 PR。只修改主仓库时,不顺带提交工作区中原有的子模块指针差异。
|
||||
|
||||
- 检查本次差异和 `git diff --check`;涉及子模块时单独检查其差异。忽略目录内的新文件要核实跟踪状态,不直接修改全局忽略规则或把生成物强制加入仓库。
|
||||
- 确认没有混入密码、业务数据、构建产物、依赖缓存或与任务无关的格式化修改。
|
||||
- 仅在任务包含提交/交付要求时暂存、提交或推送,按本节约定执行;已获得的授权持续有效。用户已有暂存内容保持原状,不擅自改写远端历史。
|
||||
- 完成说明应包含:解决的问题、主要修改文件、已运行的验证及结果、未验证项与原因。涉及 SDK/XPack、历史数据或配置迁移时说明影响。
|
||||
- PR 按实际问题和最终行为描述,遵循仓库模板,目标分支为维护者指定的 `dev-v3`;不要把计划中的验证写成已完成。两仓库的提交、推送和 PR 状态分别报告。
|
||||
Reference in New Issue
Block a user