Coverage for src\genesis\data_models.py: 100%
213 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 14:20 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 14:20 +0800
1from __future__ import annotations
3from dataclasses import dataclass, field
4from enum import Enum
5from typing import Any, Literal
8class SheetType(Enum):
9 """Excel Sheet 的类型(Parser SheetDetector 判定结果)"""
10 FUNCTION = "FUNCTION"
11 SCREEN = "SCREEN"
12 REPORT = "REPORT"
13 DATABASE = "DATABASE"
14 INTERFACE = "INTERFACE"
15 BATCH = "BATCH"
16 MASTER = "MASTER"
17 GENERIC = "GENERIC"
20class ElementType(Enum):
21 """Impact Agent 抽取的构成要素类型"""
22 FUNCTION = "機能"
23 SCREEN = "画面"
24 REPORT = "帳票"
25 DB = "DB"
26 IF = "IF"
27 BATCH = "バッチ"
30class RelationType(Enum):
31 """关联类型(Impact Agent 推理结果)"""
32 USE = "利用"
33 REFER = "参照"
34 UPDATE = "更新"
35 OUTPUT = "输出"
36 INPUT = "输入"
37 DEPEND = "依赖"
40class Confidence(Enum):
41 """置信度等级"""
42 HIGH = "high"
43 MEDIUM = "medium"
44 LOW = "low"
47class ExtractionMethod(Enum):
48 """Excel 表的抽取方式"""
49 OPENPYXL = "openpyxl"
50 LLM_FROM_FREE_TEXT = "llm_from_free_text"
53@dataclass
54class Provenance:
55 file_name: str
56 sheet_name: str
57 row: int # 数据行号(从 1 起:表格为物理行-表头行;自由文本为块序)
58 column: str
59 column_header: str
62@dataclass
63class CellFormatting:
64 strikethrough: bool = False
65 font_color: str | None = None
66 bg_color: str | None = None
69@dataclass
70class CellComment:
71 author: str
72 text: str
73 source_uri: str
76@dataclass
77class CellValue:
78 value: Any
79 provenance: Provenance
80 formatting: CellFormatting | None = None
81 comment: CellComment | None = None
84@dataclass
85class ExcelTable:
86 name: str
87 detected_type: SheetType
88 extraction_method: str # 取 ExtractionMethod 的 value(同一常量来源)
89 headers: list[str]
90 rows: list[dict[str, "CellValue"]]
93@dataclass
94class ChapterMarker:
95 type: str # "heading" | "bookmark" | "placeholder"
96 name: str
97 level: int
100@dataclass
101class ParsedTemplate:
102 file_name: str
103 sections: list[ChapterMarker]
104 placeholders: dict[str, str]
105 styles: dict
108@dataclass
109class RuleDocument:
110 file_name: str
111 category: str # "write" | "design" | "ref"
112 markdown_content: str
113 source_path: str
114 file_type: str # "word" | "excel" | "ppt"
115 hash: str
118@dataclass
119class ImageAnalysis:
120 """图片分析结果(Parser 组装,StructuredSource 消费)"""
121 image_ref: str
122 description: str
123 confidence: float
124 source_uri: str
125 sheet_name: str
126 anchor_cell: str
127 status: str # "recognized" | "recorded_only" | "failed"
128 nearby_text: str = ""
131@dataclass
132class ControllerInfo:
133 name: str
134 class_name: str
135 path: str
136 base_path: str
137 endpoints: list[str]
138 source_uri: str
141@dataclass
142class ServiceInfo:
143 name: str
144 class_name: str
145 path: str
146 methods: list[str]
147 source_uri: str
150@dataclass
151class EntityInfo:
152 name: str
153 class_name: str
154 path: str
155 table_name: str | None
156 fields: list[str]
157 source_uri: str
160@dataclass
161class EndpointInfo:
162 method: str
163 path: str
164 controller: str | None
165 description: str
166 source_uri: str
169@dataclass
170class ExistingSystemInfo:
171 controller_layer: list[ControllerInfo]
172 service_layer: list[ServiceInfo]
173 entity_layer: list[EntityInfo]
174 api_endpoints: list[EndpointInfo]
175 source_path: str
178class ChangeType(Enum):
179 """变更点定位的变更区分(对应要件定義 変更区分 列值)"""
180 NEW = "新規"
181 MODIFIED = "変更"
182 DELETED = "削除"
183 UNCHANGED = "不变"
186@dataclass
187class ChangeElement:
188 """变更点定位结果中的一个要素(Impact Agent MVP)"""
189 element_id: str
190 element_type: str # 機能/画面/帳票/DB/IF/バッチ(取 ElementType.value 或表名)
191 name: str
192 change_type: ChangeType
193 existing_mapping: list[str] = field(default_factory=list) # 既存対応 声明值(类名清单)
194 impacted_existing: list[str] = field(default_factory=list) # 确认命中的既有类
195 evidence: str = "" # 命中的既有类 source_uri / 空
196 status: str = "ok" # "ok" | "conflict" | "warning"
199@dataclass
200class ImpactWarning:
201 """影响调查告警(不阻断,供用户/QA 关注)"""
202 element_id: str
203 issue: str
206@dataclass
207class ChangeAnalysis:
208 """变更点定位结果集合(Impact Agent MVP)"""
209 project_type: str # "enhancement"(追加改修)
210 new_elements: list[ChangeElement]
211 modified_elements: list[ChangeElement]
212 deleted_elements: list[ChangeElement]
213 unchanged_elements: list[ChangeElement]
214 warnings: list[ImpactWarning]
217@dataclass
218class ImpactReport:
219 """影响调查书(MVP 子集,供 Writer 生成 + 独立下载)"""
220 metadata: dict
221 change_analysis: ChangeAnalysis | None = None
222 summary: dict = field(default_factory=dict)
225@dataclass
226class UnifiedDocument:
227 """FileReader 的统一输出(多格式归一化)"""
228 file_name: str
229 file_type: str # "excel" | "word" | "ppt" | "text"
230 source_path: str
231 content_type: str
232 tables: list[list[list[Any]]] | None = None
233 sheet_names: list[str] | None = None
234 paragraphs: list[dict] | None = None
235 slides: list[dict] | None = None
236 text: str | None = None
237 encoding: str | None = None
240@dataclass
241class CodeStructure:
242 """CodeParser 的解析输出"""
243 root_path: str
244 language: str
245 modules: list[dict]
246 classes: list[dict]
247 controllers: list[ControllerInfo]
248 services: list[ServiceInfo]
249 entities: list[EntityInfo]
250 endpoints: list[EndpointInfo]
251 raw_imports: list[dict]
254@dataclass
255class ImageDescription:
256 """ImageAnalyzer 的原始识别输出(工具层;业务侧用 ImageAnalysis)"""
257 image_ref: str
258 description: str
259 objects: list[str]
260 ocr_text: str | None
261 confidence: float
262 model: str
265@dataclass
266class StructuredSource:
267 tables: list[ExcelTable]
268 template: ParsedTemplate
269 rule_docs: list[RuleDocument]
270 image_analyses: list[ImageAnalysis]
271 existing_system: ExistingSystemInfo | None
272 comments: list[CellComment]
273 impact_report: "ImpactReport | None" = None # 影响调查书(生成后回填,门控未提供时为 None)
276@dataclass
277class MixedParagraph:
278 """混合 sheet 的一个段落(表格或自由文本)"""
279 kind: Literal["table", "free_text"]
280 matrix: list[list[Any]] | None = None # 该段原始矩阵(调试/重现)
281 table: ExcelTable | None = None # kind="table" 时填充
282 text: str | None = None # kind="free_text" 时填充(段全文)
283 source_range: tuple[int, int] | None = None # (first_row, last_row) 矩阵 0-based
286@dataclass
287class MixedSheet:
288 """混合 sheet 的段落集合"""
289 name: str
290 paragraphs: list[MixedParagraph] = field(default_factory=list)