feat(web): 项目级配置 + 会话命名/历史 + 设计文档纳入影响调查

- 会话支持 name/project 字段,上传要件定义后自动命名;前端侧边栏会话历史 + localStorage 恢复,顶部只显示会话名
- 新增 ProjectsStore(SQLite)与 /api/projects CRUD;绑定项目后 _rebuild_source 合并模板/规则/代码库/设计文档,上传区仅要件定义
- StructuredSource.design_docs 与 ImpactReport.design_references;影响调查新增既有设计文档确定性交叉引用(无 LLM)
- 同步更新 docs/design.md §12.7、README、_AI_USAGE_LOG.md;全量测试 558 通过,覆盖率 99.10%
This commit is contained in:
lhl
2026-08-27 12:13:28 +08:00
parent 838a93720e
commit 916c5beed7
18 changed files with 1174 additions and 65 deletions
+29
View File
@@ -1888,3 +1888,32 @@ Document(注入后 Word 文档)
- `app.py` 新增 `POST /api/chat/{sid}/messages`、`GET /api/chat/{sid}/messages``GET /` 改为返回聊天页
- 测试:`tests/test_chat_intent.py` / `tests/test_chat_agent.py` / `tests/test_server_chat_api.py`TestClient 全链路)
- 真实黑盒冒烟建议:用 `python scripts/serve.py` 部署后,从聊天页用中文下达「上传了文件,生成概要设计书」并确认影响即可走通全程。
### 12.7 项目级配置与既有设计文档纳入影响调查(2026-08,Web UI 升级二)
在 12.6 聊天页基础上,进一步降低每次生成的配置负担,并把既有设计文档作为影响调查的辅助证据来源。
#### 12.7.1 会话命名与历史
- 会话 `SessionRecord` 新增 `name` / `project` 字段(默认 `name="新会话"`);`store.create_session(user_id, name, project)` 支持传入。
- 上传**要件定义 xlsx** 后,若会话名仍为默认「新会话」,自动取文件名(去扩展名)作为会话名,便于在历史列表中区分。
- 前端 `chat.html` 左侧新增**会话历史侧边栏**`GET /api/sessions` 返回 `name`/`project`,点击可加载历史会话(`GET /api/chat/{sid}/messages`)并恢复消息;当前会话 ID 存入 `localStorage`,刷新后自动恢复。
- 顶部只显示 **会话名**(不显示会话 ID)。
#### 12.7.2 以项目为单位的配置(用户只传要件定义)
- 新增 `ProjectsStore`(复用 `sessions.db`):`projects` 表,字段 `name`(主键)/ `display_name` / `template` / `write_instruction` / `rules[]` / `existing_system_code_dir` / `design_docs_dir`。
- `ProjectConfigError`:路径不存在 / 非 `.docx` / 非目录 时抛出(对应 `api-design` 400 `PROJECT_CONFIG_INVALID`)。
- 校验规则:`_validate_project_paths` 对模板/做成说明书/规则/代码库目录/设计文档目录做存在性与类型校验;`rules` 与 `design_docs_dir` 为目录时枚举其中的 `.docx`。
- 配置 CRUD 端点:`POST /api/projects`(创建/更新,同名覆盖)、`GET /api/projects`、`GET /api/projects/{name}`、`DELETE /api/projects/{name}`。
- 会话绑定项目:`POST /api/sessions` 收 `project` 字段;`service.has_file(rec, ftype)` 与 `service._eff_path(rec, ftype)` 在用户未上传时回退到项目配置(同类型用户文件优先)。
- `_rebuild_source` 合并:模板/做成说明书/规则 = 用户上传优先,否则取项目配置(rules 两者追加);既有系统代码库与设计文档目录取项目配置。
- 前端交互:侧边栏「项目配置」面板可新建/选择项目;选中项目后新建会话即绑定,**上传区仅显示「要件定义 xlsx(必需)」**(其余由项目提供),并给出提示。
#### 12.7.3 既有设计文档纳入影响调查(确定性交叉引用)
- `StructuredSource` 新增 `design_docs: list[RuleDocument]``category="design"`,区别于写入规则);`SourceParser.parse` 新增 `design_doc_paths`,解析为 `RuleDocument`。
- `ImpactReport` 新增 `design_references: list[DesignReference]``doc_name` / `identifier` / `snippet`)。
- `ImpactAgent._cross_ref_design_docs`:以既有系统解析出的标识符(类/方法/模块名,小写键)为锚,在 `design_docs` 的 `markdown_content` 中做**大小写不敏感**子串检索;命中则记录原始大小写 token 与前后文片段。**无 LLM 参与**,纯字符串匹配。
- 序列化:`impact_report_to_dict` 输出包含 `design_references`;影响调查书下载 JSON 同步包含。
- 说明:设计文档作为 Type A 辅助证据,**不进入写入规则**,不引入额外 LLM 调用,保持影响调查零幻觉目标。
+123
View File
@@ -0,0 +1,123 @@
# Web 聊天前端改造 + 项目级配置 + 设计文档纳入影响(实施计划)
> 状态:已评审定稿(2026-08-26
> 决策记录:
> - 会话名称:自动取要件定义文件名(未上传前显示「新会话」),header 不显示会话 ID
> - 历史:左侧会话列表侧边栏,可切换历史会话并加载聊天记录
> - 配置单位:**以项目为单位**(服务端持久化,复用 SQLite),项目下多个会话共享配置
> - 上传区:选定项目后只显示「要件定义 xlsx(必需)」,其余来自项目配置
> - 设计文档入影响:**A 确定性交叉引用**(代码变更点标识符 × 设计文档文本命中 → design_references
---
## 一、总体设计
| 维度 | 方案 |
|---|---|
| 会话名称 | `name` 自动取要件定义文件名;默认「新会话」;header 显示 `会话: <name>` |
| 历史 | 左侧会话列表侧边栏;点击切换并 `GET /api/chat/{sid}/messages` 加载;localStorage 记当前会话 |
| 配置单位 | 项目级(服务端 SQLite `projects` 表);会话绑定 `project` 名,共享配置 |
| 上传区 | 选定项目后仅「要件定义 xlsx(必需)」;模板/规则/代码库/设计文档来自项目配置 |
| 设计文档入影响 | 做法 A:解析设计文档为文本,与代码变更点标识符交叉引用,命中写 `design_references` |
---
## 二、数据模型与存储(`src/genesis/server/store.py`
- `SessionRecord` 新增字段:
- `name: str = ""`(会话显示名)
- `project: str = ""`(绑定的项目名;为空表示无项目)
- `to_dict()` / `_from_dict()` 同步。
- 新增 `ProjectsStore`(复用同一 SQLite 文件,新增 `projects` 表):
- 字段:`name`(PK)、`display_name``template``write_instruction``rules`(JSON list of paths)、`existing_system_code_dir``design_docs_dir``created_at``updated_at`
- 方法:
- `upsert(name, display_name, template, write_instruction, rules, existing_system_code_dir, design_docs_dir)`
- `get(name) -> ProjectConfig | None`
- `list() -> list[ProjectConfig]`
- `delete(name) -> bool`
- 路径校验(`_validate_project_paths`):
- `template` / `write_instruction`:文件须存在且为 `.docx`
- `rules` / `design_docs_dir`:目录须存在,枚举其中 `.docx`(为空目录 → 空列表,不报错)。
- `existing_system_code_dir`:目录须存在(代码库目录,直接交给 CodeParser)。
- 越界/不存在 → 抛 `ProjectConfigError`(映射 API 400)。
- 异常:`ProjectConfigError`(新增,与 `SessionNotFoundError` 并列)。
---
## 三、服务层(`src/genesis/server/service.py`
- `GenesisService.__init__` 增加 `projects: ProjectsStore | None = None`
- `create_session(user_id, name=None, project=None)`:落 `name`(默认「新会话」)/`project`
- `upload_file`:上传 `requirements` 且当前 `name` 仍为默认「新会话」时,自动将 `name` 设为文件名(去扩展名)。
- **`_rebuild_source(rec)` 合并逻辑(核心)**
1.`rec.project` 非空 → `cfg = self.projects.get(rec.project)`;从 cfg 取 template / write_instruction / rules(目录枚举)/ existing_system_code_dir / design_docs(目录枚举)。
2. 用户 `rec.files`(要件定义等)**覆盖**同名类型(用户上传优先)。
3. 汇总传入 `SourceParser.parse`
- `requirement_paths` ← 用户上传 requirements
- `template_path` ← template(用户覆盖优先)
- `write_instruction_paths` ← write_instruction
- `rule_paths` ← rules 目录枚举的 `.docx`
- `existing_system_path` ← existing_system_code_dir(用户上传 zip 覆盖优先)
- `design_doc_paths` ← design_docs 目录枚举的 `.docx`
- 新增 `has_file(rec, ftype)` 同时查 `rec.files` 与项目配置,供 `run_parse` / `ChatAgent` 判断缺件。
- `run_impact``_rebuild_source` 已含 `design_doc_paths``ImpactAgent` 产出 `design_references`;影响摘要增加「设计文档关联 N 处」。
---
## 四、影响调查扩展(做法 A
- `src/genesis/data_models.py`
- `StructuredSource` 增加 `design_docs: list`(设计文档解析文本块,元素含 `name` + `text`)。
- `ImpactReport` 增加 `design_references: list[dict]`(每项为 `{element_id, identifier, doc_name, snippet}`)。
- `src/genesis/parsers/source_aggregator.py``parse` 增加 `design_doc_paths` 参数 → 用 `RuleDocParser`(category="design") 解析 Word 为文本块,挂到 `StructuredSource.design_docs`
- `src/genesis/impact/impact_agent.py``run(ss, ...)` 在代码变更点分析后,对每个变更标识符(类名/方法名)在 `ss.design_docs` 文本中检索出现处,命中即记入 `design_references`(确定性,无 LLM)。
- 影响调查书 JSON 与聊天反问摘要体现 `design_references` 计数。
---
## 五、API`src/genesis/server/app.py`
- `GET /api/projects` → 列表(name, display_name)。
- `POST /api/projects` → upsertbodydisplay_name, template, write_instruction, rules[], existing_system_code_dir, design_docs_dir);校验失败 400。
- `DELETE /api/projects/{name}`(可选)。
- `POST /api/sessions``project``name`;返回含 `name``project`
- `GET /api/sessions` 增可选 `project` 过滤;返回含 `name``project`
- `GET /api/sessions/{sid}` 已含 to_dict(含 name/project)。
- 聊天端点不变。
---
## 六、前端(`src/genesis/server/static/chat.html`
- **项目配置面板**(可折叠):display_name、name、模板路径、做成说明书路径、记入·图表规则**目录**、既有系统代码库**目录**、既有设计文档**目录**;「保存项目」→ `POST /api/projects`;顶部「项目」下拉(`GET /api/projects`)。
- 主页:选活动项目 → 「新会话」在该项目下建会话并自动套用配置;上传区**仅要件定义**。
- **左侧会话侧边栏**`GET /api/sessions` 列(名称 + 项目名 + 状态),点击切换 → `GET /api/chat/{sid}/messages` 加载;「新会话」按钮。
- header 显示 `会话: <name>`(不含 ID)。
- 页面加载:localStorage 读上次 sid,有效则恢复历史,否则新建。
---
## 七、测试(保持 `fail_under=99`
- `tests/test_server_store.py`ProjectsStore CRUD + SessionRecord 新字段。
- `tests/test_server_service.py`:项目 upsert / 路径校验拒绝 / 目录枚举 / `has_file` / 会话绑定项目 / `_rebuild_source` 合并 / design_references 进影响。
- `tests/test_server_api.py`projects 端点 / sessions 含 name+project / chat 历史。
- `tests/test_impact_agent.py` + `tests/test_source_aggregator.py`design_doc_paths 与 design_references 命中。
- `tests/test_chat_agent.py`:项目绑定流程(仅传要件定义即可生成)。
---
## 八、文档与日志
- `docs/design.md` §12.6 补:会话命名 / 历史侧边栏 / 项目级配置 / 设计文档纳入影响。
- `README.md` Web 服务段更新(项目配置用法)。
- `_AI_USAGE_LOG.md` 追加(范式步骤=Agent 实现)。
---
## 九、提交规范红线自检
- 新增代码/表全 ASCII 文件名;无新前端文件(仅改 `chat.html`)。
- 配置路径运行时解析 + 越界拒绝,**无硬编码绝对路径**。
- `.env` 不入库;无 >50MB 二进制。
- 全量 pytest 保持 `fail_under=99`