feat: 数据模型 data_models(design §3+§9.4,future.annotations)
This commit is contained in:
@@ -0,0 +1,225 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@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]
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
from dataclasses import asdict
|
||||||
|
|
||||||
|
from genesis.data_models import (
|
||||||
|
CellComment, CellFormatting, CellValue, Confidence, ElementType,
|
||||||
|
ExcelTable, ExtractionMethod, ImageAnalysis, ParsedTemplate, Provenance,
|
||||||
|
RelationType, RuleDocument, SheetType, StructuredSource,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_sheettype_has_8_members():
|
||||||
|
assert len(SheetType) == 8
|
||||||
|
assert SheetType.FUNCTION.value == "FUNCTION"
|
||||||
|
assert SheetType.GENERIC.value == "GENERIC"
|
||||||
|
|
||||||
|
|
||||||
|
def test_value_enum_members():
|
||||||
|
assert ElementType.FUNCTION.value == "機能"
|
||||||
|
assert RelationType.USE.value == "利用"
|
||||||
|
assert Confidence.HIGH.value == "high"
|
||||||
|
assert ExtractionMethod.OPENPYXL.value == "openpyxl"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cellformatting_defaults():
|
||||||
|
fmt = CellFormatting()
|
||||||
|
assert fmt.strikethrough is False
|
||||||
|
assert fmt.font_color is None
|
||||||
|
assert fmt.bg_color is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_cellvalue_forward_reference_works():
|
||||||
|
"""CellValue 引用后置定义的 CellFormatting/CellComment(future.annotations 落地)"""
|
||||||
|
prov = Provenance(file_name="f.xlsx", sheet_name="S", row=1, column="A", column_header="h")
|
||||||
|
cv = CellValue(
|
||||||
|
value="x",
|
||||||
|
provenance=prov,
|
||||||
|
formatting=CellFormatting(strikethrough=True),
|
||||||
|
comment=CellComment(author="reviewer", text="check", source_uri="f.xlsx#S!A1"),
|
||||||
|
)
|
||||||
|
assert cv.formatting.strikethrough is True
|
||||||
|
assert cv.comment.author == "reviewer"
|
||||||
|
|
||||||
|
|
||||||
|
def test_excel_table_references_sheettype():
|
||||||
|
table = ExcelTable(
|
||||||
|
name="機能一覧",
|
||||||
|
detected_type=SheetType.FUNCTION,
|
||||||
|
extraction_method=ExtractionMethod.OPENPYXL.value,
|
||||||
|
headers=["機能ID", "機能名"],
|
||||||
|
rows=[],
|
||||||
|
)
|
||||||
|
assert table.detected_type is SheetType.FUNCTION
|
||||||
|
assert table.extraction_method == "openpyxl"
|
||||||
|
|
||||||
|
|
||||||
|
def test_structured_source_assembles_all():
|
||||||
|
source = StructuredSource(
|
||||||
|
tables=[],
|
||||||
|
template=ParsedTemplate(file_name="t.docx", sections=[], placeholders={}, styles={}),
|
||||||
|
rule_docs=[RuleDocument(
|
||||||
|
file_name="記入規則.docx", category="write", markdown_content="# 規則",
|
||||||
|
source_path="samples/記入規則.docx", file_type="word", hash="abc",
|
||||||
|
)],
|
||||||
|
image_analyses=[ImageAnalysis(
|
||||||
|
image_ref="img1", description="画面遷移図", confidence=0.9,
|
||||||
|
source_uri="f.xlsx#S!A1", sheet_name="S", anchor_cell="A1", status="recognized",
|
||||||
|
)],
|
||||||
|
existing_system=None,
|
||||||
|
comments=[],
|
||||||
|
)
|
||||||
|
assert source.rule_docs[0].category == "write"
|
||||||
|
assert source.image_analyses[0].nearby_text == ""
|
||||||
|
|
||||||
|
|
||||||
|
def test_asdict_serializable():
|
||||||
|
prov = Provenance(file_name="f.xlsx", sheet_name="S", row=1, column="A", column_header="h")
|
||||||
|
d = asdict(CellValue(value=1, provenance=prov))
|
||||||
|
assert d["provenance"]["row"] == 1
|
||||||
Reference in New Issue
Block a user