feat(graph): map node status from FileStatus via source_file (GAP-B1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4cf039e029
commit
4d70df76fc
|
|
@ -16,15 +16,28 @@ _GROUPS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
_SOURCE_FILES: dict[str, str] = {
|
||||||
|
"capability": "business-architecture/02-capability-map.csv",
|
||||||
|
"module": "application-architecture/02-modules.csv",
|
||||||
|
"entity": "data-architecture/01-entities.csv",
|
||||||
|
"runtime_component": "technology-architecture/01-runtime-components.csv",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class GraphService:
|
class GraphService:
|
||||||
"""Constructs a panorama graph and supports neighbor queries."""
|
"""Constructs a panorama graph and supports neighbor queries."""
|
||||||
|
|
||||||
def build_panorama(self, scan_result: ScanResult) -> GraphView:
|
def build_panorama(self, scan_result: ScanResult, *, design_dir: str = "") -> GraphView:
|
||||||
"""Build a full panorama GraphView from a ScanResult (9-step algorithm)."""
|
"""Build a full panorama GraphView from a ScanResult (9-step algorithm)."""
|
||||||
nodes: list[GraphNode] = []
|
nodes: list[GraphNode] = []
|
||||||
edges: list[GraphEdge] = []
|
edges: list[GraphEdge] = []
|
||||||
node_ids: set[str] = set()
|
node_ids: set[str] = set()
|
||||||
|
|
||||||
|
# Build file-status lookup from ScanResult
|
||||||
|
file_status_map: dict[str, str] = {
|
||||||
|
fs.path: fs.status.value for fs in scan_result.file_statuses
|
||||||
|
}
|
||||||
|
|
||||||
# Step 1: groups are always the fixed 5
|
# Step 1: groups are always the fixed 5
|
||||||
groups = list(_GROUPS)
|
groups = list(_GROUPS)
|
||||||
|
|
||||||
|
|
@ -35,7 +48,7 @@ class GraphService:
|
||||||
id=node_id,
|
id=node_id,
|
||||||
type="capability",
|
type="capability",
|
||||||
label=cap.name,
|
label=cap.name,
|
||||||
status="unknown",
|
status=file_status_map.get(_SOURCE_FILES["capability"], "unknown"),
|
||||||
group_id="business",
|
group_id="business",
|
||||||
))
|
))
|
||||||
node_ids.add(node_id)
|
node_ids.add(node_id)
|
||||||
|
|
@ -47,7 +60,7 @@ class GraphService:
|
||||||
id=node_id,
|
id=node_id,
|
||||||
type="module",
|
type="module",
|
||||||
label=mod.name,
|
label=mod.name,
|
||||||
status="unknown",
|
status=file_status_map.get(_SOURCE_FILES["module"], "unknown"),
|
||||||
group_id="application",
|
group_id="application",
|
||||||
))
|
))
|
||||||
node_ids.add(node_id)
|
node_ids.add(node_id)
|
||||||
|
|
@ -59,7 +72,7 @@ class GraphService:
|
||||||
id=node_id,
|
id=node_id,
|
||||||
type="entity",
|
type="entity",
|
||||||
label=ent.name,
|
label=ent.name,
|
||||||
status="unknown",
|
status=file_status_map.get(_SOURCE_FILES["entity"], "unknown"),
|
||||||
group_id="data",
|
group_id="data",
|
||||||
))
|
))
|
||||||
node_ids.add(node_id)
|
node_ids.add(node_id)
|
||||||
|
|
@ -71,7 +84,7 @@ class GraphService:
|
||||||
id=node_id,
|
id=node_id,
|
||||||
type="runtime_component",
|
type="runtime_component",
|
||||||
label=rc.name,
|
label=rc.name,
|
||||||
status="unknown",
|
status=file_status_map.get(_SOURCE_FILES["runtime_component"], "unknown"),
|
||||||
group_id="technology",
|
group_id="technology",
|
||||||
))
|
))
|
||||||
node_ids.add(node_id)
|
node_ids.add(node_id)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,11 @@ def scan_result():
|
||||||
return svc.scan(project)
|
return svc.scan(project)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def design_dir():
|
||||||
|
return "/workspace/arch-design-agent-skill-dashboard/design"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def graph_service():
|
def graph_service():
|
||||||
return GraphService()
|
return GraphService()
|
||||||
|
|
@ -86,3 +91,16 @@ def test_graph_node_has_parent_field(graph_service, scan_result):
|
||||||
view = graph_service.build_panorama(scan_result)
|
view = graph_service.build_panorama(scan_result)
|
||||||
for node in view.nodes:
|
for node in view.nodes:
|
||||||
assert hasattr(node, 'parent')
|
assert hasattr(node, 'parent')
|
||||||
|
|
||||||
|
|
||||||
|
def test_panorama_nodes_have_real_status(graph_service, scan_result, design_dir):
|
||||||
|
view = graph_service.build_panorama(scan_result, design_dir=design_dir)
|
||||||
|
statuses = {n.status for n in view.nodes}
|
||||||
|
assert statuses != {"unknown"}, "All nodes still have status='unknown' — status mapping not working"
|
||||||
|
|
||||||
|
|
||||||
|
def test_panorama_status_values_are_valid(graph_service, scan_result, design_dir):
|
||||||
|
view = graph_service.build_panorama(scan_result, design_dir=design_dir)
|
||||||
|
valid_statuses = {"ok", "sparse", "missing", "template-residue", "placeholder-heavy", "unknown"}
|
||||||
|
for node in view.nodes:
|
||||||
|
assert node.status in valid_statuses, f"Node {node.id} has invalid status '{node.status}'"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user