- 会话支持 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%
124 lines
7.3 KiB
Markdown
124 lines
7.3 KiB
Markdown
# 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` → upsert(body:display_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`。
|