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:
@@ -95,6 +95,87 @@ def test_status_reports_current_state(tmp_path):
|
||||
assert "uploading" in r["reply"]
|
||||
|
||||
|
||||
def test_status_reply_with_project_design_docs(tmp_path):
|
||||
from genesis.server.store import ProjectsStore
|
||||
store = SessionStore(db_path=str(tmp_path / "s.db"))
|
||||
dd = tmp_path / "design"
|
||||
dd.mkdir()
|
||||
(dd / "d.docx").write_bytes(b"PK\x03\x04")
|
||||
projects = ProjectsStore(db_path=str(tmp_path / "p.db"))
|
||||
projects.upsert(name="projA", display_name="P", template="", write_instruction="",
|
||||
rules=[], existing_system_code_dir="", design_docs_dir=str(dd))
|
||||
agent = ChatAgent(GenesisService(store=store, data_root=str(tmp_path / "data"),
|
||||
engine=FakeEngine(), projects=projects), fake=True)
|
||||
sid = agent.service.create_session("u1", project="projA").session_id
|
||||
r = agent.handle_message(sid, "现在什么状态?")
|
||||
assert "design_docs" in r["reply"]
|
||||
|
||||
|
||||
def test_status_reply_lists_existing_system_and_design_docs(tmp_path):
|
||||
from genesis.server.store import ProjectsStore
|
||||
store = SessionStore(db_path=str(tmp_path / "s.db"))
|
||||
dd = tmp_path / "design"; dd.mkdir(); (dd / "d.docx").write_bytes(b"PK\x03\x04")
|
||||
code = tmp_path / "code"; code.mkdir()
|
||||
projects = ProjectsStore(db_path=str(tmp_path / "p.db"))
|
||||
projects.upsert(name="projA", display_name="P", template="", write_instruction="",
|
||||
rules=[], existing_system_code_dir=str(code), design_docs_dir=str(dd))
|
||||
agent = ChatAgent(GenesisService(store=store, data_root=str(tmp_path / "data"),
|
||||
engine=FakeEngine(), projects=projects), fake=True)
|
||||
sid = agent.service.create_session("u1", project="projA").session_id
|
||||
reply = agent._status_reply(agent.service.get_session(sid), [])
|
||||
assert "existing_system" in reply["reply"] and "design_docs" in reply["reply"]
|
||||
|
||||
|
||||
def test_auto_generate_unknown_status_falls_to_status_reply(tmp_path):
|
||||
from genesis.server.store import ProjectsStore
|
||||
store = SessionStore(db_path=str(tmp_path / "s.db"))
|
||||
projects = ProjectsStore(db_path=str(tmp_path / "p.db"))
|
||||
projects.upsert(name="projA", display_name="P",
|
||||
template=str(_SAMPLE / "template_design_ja.docx"),
|
||||
write_instruction="", rules=[], existing_system_code_dir="", design_docs_dir="")
|
||||
agent = ChatAgent(GenesisService(store=store, data_root=str(tmp_path / "data"),
|
||||
engine=FakeEngine(), projects=projects), fake=True)
|
||||
sid = agent.service.create_session("u1", project="projA").session_id
|
||||
# 上传要件定义,使 has_file 通过;随后将状态置为 done 触发 _status_reply 分支
|
||||
agent.service.upload_file(sid, "requirements", "requirements_newdev.xlsx",
|
||||
(_SAMPLE / "requirements_newdev.xlsx").read_bytes())
|
||||
agent.service.store.update_status(sid, "done")
|
||||
r = agent._auto_generate(sid, "auto", [])
|
||||
assert "done" in r["reply"]
|
||||
|
||||
|
||||
def test_run_generate_from_awaiting_impact_confirm_confirms_first(tmp_path):
|
||||
agent = ChatAgent(_svc(tmp_path), fake=True)
|
||||
sid = agent.service.create_session("u1").session_id
|
||||
agent.service.store.update_status(sid, "awaiting_impact_confirm")
|
||||
rec = agent.service.get_session(sid)
|
||||
r = agent._run_generate(sid, rec, [], output_language="auto")
|
||||
# confirm_impact 先执行(line 194),随后 generate 因缺文件抛错被捕获
|
||||
assert r["status"] in ("writing", "awaiting_impact_confirm")
|
||||
|
||||
|
||||
def test_run_impact_from_awaiting_parse_confirm(tmp_path):
|
||||
from genesis.server.store import ProjectsStore
|
||||
store = SessionStore(db_path=str(tmp_path / "s.db"))
|
||||
code = tmp_path / "code"; code.mkdir(); (code / "A.java").write_text("class A {}")
|
||||
projects = ProjectsStore(db_path=str(tmp_path / "p.db"))
|
||||
projects.upsert(name="projA", display_name="P", template="", write_instruction="",
|
||||
rules=[], existing_system_code_dir=str(code), design_docs_dir="")
|
||||
agent = ChatAgent(GenesisService(store=store, data_root=str(tmp_path / "data"),
|
||||
engine=FakeEngine(), projects=projects), fake=True)
|
||||
sid = agent.service.create_session("u1", project="projA").session_id
|
||||
agent.service.store.update_status(sid, "awaiting_parse_confirm")
|
||||
r = agent._run_impact(sid, [])
|
||||
assert r["status"] == "awaiting_impact_confirm"
|
||||
|
||||
|
||||
def test_impact_brief_malformed_returns_default(tmp_path):
|
||||
agent = ChatAgent(_svc(tmp_path), fake=True)
|
||||
rec = agent.service.create_session("u1")
|
||||
rec.impact_summary = "not-json"
|
||||
assert agent._impact_brief(rec) == "已完成"
|
||||
|
||||
|
||||
def test_generate_without_files_hints_upload(tmp_path):
|
||||
agent = ChatAgent(_svc(tmp_path), fake=True)
|
||||
sid = agent.service.create_session("u1").session_id
|
||||
|
||||
Reference in New Issue
Block a user