- 会话支持 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%
300 lines
7.4 KiB
Python
300 lines
7.4 KiB
Python
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass, field
|
||
from enum import Enum
|
||
from typing import Any, Literal
|
||
|
||
|
||
class SheetType(Enum):
|
||
"""Excel Sheet 的类型(Parser SheetDetector 判定结果)"""
|
||
FUNCTION = "FUNCTION"
|
||
SCREEN = "SCREEN"
|
||
REPORT = "REPORT"
|
||
DATABASE = "DATABASE"
|
||
INTERFACE = "INTERFACE"
|
||
BATCH = "BATCH"
|
||
MASTER = "MASTER"
|
||
GENERIC = "GENERIC"
|
||
|
||
|
||
class ElementType(Enum):
|
||
"""Impact Agent 抽取的构成要素类型"""
|
||
FUNCTION = "機能"
|
||
SCREEN = "画面"
|
||
REPORT = "帳票"
|
||
DB = "DB"
|
||
IF = "IF"
|
||
BATCH = "バッチ"
|
||
|
||
|
||
class RelationType(Enum):
|
||
"""关联类型(Impact Agent 推理结果)"""
|
||
USE = "利用"
|
||
REFER = "参照"
|
||
UPDATE = "更新"
|
||
OUTPUT = "输出"
|
||
INPUT = "输入"
|
||
DEPEND = "依赖"
|
||
|
||
|
||
class Confidence(Enum):
|
||
"""置信度等级"""
|
||
HIGH = "high"
|
||
MEDIUM = "medium"
|
||
LOW = "low"
|
||
|
||
|
||
class ExtractionMethod(Enum):
|
||
"""Excel 表的抽取方式"""
|
||
OPENPYXL = "openpyxl"
|
||
LLM_FROM_FREE_TEXT = "llm_from_free_text"
|
||
|
||
|
||
@dataclass
|
||
class Provenance:
|
||
file_name: str
|
||
sheet_name: str
|
||
row: int # 数据行号(从 1 起:表格为物理行-表头行;自由文本为块序)
|
||
column: str
|
||
column_header: str
|
||
|
||
|
||
@dataclass
|
||
class CellFormatting:
|
||
strikethrough: bool = False
|
||
font_color: str | None = None
|
||
bg_color: str | None = None
|
||
|
||
|
||
@dataclass
|
||
class CellComment:
|
||
author: str
|
||
text: str
|
||
source_uri: str
|
||
|
||
|
||
@dataclass
|
||
class CellValue:
|
||
value: Any
|
||
provenance: Provenance
|
||
formatting: CellFormatting | None = None
|
||
comment: CellComment | None = None
|
||
|
||
|
||
@dataclass
|
||
class ExcelTable:
|
||
name: str
|
||
detected_type: SheetType
|
||
extraction_method: str # 取 ExtractionMethod 的 value(同一常量来源)
|
||
headers: list[str]
|
||
rows: list[dict[str, "CellValue"]]
|
||
|
||
|
||
@dataclass
|
||
class ChapterMarker:
|
||
type: str # "heading" | "bookmark" | "placeholder"
|
||
name: str
|
||
level: int
|
||
|
||
|
||
@dataclass
|
||
class ParsedTemplate:
|
||
file_name: str
|
||
sections: list[ChapterMarker]
|
||
placeholders: dict[str, str]
|
||
styles: dict
|
||
|
||
|
||
@dataclass
|
||
class RuleDocument:
|
||
file_name: str
|
||
category: str # "write" | "design" | "ref"
|
||
markdown_content: str
|
||
source_path: str
|
||
file_type: str # "word" | "excel" | "ppt"
|
||
hash: str
|
||
|
||
|
||
@dataclass
|
||
class ImageAnalysis:
|
||
"""图片分析结果(Parser 组装,StructuredSource 消费)"""
|
||
image_ref: str
|
||
description: str
|
||
confidence: float
|
||
source_uri: str
|
||
sheet_name: str
|
||
anchor_cell: str
|
||
status: str # "recognized" | "recorded_only" | "failed"
|
||
nearby_text: str = ""
|
||
|
||
|
||
@dataclass
|
||
class ControllerInfo:
|
||
name: str
|
||
class_name: str
|
||
path: str
|
||
base_path: str
|
||
endpoints: list[str]
|
||
source_uri: str
|
||
|
||
|
||
@dataclass
|
||
class ServiceInfo:
|
||
name: str
|
||
class_name: str
|
||
path: str
|
||
methods: list[str]
|
||
source_uri: str
|
||
|
||
|
||
@dataclass
|
||
class EntityInfo:
|
||
name: str
|
||
class_name: str
|
||
path: str
|
||
table_name: str | None
|
||
fields: list[str]
|
||
source_uri: str
|
||
|
||
|
||
@dataclass
|
||
class EndpointInfo:
|
||
method: str
|
||
path: str
|
||
controller: str | None
|
||
description: str
|
||
source_uri: str
|
||
|
||
|
||
@dataclass
|
||
class ExistingSystemInfo:
|
||
controller_layer: list[ControllerInfo]
|
||
service_layer: list[ServiceInfo]
|
||
entity_layer: list[EntityInfo]
|
||
api_endpoints: list[EndpointInfo]
|
||
source_path: str
|
||
|
||
|
||
class ChangeType(Enum):
|
||
"""变更点定位的变更区分(对应要件定義 変更区分 列值)"""
|
||
NEW = "新規"
|
||
MODIFIED = "変更"
|
||
DELETED = "削除"
|
||
UNCHANGED = "不变"
|
||
|
||
|
||
@dataclass
|
||
class ChangeElement:
|
||
"""变更点定位结果中的一个要素(Impact Agent MVP)"""
|
||
element_id: str
|
||
element_type: str # 機能/画面/帳票/DB/IF/バッチ(取 ElementType.value 或表名)
|
||
name: str
|
||
change_type: ChangeType
|
||
existing_mapping: list[str] = field(default_factory=list) # 既存対応 声明值(类名清单)
|
||
impacted_existing: list[str] = field(default_factory=list) # 确认命中的既有类
|
||
evidence: str = "" # 命中的既有类 source_uri / 空
|
||
status: str = "ok" # "ok" | "conflict" | "warning"
|
||
|
||
|
||
@dataclass
|
||
class ImpactWarning:
|
||
"""影响调查告警(不阻断,供用户/QA 关注)"""
|
||
element_id: str
|
||
issue: str
|
||
|
||
|
||
@dataclass
|
||
class ChangeAnalysis:
|
||
"""变更点定位结果集合(Impact Agent MVP)"""
|
||
project_type: str # "enhancement"(追加改修)
|
||
new_elements: list[ChangeElement]
|
||
modified_elements: list[ChangeElement]
|
||
deleted_elements: list[ChangeElement]
|
||
unchanged_elements: list[ChangeElement]
|
||
warnings: list[ImpactWarning]
|
||
|
||
|
||
@dataclass
|
||
class DesignReference:
|
||
"""既有设计文档命中引用(Type A 确定性交叉引用)"""
|
||
doc_name: str # 设计文档文件名
|
||
identifier: str # 命中的代码/表标识符
|
||
snippet: str # 摘录(前后文片段)
|
||
|
||
|
||
@dataclass
|
||
class ImpactReport:
|
||
"""影响调查书(MVP 子集,供 Writer 生成 + 独立下载)"""
|
||
metadata: dict
|
||
change_analysis: ChangeAnalysis | None = None
|
||
summary: dict = field(default_factory=dict)
|
||
design_references: list[DesignReference] = field(default_factory=list) # 设计文档命中
|
||
|
||
|
||
@dataclass
|
||
class UnifiedDocument:
|
||
"""FileReader 的统一输出(多格式归一化)"""
|
||
file_name: str
|
||
file_type: str # "excel" | "word" | "ppt" | "text"
|
||
source_path: str
|
||
content_type: str
|
||
tables: list[list[list[Any]]] | None = None
|
||
sheet_names: list[str] | None = None
|
||
paragraphs: list[dict] | None = None
|
||
slides: list[dict] | None = None
|
||
text: str | None = None
|
||
encoding: str | None = None
|
||
|
||
|
||
@dataclass
|
||
class CodeStructure:
|
||
"""CodeParser 的解析输出"""
|
||
root_path: str
|
||
language: str
|
||
modules: list[dict]
|
||
classes: list[dict]
|
||
controllers: list[ControllerInfo]
|
||
services: list[ServiceInfo]
|
||
entities: list[EntityInfo]
|
||
endpoints: list[EndpointInfo]
|
||
raw_imports: list[dict]
|
||
|
||
|
||
@dataclass
|
||
class ImageDescription:
|
||
"""ImageAnalyzer 的原始识别输出(工具层;业务侧用 ImageAnalysis)"""
|
||
image_ref: str
|
||
description: str
|
||
objects: list[str]
|
||
ocr_text: str | None
|
||
confidence: float
|
||
model: str
|
||
|
||
|
||
@dataclass
|
||
class StructuredSource:
|
||
tables: list[ExcelTable]
|
||
template: ParsedTemplate
|
||
rule_docs: list[RuleDocument]
|
||
image_analyses: list[ImageAnalysis]
|
||
existing_system: ExistingSystemInfo | None
|
||
comments: list[CellComment]
|
||
design_docs: list[RuleDocument] = field(default_factory=list) # 既有系统设计文档(Type A,仅参考不做写入规则)
|
||
impact_report: "ImpactReport | None" = None # 影响调查书(生成后回填,门控未提供时为 None)
|
||
|
||
|
||
@dataclass
|
||
class MixedParagraph:
|
||
"""混合 sheet 的一个段落(表格或自由文本)"""
|
||
kind: Literal["table", "free_text"]
|
||
matrix: list[list[Any]] | None = None # 该段原始矩阵(调试/重现)
|
||
table: ExcelTable | None = None # kind="table" 时填充
|
||
text: str | None = None # kind="free_text" 时填充(段全文)
|
||
source_range: tuple[int, int] | None = None # (first_row, last_row) 矩阵 0-based
|
||
|
||
|
||
@dataclass
|
||
class MixedSheet:
|
||
"""混合 sheet 的段落集合"""
|
||
name: str
|
||
paragraphs: list[MixedParagraph] = field(default_factory=list) |