mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
docs(agents): add agent guidance suite (AGENTS.md, CONTEXT.md, docs/agents)
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# SQLBot Agent 指南
|
||||
|
||||
SQLBot 让业务用户用自然语言提问,基于已配置的数据源生成并安全执行 SQL,返回数据、图表、分析和后续问题建议。领域词汇表见 `CONTEXT.md`。
|
||||
|
||||
## 仓库结构
|
||||
|
||||
| 路径 | 职责 |
|
||||
| --- | --- |
|
||||
| `backend/` | Python 3.11 / FastAPI / SQLModel 后端。`main.py` 组装应用、MCP、中间件、静态资源和 xpack;业务域在 `apps/`,共享代码在 `common/`,迁移在 `alembic/versions/`,全部测试(含仓库守卫)在 `tests/`。 |
|
||||
| `frontend/` | Vue 3、TypeScript strict、Vite、Pinia、Vue Router 和 Element Plus。请求在 `src/api/`,共享实体在 `src/entity/`,状态在 `src/stores/`,路由在 `src/router/`,UI 在 `src/views/` 和 `src/components/`。 |
|
||||
| `g2-ssr/` | Node.js 图表渲染服务,使用 `@antv/g2-ssr`;图表实现位于 `charts/`,目录内有独立 `AGENTS.md`。 |
|
||||
| `installer/` | 离线安装、卸载、配置模板和服务控制脚本。 |
|
||||
| `Dockerfile*`、`docker-compose.yaml`、`start.sh` | 容器组装和运行时进程启动。 |
|
||||
|
||||
商业扩展源码维护在独立仓库 [dataease/sqlbot-xpack](https://github.com/dataease/sqlbot-xpack)。它不是 submodule,也不是本仓库的固定子目录。本地 `sqlbot-xpack/` checkout 会被主仓库忽略,永远不应出现在本仓库 PR 中。
|
||||
|
||||
## xpack 工作流
|
||||
|
||||
默认使用开源版 SQLBot 工作流:把 `sqlbot-xpack` 视为版本范围由 `backend/pyproject.toml` 约束的已发布 wheel(精确版本冻结在不入库的 `uv.lock`)。不读取、不修改本地 xpack checkout。
|
||||
|
||||
只有任务确实需要修改或调试闭源 xpack 代码,或需要两个仓库联动验证时,才按 `docs/agents/xpack.md` 检查本地关联开关(`AGENTS.local.env`)并协调两个仓库的变更。
|
||||
|
||||
## 按需文档
|
||||
|
||||
| 触发条件 | 必读文档 |
|
||||
| --- | --- |
|
||||
| 修改业务逻辑、数据模型(SQLModel)、权限、Chat 问题流程、助手集成、前端信息架构,或需要命名和领域术语 | `CONTEXT.md` |
|
||||
| 修改后端业务代码 | `docs/agents/backend.md` |
|
||||
| 修改前端代码 | `docs/agents/frontend.md` |
|
||||
| 修改或新增测试、执行验证 | `docs/agents/testing.md` |
|
||||
| 修改用户可见文案或新增语言 | `docs/agents/i18n.md` |
|
||||
| 修改认证、授权、SQL 执行、上传/下载、嵌入协议或前端渲染安全 | `docs/agents/security.md` |
|
||||
| 修改 SQLModel 模型或 Alembic 迁移 | `docs/agents/migrations.md` |
|
||||
| 修改 Dockerfile、installer、GitHub Actions 或发布产物 | `docs/agents/packaging.md` |
|
||||
| 修改或调试闭源 xpack 代码、双仓库联动验证 | `docs/agents/xpack.md` |
|
||||
| 修改图表渲染服务、后端图表配置或图表字段/输出契约 | `g2-ssr/AGENTS.md` |
|
||||
| 领域边界仍不明确 | `docs/agents/domain-open-questions.md`,并向使用者确认 |
|
||||
|
||||
## 全局硬规则
|
||||
|
||||
- 在正确仓库检查 status/diff;SQLBot 主仓库和 xpack 独立仓库不要混出同一个提交。
|
||||
- 不要提交日志、构建产物、`.env` 值、密钥、本地路径、私有 registry 配置或生成的 xpack 产物。
|
||||
- 提交信息和 PR 描述不添加 `Co-Authored-By`、"Generated with" 等任何 AI 工具署名行。
|
||||
- 提交信息沿用仓库既有 conventional 风格:`fix:`、`feat:`、`refactor:` 等前缀(可带 scope),单行概述。
|
||||
- 不要为了通过测试削弱安全守卫;安全、权限、SQL、Host、路径和嵌入认证改动必须有相关回归验证。
|
||||
- 修改 Docker、installer 或路径配置时,核对前端构建产物、后端工作目录、`/opt/sqlbot` 数据目录、图表输出和日志挂载仍然一致。
|
||||
- 依赖、lockfile 和版本号只在任务明确需要时更新;不要顺手刷新。
|
||||
- 验证以构建和测试为准;除非用户明确要求,不构建 Docker 镜像、不启动完整运行栈。
|
||||
- 除非用户明确要求,不要上传、发布或推送镜像 / wheel / 包。
|
||||
- 变更涉及本文件或 `docs/agents/` 描述的约定(目录职责、命令、流程)时,同步更新对应文档。
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# SQLBot
|
||||
|
||||
SQLBot 让业务用户用自然语言提问,基于已配置的数据源生成并安全执行 SQL,然后返回数据、图表、分析和后续问题建议。
|
||||
|
||||
## Language
|
||||
|
||||
### 工作空间与数据
|
||||
|
||||
**Workspace / 工作空间**:
|
||||
用户、会话、数据源、模型等 SQLBot 资源的隔离边界。
|
||||
_Avoid_: Organization、tenant
|
||||
|
||||
**Workspace ID / 工作空间 ID**:
|
||||
工作空间的标识。历史上的 `oid` 和 `workspace_id` 字段表示同一个概念。
|
||||
_Avoid_: 把 `oid` 理解成独立的组织概念
|
||||
|
||||
**Datasource / 数据源**:
|
||||
已配置的外部数据源,以及 SQLBot 用于生成查询的表、字段、关系和 embedding 等元数据。
|
||||
_Avoid_: Database、connection
|
||||
|
||||
**SQL Example / SQL 示例**:
|
||||
用于引导 SQL 生成的“问题 + SQL”示例。
|
||||
_Avoid_: Data training、training data
|
||||
|
||||
**Terminology / 术语**:
|
||||
业务词或短语的解释,可包含同义词,用于提升问题和表结构理解。
|
||||
_Avoid_: Custom prompt、SQL example
|
||||
|
||||
**Custom Prompt / 自定义提示词**:
|
||||
附加在模型任务上的场景指令,可按工作空间、数据源或助手场景生效。
|
||||
_Avoid_: Terminology、SQL example
|
||||
|
||||
### 会话
|
||||
|
||||
**Chat / 会话**:
|
||||
用户在一个工作空间内连续提出数据问题的对话。
|
||||
_Avoid_: Assistant、dashboard
|
||||
|
||||
**Chat Record / 会话记录**:
|
||||
一次问题执行的可持久化结果,包含问题、生成 SQL、查询结果、图表配置、错误以及关联的后续记录。
|
||||
_Avoid_: Chat
|
||||
|
||||
**Analysis / 分析**:
|
||||
基于既有问题结果的模型生成解读。
|
||||
_Avoid_: Prediction
|
||||
|
||||
**Prediction / 预测**:
|
||||
基于既有问题结果的模型生成前瞻性估计。
|
||||
_Avoid_: Analysis
|
||||
|
||||
**Recommended Problem / 推荐问题**:
|
||||
与数据源关联的已配置问题。
|
||||
_Avoid_: Guess question
|
||||
|
||||
**Guess Question / 猜测问题**:
|
||||
由模型根据会话上下文推测的后续问题。
|
||||
_Avoid_: Recommended problem
|
||||
|
||||
### 助手与集成
|
||||
|
||||
**Assistant / 助手**:
|
||||
把 SQLBot 问数能力暴露给外部系统的集成配置。
|
||||
_Avoid_: Chat
|
||||
|
||||
**Ordinary Assistant / 普通小助手**:
|
||||
标准的小助手集成形态。
|
||||
_Avoid_: Advanced assistant、page-embedded assistant
|
||||
|
||||
**Advanced Assistant / 高级应用**:
|
||||
面向更深集成场景的高级小助手形态。
|
||||
_Avoid_: Ordinary assistant、page-embedded assistant
|
||||
|
||||
**Page-embedded Assistant / 页面嵌入助手**:
|
||||
用于把 SQLBot 页面嵌入目标系统的小助手形态。
|
||||
_Avoid_: Ordinary assistant、advanced assistant
|
||||
|
||||
**Assistant Domain / 助手目标域名**:
|
||||
小助手对接的外部目标系统域名。
|
||||
_Avoid_: Business domain、workspace
|
||||
|
||||
**Dashboard / 仪表板**:
|
||||
为重复分析保存的数据视图集合。
|
||||
_Avoid_: Chat、chat record
|
||||
@@ -0,0 +1,98 @@
|
||||
# 后端 Agent 说明
|
||||
|
||||
## 领域与代码映射
|
||||
|
||||
- `oid` 和 `workspace_id` 是同一个工作空间 ID 的历史命名。
|
||||
- `AssistantModel.type`:
|
||||
- `0`:普通小助手;
|
||||
- `1`:高级应用;
|
||||
- `4`:页面嵌入。
|
||||
- `AssistantModel.domain` 表示对接目标系统的域名,不是业务领域。
|
||||
- `DataTraining` 是「SQL 示例库」概念的持久化命名。
|
||||
|
||||
## 代码组织
|
||||
|
||||
- 领域代码放在 `backend/apps/<domain>/`。多数域采用 `api/`、`crud/` 或 `curd/`、`models/` 分层;`schemas/` 仅 `system` 和 `settings` 有,`chat` 另有 `task/`,`ai_model`、`db`、`mcp`、`template`、`swagger` 不遵循该布局——新代码跟随所在域的既有形态。
|
||||
- 项目同时存在 `crud` 和 `curd` 拼写;不要为统一命名制造无关重构。
|
||||
- 新 router 注册到 `backend/apps/api.py`。
|
||||
- 应用组装、中间件、MCP、静态资源挂载和 xpack 初始化属于 `backend/main.py`。
|
||||
- SQLModel 结构变更必须配套 Alembic 迁移;细节见 `docs/agents/migrations.md`。
|
||||
- 用户可见后端消息使用 `backend/locales/`,不要硬编码新文案。
|
||||
|
||||
## API 黄金路径
|
||||
|
||||
新 endpoint 参考 `terminology`、`data_training` 域和 `datasource` 域内的 `recommended_problem` 模块(`backend/apps/datasource/api/recommended_problem.py`)的分层:
|
||||
|
||||
1. 在 `api/<domain>.py` 定义 router、prefix、tags 和 Swagger summary;
|
||||
2. 使用 `SessionDep`、`CurrentUser`、`Trans` 等依赖注入;
|
||||
3. 资源型接口配置 `@require_permissions`,确认 `keyExpression` 指向真实资源;
|
||||
4. 需要审计的操作配置 `@system_log`,新代码优先让权限装饰器位于审计装饰器外层,只记录已授权操作;
|
||||
5. handler 只做参数解析、权限上下文提取和分支,业务规则下沉到 CRUD/service;
|
||||
6. 返回领域对象、DTO 或既有分页 dict;正常 JSON 由 `ResponseMiddleware` 包装,不要手工包一层 `code/data/msg`;
|
||||
7. 用户可见异常通过 `Trans` 使用 locale key;`HTTPException` 留在 API 层,不要让 CRUD 依赖 FastAPI 响应细节。
|
||||
|
||||
Endpoint 命名沿既有风格:
|
||||
|
||||
- 分页:`GET /page/{current_page}/{page_size}`;
|
||||
- 新增或更新:`PUT ""`,按 `info.id` 分支;
|
||||
- 删除:`DELETE ""`,传 ID 列表;
|
||||
- 启用/禁用:`GET /{id}/enable/{enabled}`;
|
||||
- 导出:`GET /export`;
|
||||
- 导入:`POST /uploadExcel`。
|
||||
|
||||
只在确实与现有 API 兼容性冲突时发明新形态,并说明原因。
|
||||
|
||||
## CRUD 与查询
|
||||
|
||||
- 查询构建参考 `build_<entity>_query` 的分层:
|
||||
1. `get_<entity>_base_query` 构造工作空间过滤;
|
||||
2. `build_<entity>_query` 追加搜索、作用域、join、count 和分页;
|
||||
3. `execute_<entity>_query` 转换为 DTO/result;
|
||||
4. `page_<entity>` 返回 API 需要的分页元数据。
|
||||
- 默认过滤当前 `current_user.oid`;管理员或助手场景必须显式说明为何可以切换工作空间。
|
||||
- 使用 SQLAlchemy `select` / `and_` / `or_` 表达查询;不要为用户输入拼接 SQL 字符串。
|
||||
- 分页先 count,再计算 `total_pages`,最后构造 offset/limit 子查询。
|
||||
- 创建/更新前完成重复性、必填和作用域校验;不要先写入再依赖唯一约束报错。
|
||||
- 事务提交通常发生在 CRUD/service 边界;API handler 不要随意中途 commit。
|
||||
- embedding、缓存清理或后台任务沿用当前领域的线程任务模式,不在请求路径中阻塞等待长任务。
|
||||
|
||||
## 异步与阻塞
|
||||
|
||||
- FastAPI handler 可以是 `async def`,但不要在事件循环中执行外部 HTTP、pandas 大文件解析、CPU 密集转换或长时间文件 IO。
|
||||
- 这些操作参考现有 `asyncio.to_thread(inner)` 模式。
|
||||
- 数据库 session 由依赖注入管理;在线程中需要新 session 时使用对应 `session_maker()` 并确保清理。
|
||||
- 不要把 `asyncio.to_thread` 当成绕过权限或事务边界的手段。
|
||||
|
||||
## 模型与 DTO
|
||||
|
||||
- 表模型继承 `SQLModel, table=True`;输入/输出 DTO 使用 Pydantic BaseModel 或非 table SQLModel。
|
||||
- 大 ID 使用 `BigInteger`;返回给前端时按既有 DTO 规则处理超过 JavaScript 安全整数的情况。
|
||||
- 时间、启用状态、工作空间归属和高级应用/数据源作用域要显式建模,不依赖调用方隐式状态。
|
||||
- 新增字段同时考虑迁移、导入/导出、embedding、缓存和 xpack 调用。
|
||||
|
||||
## 安全与事务边界
|
||||
|
||||
- 保留认证、工作空间/数据源权限、审计日志和既有错误响应模式;不要在 handler 中绕过它们。
|
||||
- 生成 SQL、路径、Host 头和上传文件都按不可信输入处理。
|
||||
- 不要削弱行数限制、权限过滤、元数据查询控制、Host 校验或路径穿越防护。
|
||||
- 修改连接池、事务和异步执行边界时,先阅读相邻实现和回归测试;不要把阻塞调用移回事件循环。
|
||||
- 商业实现留在 xpack;本仓库只保留对已发布包的调用和初始化。
|
||||
|
||||
## Chat 问题流程
|
||||
|
||||
主要入口在 `backend/apps/chat/api/chat.py`:
|
||||
|
||||
1. `POST /chat/start` 与 `POST /chat/assistant/start` 在工作空间内创建会话,并可绑定初始数据源或助手上下文。
|
||||
2. `POST /chat/question` 先解析快速命令。普通问题进入 `stream_sql`;`/regenerate` 直接再生。`/analysis` 和 `/predict` 在会话内会直接拒绝(temporary not supported),实际通过 `POST /record/{chat_record_id}/{action_type}` 触发。
|
||||
3. `stream_sql` 构造 `LLMService`,创建 `ChatRecord`,并启动异步执行。
|
||||
4. 已绑定数据源时,服务先提取关键词并扩展术语,再筛选适用的术语、SQL 示例和自定义提示词,随后组装 SQL 消息。
|
||||
5. 未绑定数据源时,先由模型选择数据源;服务随后校验数据源访问权和连接可用性。
|
||||
6. 模型生成 SQL 后,服务解析 SQL、对照允许的表元数据校验引用表,并按需应用行权限或助手动态 SQL 变换。
|
||||
7. 服务执行最终 SQL,规范化大数字和带限定名的列结果,并持久化查询结果。
|
||||
8. 模型基于实际使用的表结构生成图表配置;服务校验并持久化配置。非会话式流式调用还可请求渲染图片。
|
||||
9. 分析和预测是基于既有图表记录的独立后续执行。
|
||||
10. 猜测问题与已配置的推荐问题分开生成。
|
||||
|
||||
`ChatFinishStep` 允许一次执行在生成 SQL、查询数据或生成图表后停止。不要假设所有调用方都需要完整图表流程。
|
||||
|
||||
验证要求与测试选择标准见 `docs/agents/testing.md`。
|
||||
@@ -0,0 +1,64 @@
|
||||
# 领域文档待补充问题
|
||||
|
||||
这份文件只记录尚未确认的领域边界。问题确认后,把稳定术语移入根目录 `CONTEXT.md`,再从本文删除对应问题。
|
||||
|
||||
## 工作空间与用户
|
||||
|
||||
- 用户在工作空间中的角色如何定义?`UserWsModel.weight` 的取值和含义是什么?
|
||||
- 系统管理员、工作空间管理员、普通用户、数据源管理员之间的权限边界是什么?
|
||||
- 用户是否可以同时属于多个工作空间?切换工作空间对会话、数据源、模型和助手上下文有什么影响?
|
||||
|
||||
## 数据源与元数据
|
||||
|
||||
- 数据源的完整生命周期是什么?创建、连接校验、元数据同步、启用/禁用、删除分别如何界定?
|
||||
- Excel 数据源在领域上是普通数据源的一种,还是有独立生命周期和限制?
|
||||
- 表关系、表备注、字段备注、embedding 的业务含义和维护责任分别是什么?
|
||||
- 高级应用动态数据源与普通数据源在领域上的差异是什么?
|
||||
|
||||
## 知识增强
|
||||
|
||||
- 术语、SQL 示例、自定义提示词的作用域规则是否完全一致?
|
||||
- 当同一问题命中多个术语、多个 SQL 示例或多个自定义提示词时,选择和组合规则是什么?
|
||||
- embedding 相似度、关键词匹配和高级应用/数据源绑定之间的优先级是什么?
|
||||
|
||||
## 权限
|
||||
|
||||
- 工作空间权限、数据源权限、行权限、列权限、API 权限如何叠加?
|
||||
- 权限冲突时使用交集、并集还是显式拒绝优先?
|
||||
- 页面嵌入、高级应用和 MCP 场景下的用户身份与数据权限如何映射?
|
||||
|
||||
## 助手与集成
|
||||
|
||||
- `AssistantModel.type` 目前确认 `0` 普通小助手、`1` 高级应用、`4` 页面嵌入;是否还有其他历史值或保留值?
|
||||
- 普通小助手、高级应用、页面嵌入在目标系统认证、数据源获取和页面能力上的完整差异是什么?
|
||||
- `app_id`、`app_secret`、`domain` 与目标系统信任关系如何建模?
|
||||
|
||||
## Chat 流程与产物
|
||||
|
||||
- `Chat.chat_type`、`Chat.origin`、`first_chat`、`regenerate_record_id` 等状态字段的完整业务含义是什么?
|
||||
- 分析记录、预测记录和普通问答记录的生命周期与展示关系是什么?
|
||||
- 生成失败、执行失败、图表失败时,`ChatRecord` 的最终状态如何界定?
|
||||
- 猜测问题和推荐问题在产品展示上是否使用相同入口?二者是否需要统一命名?
|
||||
|
||||
## 模型配置
|
||||
|
||||
- 供应商、模型类型、基础模型、模型名称、默认模型、工作空间映射之间的准确关系是什么?
|
||||
- 系统默认模型和工作空间可用模型的决策顺序是什么?
|
||||
- 自定义模型在助手和 MCP 场景中的约束是什么?
|
||||
|
||||
## 仪表板
|
||||
|
||||
- 仪表板只能由会话图表创建,还是也可以独立创建和编辑?
|
||||
- 仪表板组件、会话记录、图表配置之间的归属关系是什么?
|
||||
- 仪表板查看和编辑权限如何与工作空间、数据源权限叠加?
|
||||
|
||||
## MCP 与嵌入
|
||||
|
||||
- MCP 调用者、工作空间和数据源之间的授权关系是什么?
|
||||
- 页面嵌入、小助手嵌入、MCP 在产品分类上的边界是什么?
|
||||
|
||||
## xpack 商业概念
|
||||
|
||||
- 许可证能力项、版本限制和功能开关如何影响领域对象?
|
||||
- 认证源、平台集成、审计日志和商业权限的领域边界是什么?
|
||||
- xpack 侧是否需要独立 `CONTEXT.md` 来维护商业扩展术语?
|
||||
@@ -0,0 +1,112 @@
|
||||
# 前端 Agent 说明
|
||||
|
||||
## 技术与运行
|
||||
|
||||
- 技术栈:Vue 3、TypeScript strict mode、Vite、Pinia、Vue Router、Element Plus / `element-plus-secondary`、Less。
|
||||
- 路径别名 `@/` 指向 `frontend/src/`。
|
||||
- 构建目标是 Chrome 81,并启用 Vite legacy 插件;不要只按最新浏览器能力选择 API。
|
||||
- 常用命令:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev
|
||||
npm run build
|
||||
```
|
||||
|
||||
`dev` 和 `build` 都会先运行 `vue-tsc -b`。依赖变更只手动修改 `package.json`;`package-lock.json` 由 npm 命令自动生成且不入库,不要手工编辑或强制加入提交,也不要提交私有 registry 配置。
|
||||
|
||||
## 代码组织
|
||||
|
||||
| 内容 | 位置 |
|
||||
| --- | --- |
|
||||
| 后端接口封装 | `src/api/<domain>.ts` |
|
||||
| 仅单个业务域使用的类型和模型 | 跟随对应 `src/api/<domain>.ts` |
|
||||
| 跨页面/跨模块共享实体与配置 | `src/entity/` |
|
||||
| Pinia 状态 | `src/stores/<domain>.ts` |
|
||||
| 路由 | `src/router/index.ts`、`dynamic.ts`、`watch.ts` |
|
||||
| 页面级视图 | `src/views/<domain>/` |
|
||||
| 业务域私有子组件 | 对应 `src/views/<domain>/` 子目录 |
|
||||
| 跨业务复用组件 | `src/components/<component>/` |
|
||||
| 工具函数 | `src/utils/` |
|
||||
| 用户可见文案 | `src/i18n/` 五种语言 JSON |
|
||||
|
||||
组件目录常使用 `index.ts` 加 `src/` 的形式。新增复用组件时优先参考相邻组件结构;仅单个页面使用的组件不要提前提升到全局 `components/`。
|
||||
|
||||
## API 调用
|
||||
|
||||
- 不要在视图组件中直接使用 axios;统一通过 `@/utils/request.ts` 的 `request` 实例。
|
||||
- 新接口放入对应 `src/api/<domain>.ts`,导出类似 `xxxApi` 的对象,并复用既有命名风格。
|
||||
- 普通请求使用 `request.get/post/put/delete/patch`;SSE 使用 `request.fetchStream` 并传入 `AbortController`。
|
||||
- 不要手工添加认证 token、助手 token、证书、语言或 xpack 静态资源头。普通请求的头由 request interceptor 统一处理;SSE 走 `request.fetchStream`(原生 fetch,不经过 axios interceptor),头部在 `fetchStream` 内单独拼装(当前不含 `Accept-Language`),新增请求头时两条路径都要核对。
|
||||
- 下载类 blob 请求沿用:
|
||||
|
||||
```ts
|
||||
request.get('/path', {
|
||||
responseType: 'blob',
|
||||
requestOptions: { customError: true },
|
||||
})
|
||||
```
|
||||
|
||||
- 后端统一响应中 `code === 0` 时 interceptor 会返回 `data`;调用方不要重复解包。
|
||||
- 外部请求失败需要自定义处理时使用 `customError` 或 `silent`,不要绕开统一请求封装。
|
||||
|
||||
## 类型
|
||||
|
||||
- 新增代码优先使用具体 interface/type 或从 API 模块导出的模型;不要扩大 `any` 的使用范围。
|
||||
- 后端返回结构复杂且已有转换函数时,参考 `src/api/chat.ts` 的模型类和 `toXxx` 转换函数模式。
|
||||
- 共享类型放 `src/entity/`,业务专属类型跟随业务模块,避免相同 DTO 在多个视图中重复声明。
|
||||
- 修改类型后必须运行 `npm run build`,让 `vue-tsc` 检查模板和引用。
|
||||
|
||||
## 状态管理
|
||||
|
||||
- 新 store 放 `src/stores/<domain>.ts`,使用 Pinia options API 风格:`state`、`getters`、`actions`。
|
||||
- 为 state 定义 interface;getter 命名沿用 `getXxx`,action 命名表达业务行为。
|
||||
- 需要在 setup 外使用的 store,参考现有模块通过 `stores/index.ts` 的 `store` 实例导出包装函数。
|
||||
- 用户、语言、工作空间、助手上下文等状态已有 store;不要在组件里复制派生状态或直接改缓存键。
|
||||
|
||||
## 路由与权限
|
||||
|
||||
- 静态路由主要在 `src/router/index.ts`;由许可证或管理员能力控制的动态路由在 `dynamic.ts` 与 xpack 的 `LicenseGenerator.generateRouters` 中处理。
|
||||
- 修改 `watch.ts` 时必须核对:
|
||||
- 普通登录和管理员登录白名单;
|
||||
- `/assistant`、`/embeddedPage`、`/embeddedCommon`、`/401` 助手白名单;
|
||||
- `userStore.isAdmin` 与 `isSpaceAdmin` 的路由差异;
|
||||
- xpack 静态脚本加载失败路径。
|
||||
- 新路由必须配置名称、标题 i18n 和正确父布局;不要绕过已有访问控制。
|
||||
|
||||
## 视图、组件与样式
|
||||
|
||||
- 页面组件使用 Vue 3 组合式 API;新组件优先使用 `<script setup lang="ts">`。
|
||||
- Element Plus / `element-plus-secondary` 组件由插件自动导入;除非相邻代码已有显式导入,否则不要添加不必要的组件导入。
|
||||
- 样式优先使用 scoped Less,并复用邻近页面的布局类、间距类和 `flex-gap-fallback` 模式。
|
||||
- 只在有全局设计理由时修改 `src/style.less` 或跨页面公共样式;不要用行内样式解决可复用布局问题。
|
||||
- 图表逻辑优先复用 `src/views/chat/component/` 和 dashboard 现有封装,不要直接散落 G2/S2 配置。
|
||||
|
||||
## 国际化与安全
|
||||
|
||||
- 用户可见文案必须使用 vue-i18n,并同步:
|
||||
- `en.json`
|
||||
- `zh-CN.json`
|
||||
- `zh-TW.json`
|
||||
- `ko-KR.json`
|
||||
- `th-TH.json`
|
||||
- 新增语言时按 `docs/agents/i18n.md` 的完整链路检查,不要只添加 JSON 或漏掉文档更新。
|
||||
- 不要在组件中硬编码新文案;枚举和 supplier 配置可保留 i18n key。
|
||||
- 渲染模型输出或第三方内容时走既有 markdown/XSS 工具与安全指令;不要新增未净化的 `v-html`。
|
||||
- 不要削弱助手 postMessage 证书流程、请求头、token 存储和嵌入白名单逻辑。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
只检查改动文件时可运行:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npx eslint <changed-file...> --fix
|
||||
```
|
||||
|
||||
不要默认执行 `npm run lint`,它会修复整个前端,容易产生无关变更。当前没有独立前端单测框架;跨前端结构或安全约定由 `backend/tests/` 中的守卫测试保护,必要时新增或更新对应守卫。
|
||||
@@ -0,0 +1,79 @@
|
||||
# 国际化 Agent 说明
|
||||
|
||||
## 普通文案
|
||||
|
||||
- 前端界面文案使用 vue-i18n,JSON 位于 `frontend/src/i18n/`。
|
||||
- 后端返回给用户的错误和提示使用 `backend/locales/`。
|
||||
- 两处都必须同步五种语言:
|
||||
- `en`
|
||||
- `zh-CN`
|
||||
- `zh-TW`
|
||||
- `ko-KR`
|
||||
- `th-TH`
|
||||
- 以 `zh-CN` 的键结构为基准校验其他语言。
|
||||
- 不要把新用户可见文案硬编码在 Vue 组件、后端 handler、异常消息或 prompt 展示层中。
|
||||
- 后端 Swagger summary/description 使用 `PLACEHOLDER_PREFIX` 模式时,确认对应翻译键存在。
|
||||
|
||||
可以用脚本比较键路径,但不要为了普通文案变更引入新依赖。
|
||||
|
||||
## 新增语言
|
||||
|
||||
新增语言不是只添加 JSON 文件。以提交 `21961e2d`(Thai / `th-TH`)为完整示例,逐项检查:
|
||||
|
||||
### 前端
|
||||
|
||||
- 添加 `frontend/src/i18n/<locale>.json`,并与 `zh-CN.json` 保持键结构一致。
|
||||
- 在 `frontend/src/i18n/index.ts`:
|
||||
- import 语言 JSON;
|
||||
- 注册 messages;
|
||||
- import 并注册 Element Plus / `element-plus-secondary` locale。
|
||||
- 更新语言选择入口:
|
||||
- `frontend/src/components/Language-selector/index.vue`
|
||||
- `frontend/src/components/layout/Person.vue`
|
||||
- 更新浏览器语言识别:
|
||||
- `frontend/src/utils/utils.ts`
|
||||
- 更新旧版下划线别名:
|
||||
- `frontend/src/stores/user.ts`
|
||||
- 例如 `th_TH` → `th-TH`。
|
||||
- 在所有既有前端 locale 中新增该语言名称键,例如 `common.thai`。
|
||||
|
||||
### 后端
|
||||
|
||||
- 添加 `backend/locales/<locale>.json`。
|
||||
- 更新用户语言白名单:
|
||||
- `backend/apps/system/api/user.py`
|
||||
- `backend/apps/mcp/mcp.py`
|
||||
- 更新 schema 正则和显式校验:
|
||||
- `backend/apps/system/schemas/system_schema.py`
|
||||
- 同步 MCP 参数描述中的语言枚举:
|
||||
- `backend/apps/chat/models/chat_model.py`
|
||||
|
||||
### 模型输出
|
||||
|
||||
- 更新 `backend/apps/chat/task/llm.py` 中 `get_lang_name` 的语言映射。
|
||||
- 检查 `backend/templates/template.yaml`:
|
||||
- 所有需要跟随用户语言的输出都通过 `{lang}` 约束;
|
||||
- 猜测问题、分析和图表相关 JSON 值不会固定在中文;
|
||||
- 不需要的重复语言指令没有重新引入。
|
||||
|
||||
### 文档
|
||||
|
||||
- 更新所有明确声明支持语言列表的文档;不要让文档继续停留在旧语言集合。
|
||||
- 检查 `README.md` 和 `docs/README.en.md`:
|
||||
- 如果新增语言提供公开文档,则添加对应 localized README;
|
||||
- 更新每个 README 顶部的语言切换 badge/link;
|
||||
- 不要提交机器翻译后未检查的正式文档。
|
||||
- 如果 README 的功能列表或部署说明提到界面语言,同步新增语言名称。
|
||||
- 涉及 agent 指引时,更新:
|
||||
- `docs/agents/i18n.md` 的语言列表和新增语言 checklist;
|
||||
- `docs/agents/frontend.md` 的 locale 文件列表。
|
||||
- xpack 功能使用该语言输出用户可见错误或商业界面时,检查独立 xpack 仓库的说明和领域词汇是否需要同步。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
再运行与 supplier、文档或语言配置相关的守卫测试(`backend/tests/`);如没有对应守卫,至少用脚本验证五个 JSON 的递归键路径一致。
|
||||
@@ -0,0 +1,61 @@
|
||||
# 数据库迁移 Agent 说明
|
||||
|
||||
## 基本规则
|
||||
|
||||
- 数据库是 PostgreSQL;SQLModel 变更必须配套 Alembic 迁移。
|
||||
- 迁移位于 `backend/alembic/versions/`。
|
||||
- 文件名沿用三位编号加语义描述(存在 `009_0`、`009_1` 子编号形态);编号从现有迁移文件推导下一个可用值,不要假设固定值。
|
||||
- 每个迁移必须:
|
||||
- 设置唯一 `revision`;
|
||||
- 把 `down_revision` 指向当前 head;
|
||||
- 提供 `upgrade()` 和可执行的 `downgrade()`;
|
||||
- 保持单线迁移链,不创建并行 head。
|
||||
|
||||
生成方式:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run alembic revision --autogenerate -m "073 describe change"
|
||||
```
|
||||
|
||||
autogenerate 只是草稿。必须人工检查:
|
||||
|
||||
- 是否漏掉 xpack 或延迟导入模型的表;
|
||||
- 索引、约束、默认值、nullable、comment 是否完整;
|
||||
- 是否包含无关表或历史差异;
|
||||
- PostgreSQL 方言是否正确,尤其是 `JSONB`、`VECTOR` 和 `USING` 转换。
|
||||
|
||||
## 结构迁移
|
||||
|
||||
- 新增非空列优先采用两步:先加 nullable 列并回填,再视需要收紧约束。
|
||||
- 有默认值语义时明确 `server_default`,不要只依赖 Python 模型默认值。
|
||||
- 修改类型时提供 PostgreSQL `USING` 表达式;参考 `071_modify_permission_jsonb.py`。
|
||||
- 删除或重命名列先确认代码、导出、报表和 xpack 调用没有旧名残留。
|
||||
- 不要在迁移里顺手重命名历史表或整理无关 schema。
|
||||
|
||||
## 数据迁移
|
||||
|
||||
- 数据回填必须分批,避免长事务锁表。
|
||||
- 先明确空值、重复值和非法历史值的默认策略。
|
||||
- 不要在迁移中调用业务 CRUD;使用面向迁移的 SQL 或轻量对象。
|
||||
- 涉及加密、embedding 或外部系统时,说明为什么迁移期可以安全执行。
|
||||
- downgrade 若无法完整恢复数据,必须显式说明局限,不要伪装成无损回滚。
|
||||
|
||||
## xpack schema
|
||||
|
||||
- xpack 表结构变更属于跨仓库接口变更。
|
||||
- 先确认主仓库将锁定的 xpack wheel 版本,并检查该版本中的模型。
|
||||
- 不要把仅闭源功能需要的表混进开源功能迁移。
|
||||
- 发布顺序遵循 `docs/agents/packaging.md`。
|
||||
|
||||
## 验证
|
||||
|
||||
在有可用的一次性开发数据库前,不要默认执行迁移。至少执行:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run alembic heads
|
||||
uv run alembic history
|
||||
```
|
||||
|
||||
确认只有一个 head 且新迁移的父节点正确。对一次性数据库执行 `upgrade head`,必要时再执行一级 downgrade 验证回滚。数据库结构变更要同步检查模型、CRUD、API schema、导出/导入和 xpack 调用。
|
||||
@@ -0,0 +1,78 @@
|
||||
# 打包与发布 Agent 说明
|
||||
|
||||
## 产物组成
|
||||
|
||||
运行镜像由多个阶段组成:
|
||||
|
||||
1. 前端构建:`frontend/` 执行 `npm install` 和 `npm run build`,产物进入 `/opt/sqlbot/frontend/dist`。
|
||||
2. 后端构建:复制 `backend/`,使用 base 镜像中的 uv 安装依赖;存在 `backend/uv.lock` 时先按 lock 冻结安装,缺失时(如 CI 全新 checkout)回退按 `pyproject.toml` 解析。
|
||||
3. 图表服务构建:复制 `g2-ssr/app.js`、`package.json` 和 `charts/`,安装 Node 依赖和 canvas 相关库。
|
||||
4. 运行层:基于含 PostgreSQL / Python 的 base 镜像,复制前端、后端、g2-ssr、字体、向量模型和启动脚本。
|
||||
5. 启动脚本依次准备 PostgreSQL、supervisor/g2-ssr、MCP 服务和主 FastAPI 服务。
|
||||
|
||||
修改路径、端口、依赖或构建脚本时,必须核对最终运行目录仍是 `/opt/sqlbot` 布局,且数据、图片、日志和字体路径没有断开。
|
||||
|
||||
## 本地验证
|
||||
|
||||
普通代码任务不要默认构建镜像;Docker 构建需要外部镜像、模型资源和较长耗时。用户明确要求时才执行,并说明目标平台。
|
||||
|
||||
可以做的轻量检查:
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run pytest -q
|
||||
```
|
||||
|
||||
```bash
|
||||
node --check g2-ssr/app.js
|
||||
node --check g2-ssr/charts/<changed-file.js>
|
||||
```
|
||||
|
||||
修改 Dockerfile 或 installer 后,至少人工追踪:
|
||||
|
||||
- COPY 源路径和目标路径;
|
||||
- 构建阶段产物是否被运行层复制;
|
||||
- `start.sh` 启动顺序和健康检查端口;
|
||||
- `8000` / `8001` / `3000` / `5432` 的用途;
|
||||
- excel、file、images、logs、PostgreSQL 数据挂载;
|
||||
- `installer/sqlbot/templates/sqlbot.conf` 中的环境变量仍然存在且默认值安全。
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
| 工作流 | 用途 | 关键输入 |
|
||||
| --- | --- | --- |
|
||||
| `build-base-and-push` | 构建 PostgreSQL / Python base 镜像 | tag、架构、registry、是否 latest |
|
||||
| `build-and-push` | 构建 SQLBot 主镜像 | tag、架构、registry、是否 latest |
|
||||
| `package-and-push` | 构建 CE/EE 在线与离线安装包 | SQLBot tag、架构、registry、是否 EE |
|
||||
| `Build Wheels Universal` | 从主仓库触发 xpack 多平台 wheel 构建 | xpack 分支、平台矩阵、是否发布、TestPyPI/PyPI |
|
||||
| `Typos Check` | push 和 PR 的拼写检查 | — |
|
||||
| `Synchronize to Gitee` | push 时同步镜像到 Gitee | — |
|
||||
| `Sync to CNB` | 手动同步到 CNB | — |
|
||||
|
||||
规则:
|
||||
|
||||
- 根 `Dockerfile` 的构建阶段还依赖 `registry.cn-qingdao.aliyuncs.com/dataease/sqlbot-base:latest`,该镜像不在本仓库工作流中构建(外部维护);`build-base-and-push` 只产出 `sqlbot-python-pg` base 镜像。
|
||||
- 这些工作流都是发布/分发流程,不要因为普通代码修改建议运行。
|
||||
- `latest` 只应在正式发布时启用。
|
||||
- arm64 和 amd64 的依赖、驱动和包名必须同时考虑。
|
||||
- 离线包会替换 `SQLBOT_TAG` 并生成 version 文件;不要在源码里提交生成后的 tag。
|
||||
- xpack 工作流会 checkout 独立仓库;不要把本地 `sqlbot-xpack/` 目录当作它的输入。
|
||||
|
||||
## 发布顺序
|
||||
|
||||
1. 主仓库功能和测试完成。
|
||||
2. 若涉及 xpack:
|
||||
1. xpack 独立仓库完成实现、版本提升和静态构建;
|
||||
2. 发布目标 wheel;
|
||||
3. 主仓库更新 `backend/pyproject.toml` 版本范围并重新验证。
|
||||
3. 确认迁移、默认配置和 installer 模板兼容。
|
||||
4. 构建 base 镜像(仅在 base 变更时)。
|
||||
5. 构建主镜像。
|
||||
6. 构建在线 / 离线安装包。
|
||||
|
||||
发布版本号、镜像 tag、离线包名、backend 包版本和 Git tag 必须由使用者明确确认。agent 不要自行发布、上传、打 tag 或推送。
|
||||
@@ -0,0 +1,91 @@
|
||||
# 安全 Agent 说明
|
||||
|
||||
## 原则
|
||||
|
||||
- LLM 输出、SQL、文件名、路径、Host 头、路由参数、第三方回传数据和前端消息都不是可信输入。
|
||||
- 新接口默认拒绝;先认证、再授权、再校验资源归属,最后执行业务。
|
||||
- 发现现有绕过路径时优先收敛授权语义,不要只在单个 URL 上打补丁。
|
||||
- 涉及以下任何区域,必须补充或更新回归测试,并运行 `backend/tests/` 中的相关守卫。
|
||||
|
||||
## API 权限
|
||||
|
||||
- 使用 `CurrentUser` / `SessionDep` 获取身份和会话,不信任请求体中的用户或工作空间 ID。
|
||||
- 资源型接口使用 `@require_permissions(...)`,并确认:
|
||||
- `type` 指向正确资源;
|
||||
- `keyExpression` 能取到真实资源 ID;
|
||||
- 列表语义不会被单个资源绕过;
|
||||
- 管理员、工作空间管理员和普通用户路径都明确。
|
||||
- 手写查询归属时,同时校验:
|
||||
- 资源存在;
|
||||
- 资源属于当前工作空间;
|
||||
- 资源属于当前用户或其授权范围;
|
||||
- 助手上下文没有切换到其他工作空间。
|
||||
- `oid` 和 `workspace_id` 都表示工作空间 ID;不要把两者当成不同授权域。
|
||||
- 高级助手动态数据源只允许既有动态类型走动态数据源例外;本地 `CoreDatasource` 仍必须校验工作空间归属。
|
||||
|
||||
## SQL 生成与执行
|
||||
|
||||
当前主流程的安全顺序不可弱化:
|
||||
|
||||
1. 只把允许的表和字段元数据提供给模型;
|
||||
2. 解析模型返回 JSON 并提取 SQL;
|
||||
3. 用 `sqlglot` 提取真实表名并排除 CTE 别名;
|
||||
4. 对照允许表集合拒绝未授权表;
|
||||
5. 按用户、助手和页面嵌入场景应用行权限或动态 SQL 变换;
|
||||
6. 校验并保存最终 SQL;
|
||||
7. 执行最终 SQL 并保存结果。
|
||||
|
||||
额外要求:
|
||||
|
||||
- 不要信任模型返回的 `tables` 字段替代真实 SQL 解析。
|
||||
- 行权限拼接沿用白名单逻辑运算符和 `_escape_sql_value`,不要引入新的字符串拼接入口。
|
||||
- 保持 SQL 行数限制和 `SQLBOT_ALLOW_METADATA_QUERIES` 默认关闭语义;不要为了调试全局开启元数据查询。
|
||||
- 动态 SQL 生成后仍必须走同一解析、校验和保存路径。
|
||||
- 数据源连接配置解密只发生在服务端执行路径,不进入日志或 API 响应。
|
||||
|
||||
## 认证、Host 与嵌入
|
||||
|
||||
- 不要改变 `backend/main.py` 中中间件注册顺序;`HostValidationMiddleware` 必须在外层拒绝非法 Host。
|
||||
- Host 只允许合法域名 / IPv4 / IPv6 形态,不能包含 `/`、`@` 或空白。
|
||||
- 认证和助手 token 头由后端中间件与前端 request interceptor 处理;不要新增手工传递或复制 token 的路径。
|
||||
- 页面嵌入协议必须保持:
|
||||
- 仅 `AssistantModel.type == 4` 可用 embedded 协议;
|
||||
- 先提取目标助手,再用 `app_secret` 验证签名;
|
||||
- 管理员账号拒绝通过 embedded token 使用;
|
||||
- 账号状态和工作空间归属仍需校验。
|
||||
- 修改助手 `domain`、`app_id`、`app_secret` 或类型时,同时考虑目标系统信任边界和跨工作空间访问。
|
||||
- 前端 `postMessage` 证书流程不要降级为无请求绑定、无来源约束或永久有效证书。
|
||||
|
||||
## 文件与路径
|
||||
|
||||
- 不信任上传文件名、扩展名、MIME、sheet 名或用户提供的 `filePath`。
|
||||
- 上传必须限制类型和大小,落盘使用服务端生成的文件名或 opaque ID。
|
||||
- 读取用户可控路径前必须证明路径仍位于允许目录内;优先使用 `os.path.commonpath` 或仅通过内部 ID 映射真实路径。
|
||||
- 下载响应使用 `os.path.basename` 或 FileResponse,不回显绝对路径。
|
||||
- Excel/CSV 解析错误不能变成可猜测的内部路径信息。
|
||||
|
||||
## 前端渲染
|
||||
|
||||
- 不直接在组件中调用 axios,避免绕开认证、语言、助手证书和错误处理。
|
||||
- Markdown 渲染保持 `html: false`,代码高亮必须转义。
|
||||
- 新增富文本 / HTML 渲染必须走既有安全工具和组件;不要添加未净化 `v-html`。
|
||||
- 链接、图片和远程脚本必须限制协议和来源,不允许 `javascript:` 或用户控制的服务端地址。
|
||||
- xpack 静态脚本保留缓存穿透参数和失败处理;不要把商业脚本或密钥复制进前端源码。
|
||||
|
||||
## 日志与敏感信息
|
||||
|
||||
- 不记录 token、密码、API key、数据源明文连接串、SQL 凭据、助手 secret 或完整敏感配置。
|
||||
- 异常响应面向用户时使用后端 i18n 错误;内部 traceback 只进入受控日志。
|
||||
- 安全测试样本可以包含攻击载荷,但不得包含真实可用凭据或内部地址。
|
||||
|
||||
## 必测场景
|
||||
|
||||
修改相关逻辑时至少覆盖:
|
||||
|
||||
- 未登录、无权限、资源不存在、跨工作空间访问;
|
||||
- 管理员、工作空间管理员、普通用户、助手用户;
|
||||
- Host 头携带路径、`@`、空白等污染形态;
|
||||
- SQL 引用未授权表、CTE 别名、动态 SQL 和行权限边界;
|
||||
- embedded token 错误助手类型、错误签名、管理员账号和无效账号;
|
||||
- 上传路径穿越、非法扩展、超限大小和重复扩展名;
|
||||
- 前端错误传播和未净化内容渲染。
|
||||
@@ -0,0 +1,79 @@
|
||||
# 测试 Agent 说明
|
||||
|
||||
## 测试布局
|
||||
|
||||
所有测试都在 `backend/tests/`,从 `backend/` 目录用同一条命令运行:
|
||||
|
||||
```bash
|
||||
uv run pytest -q
|
||||
uv run pytest -q tests/<relevant-test.py>
|
||||
```
|
||||
|
||||
按用途分两类(目录内不按类再分层级):
|
||||
|
||||
- 后端单元回归:纯函数、连接池、数据格式、embedding、驱动兼容、分布式锁。
|
||||
- 仓库守卫:SQL 转义、权限过滤、Host 校验、嵌入认证等安全修复;关键前端组件之间的错误传递和结构契约;supplier/model 配置一致性;i18n 键。这类测试常直接读取源码文本或用 AST 提取局部实现,路径从 `backend/tests/` 推到仓库根。
|
||||
|
||||
前端没有独立单测框架;`npm run build` 中的 `vue-tsc` 是类型验证,结构性契约由上述守卫测试保护。xpack 在独立仓库内先做 compileall 和静态 SDK 构建;完整集成在 SQLBot 后端环境中执行。
|
||||
|
||||
不要为了速度跳过与改动相关的层,也不要把所有历史失败当成当前变更造成的问题;先用目标测试定位边界。
|
||||
|
||||
## 新增测试约定
|
||||
|
||||
- 测试可隔离的纯逻辑或服务函数;
|
||||
- 用 `Mock`、`SimpleNamespace`、SQLite 或 AST 加载方式隔离外部数据库和驱动;
|
||||
- 不访问真实 LLM、数据库或互联网;
|
||||
- 命名和断言风格跟随相邻测试。
|
||||
|
||||
`LOG_FORMAT` 只是 `logging.Formatter` 的百分号格式串模板,代码中没有 JSON 日志实现;若本机环境把它设成了非默认格式串导致 formatter 初始化失败,测试前 `unset LOG_FORMAT` 恢复默认。
|
||||
|
||||
## 守卫维护
|
||||
|
||||
当 intentional 变更导致守卫失败时,更新守卫以表达新契约;不要删除断言、扩大白名单或降低安全约束来让测试通过。
|
||||
|
||||
## 前端验证
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
- 类型、模板和打包验证由 `vue-tsc -b` 与 Vite 完成。
|
||||
- 修改少量文件时可用 `npx eslint <changed-file...> --fix`。
|
||||
- 不要默认运行全量自动修复脚本。
|
||||
- 当前不要自行引入 Vitest/Jest/Playwright 等新测试框架;若需要,先提出框架、运行成本和 CI 影响。
|
||||
|
||||
## 图表渲染服务
|
||||
|
||||
修改 `g2-ssr/` 或后端图表配置时,验证命令与前后端字段契约见 `g2-ssr/AGENTS.md`。
|
||||
|
||||
## Ruff 和类型检查
|
||||
|
||||
后端 Ruff 只针对改动文件运行,避免全仓库历史问题产生无关 diff:
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
uv run ruff check <changed-file.py...>
|
||||
uv run ruff format <changed-file.py...>
|
||||
```
|
||||
|
||||
`pyproject.toml` 配置了 mypy strict,但历史代码尚未建立全仓库通过基线。新代码应避免引入新的类型问题;是否运行 mypy 由改动范围和相邻模块现状决定,不要自动对全仓库执行大规模修复。
|
||||
|
||||
## 测试选择标准
|
||||
|
||||
必须至少运行相关测试的情况:
|
||||
|
||||
- 修复 bug:覆盖原始失败输入和边界输入;
|
||||
- 安全逻辑:覆盖攻击样本、拒绝路径和合法路径;
|
||||
- 数据格式/连接池/embedding:运行对应既有测试;
|
||||
- API 或前端结构契约:运行相关守卫测试;
|
||||
- i18n:确认五种语言键结构;
|
||||
- xpack 联调:使用 editable 安装并运行 SQLBot 后端测试。
|
||||
|
||||
完成标准:
|
||||
|
||||
- 相关测试通过,或明确记录与本次改动无关的既有失败;
|
||||
- 新行为有回归测试或说明为什么不适用;
|
||||
- 没有为了通过测试削弱安全约束;
|
||||
- 没有引入网络、数据库、密钥或不可重复依赖;
|
||||
- 正确仓库的 status/diff 只包含任务相关变更。
|
||||
@@ -0,0 +1,32 @@
|
||||
# xpack 工作流 Agent 说明
|
||||
|
||||
`sqlbot-xpack` 默认作为版本范围由 `backend/pyproject.toml` 约束的已发布 wheel 使用;`uv.lock` 不入库,只用于冻结本机安装。日常任务不读取、不修改本地 xpack checkout。
|
||||
|
||||
只有任务确实需要修改或调试闭源 xpack 代码,或者需要两个仓库联动验证时,才检查本地关联开关。未提交的根目录 `AGENTS.local.env` 保存本机配置:
|
||||
|
||||
```dotenv
|
||||
# 请把路径替换为本机真实的 xpack 仓库根目录绝对路径。
|
||||
SQLBOT_XPACK_LINK_ENABLED=true
|
||||
SQLBOT_XPACK_REPO=/replace/with/your/sqlbot-xpack-checkout
|
||||
```
|
||||
|
||||
| 开关状态 | 行为 |
|
||||
| --- | --- |
|
||||
| 未配置或值无效 | 仅当任务需要 xpack 时,询问一次是否开启本地关联;同意后验证并保存路径。 |
|
||||
| `false` | 继续使用已发布 wheel。不读取路径、不安装 editable 包、不修改 xpack、不重复询问。若任务无法绕开闭源实现,说明需要用户主动开启开关。 |
|
||||
| `true` | 验证路径后,把该 checkout 作为可修改的 xpack 工作区,读取 `sqlbot-xpack/AGENTS.md`,并协调两个仓库的变更。 |
|
||||
|
||||
路径目录名可以任意,但必须是指向 xpack Git 仓库根目录的绝对路径;用 `git -C "$SQLBOT_XPACK_REPO" rev-parse --show-toplevel` 验证。环境变量优先于 `AGENTS.local.env`。不要静默覆盖该文件,也不要在其中保存密钥。
|
||||
|
||||
本地联调时,先加载配置,把 xpack 以 editable 方式安装进后端环境,并使用 `--no-sync` 避免 uv 用锁定 wheel 替换它:
|
||||
|
||||
```bash
|
||||
set -a
|
||||
. ./AGENTS.local.env
|
||||
set +a
|
||||
cd backend
|
||||
uv pip install -e "$SQLBOT_XPACK_REPO"
|
||||
uv run --no-sync pytest -q
|
||||
```
|
||||
|
||||
在 `backend/` 执行 `uv sync` 可恢复已发布包。变更和提交必须分开:SQLBot 变更留在本仓库,xpack 变更留在独立仓库。完整发布顺序以 `docs/agents/packaging.md` 为准。
|
||||
@@ -0,0 +1,21 @@
|
||||
# g2-ssr Agent 说明
|
||||
|
||||
## 定位
|
||||
|
||||
无框架 Node.js http 服务,端口 `3000`。接收后端提交的图表配置,用 `@antv/g2-ssr` + `node-canvas` 渲染为 PNG。`app.js` 是唯一入口;图表实现位于 `charts/`(bar、column、line、pie、utils)。
|
||||
|
||||
## 修改
|
||||
|
||||
- 新增图表类型:新建 `charts/<type>.js` 导出 `get<Xxx>Options`,并在 `app.js` 中注册。
|
||||
- 请求体、图表配置或输出路径是与 backend 的契约(图表配置在 `backend/apps/chat` 的会话流程中生成);变更时两侧一起核对字段一致。
|
||||
- 依赖变更只改 `package.json`,`package-lock.json` 不入库;注意容器构建依赖 canvas 相关系统库。
|
||||
- Dockerfile 只 COPY `app.js`、`package.json`、`charts/*`、`*.ttf` 和 `supervisord.conf`,运行目录 `/opt/sqlbot/g2-ssr`;新增文件或改路径时核对 COPY 范围。
|
||||
|
||||
## 验证
|
||||
|
||||
没有测试框架,至少执行语法检查:
|
||||
|
||||
```bash
|
||||
node --check g2-ssr/app.js
|
||||
node --check g2-ssr/charts/<changed-file.js>
|
||||
```
|
||||
Reference in New Issue
Block a user