feat: implement full arch design dashboard #1
760
docs/superpowers/specs/2026-03-23-full-implementation-design.md
Normal file
760
docs/superpowers/specs/2026-03-23-full-implementation-design.md
Normal file
|
|
@ -0,0 +1,760 @@
|
||||||
|
# Arch Design Dashboard — 全量实现设计规格
|
||||||
|
|
||||||
|
## 1. 概述
|
||||||
|
|
||||||
|
将 `design/` 目录下完整的架构设计文档转化为可运行的 Web 应用。系统是单体前后端分离架构,单人使用(无认证),设计文件为 single source of truth(无数据库)。
|
||||||
|
|
||||||
|
**实现范围:** MVP + Phase 2 全部功能。
|
||||||
|
|
||||||
|
**技术栈:**
|
||||||
|
- 后端:Python 3.12 + FastAPI + Uvicorn,包管理用 uv
|
||||||
|
- 前端:Vue 3 + TypeScript + Vite + Pinia + D3.js
|
||||||
|
- 部署:Docker Compose + Nginx 反代
|
||||||
|
|
||||||
|
## 2. 模块清单与实现顺序
|
||||||
|
|
||||||
|
全局顺序(自底向上):构建配置 → shared → design → project → scanner → graph → editor → impl_tracker → 前端
|
||||||
|
|
||||||
|
每个后端模块内部顺序:**Domain → Infrastructure → Application → Interfaces**
|
||||||
|
|
||||||
|
| # | 模块 | 层 | 依赖 | 阶段 |
|
||||||
|
|---|------|------|------|------|
|
||||||
|
| 0 | 构建配置 | - | - | MVP |
|
||||||
|
| 1 | shared | backend | - | MVP |
|
||||||
|
| 2 | MOD-DESIGN | backend domain-only | - | MVP |
|
||||||
|
| 3 | MOD-PROJECT | backend full | - | MVP |
|
||||||
|
| 4 | MOD-SCANNER | backend full | MOD-DESIGN | MVP |
|
||||||
|
| 5 | MOD-GRAPH | backend full | MOD-DESIGN | MVP |
|
||||||
|
| 6 | MOD-EDITOR | backend full | MOD-DESIGN, MOD-SCANNER, MOD-GRAPH | Phase 2 |
|
||||||
|
| 7 | MOD-IMPL-TRACKER | backend full | MOD-DESIGN, MOD-SCANNER | Phase 2 |
|
||||||
|
| 8 | 前端基础设施 | frontend | - | MVP |
|
||||||
|
| 9 | MOD-FE-PROJECT | frontend | 后端 MOD-PROJECT | MVP |
|
||||||
|
| 10 | MOD-FE-GRAPH | frontend | 后端 MOD-SCANNER, MOD-GRAPH | MVP |
|
||||||
|
| 11 | MOD-FE-EDITOR | frontend | 后端 MOD-EDITOR, MOD-IMPL-TRACKER | Phase 2 |
|
||||||
|
| 12 | Docker 部署 | infra | 前后端完成 | MVP |
|
||||||
|
|
||||||
|
## 3. 后端详细设计
|
||||||
|
|
||||||
|
### 3.0 构建配置
|
||||||
|
|
||||||
|
- `backend/pyproject.toml`:Python 3.12+,依赖 fastapi, uvicorn, pyyaml, python-multipart
|
||||||
|
- `backend/.python-version`:3.12
|
||||||
|
- `frontend/package.json`:vue 3, vue-router, pinia, d3, axios, vite, typescript
|
||||||
|
- `frontend/vite.config.ts`:dev proxy `/api` → `localhost:8900`
|
||||||
|
- `frontend/tsconfig.json`
|
||||||
|
- `frontend/index.html`
|
||||||
|
|
||||||
|
### 3.1 shared 层
|
||||||
|
|
||||||
|
**shared/kernel/exceptions.py**:
|
||||||
|
- `NotFoundError(entity: str, id: str)` — 404
|
||||||
|
- `ValidationError(message: str)` — 400
|
||||||
|
- `FileSystemError(path: str, message: str)` — 500
|
||||||
|
|
||||||
|
**shared/infrastructure/config.py**:
|
||||||
|
- `Settings` dataclass:registry_path(projects.json 路径,默认 `~/.arch-design-dashboard/projects.json`)
|
||||||
|
|
||||||
|
**shared/infrastructure/filesystem.py**:
|
||||||
|
- `read_text(path) -> str`
|
||||||
|
- `write_text(path, content)`
|
||||||
|
- `list_files(directory, extensions) -> list[Path]`
|
||||||
|
- `file_exists(path) -> bool`
|
||||||
|
|
||||||
|
### 3.2 MOD-DESIGN(核心领域,纯 Python)
|
||||||
|
|
||||||
|
**domain/entities.py** — 28 种设计实体,用 `@dataclass` 定义:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 业务层
|
||||||
|
@dataclass
|
||||||
|
class Capability:
|
||||||
|
capability_id: str
|
||||||
|
name: str
|
||||||
|
description: str
|
||||||
|
priority: str # must / should / could
|
||||||
|
phase: str
|
||||||
|
related_value_flows: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ValueFlow:
|
||||||
|
value_flow_id: str
|
||||||
|
name: str
|
||||||
|
trigger: str
|
||||||
|
actor: str
|
||||||
|
steps: str
|
||||||
|
outcome: str
|
||||||
|
phase: str
|
||||||
|
related_capabilities: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class UserJourney:
|
||||||
|
journey_id: str
|
||||||
|
name: str
|
||||||
|
actor: str
|
||||||
|
precondition: str
|
||||||
|
steps: str
|
||||||
|
postcondition: str
|
||||||
|
phase: str
|
||||||
|
related_value_flows: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ScopeAndGoals:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
core_problem: str
|
||||||
|
users: str
|
||||||
|
constraints: str
|
||||||
|
|
||||||
|
# 应用层
|
||||||
|
@dataclass
|
||||||
|
class Module:
|
||||||
|
module_id: str
|
||||||
|
name: str
|
||||||
|
layer: str # backend / frontend
|
||||||
|
description: str
|
||||||
|
phase: str
|
||||||
|
depends_on: list[str]
|
||||||
|
capabilities: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Integration:
|
||||||
|
integration_id: str
|
||||||
|
source_id: str
|
||||||
|
target_id: str
|
||||||
|
target_type: str
|
||||||
|
direction: str
|
||||||
|
protocol: str
|
||||||
|
trigger: str
|
||||||
|
phase: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ExternalSystem:
|
||||||
|
system_id: str
|
||||||
|
name: str
|
||||||
|
type: str
|
||||||
|
protocol: str
|
||||||
|
direction: str
|
||||||
|
phase: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApiContract:
|
||||||
|
doc_id: str
|
||||||
|
path: str
|
||||||
|
method: str
|
||||||
|
operation_id: str
|
||||||
|
summary: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CodebaseAlignment:
|
||||||
|
module_id: str
|
||||||
|
repo_root: str
|
||||||
|
code_root: str
|
||||||
|
package_name: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ModuleBoundaryRule:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SystemContext:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SolutionLayer:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
# 数据层
|
||||||
|
@dataclass
|
||||||
|
class Entity:
|
||||||
|
entity_id: str
|
||||||
|
name: str
|
||||||
|
domain: str
|
||||||
|
owner_module: str
|
||||||
|
description: str
|
||||||
|
phase: str
|
||||||
|
source_file: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataFlow:
|
||||||
|
data_flow_id: str
|
||||||
|
source: str
|
||||||
|
target: str
|
||||||
|
data_content: str
|
||||||
|
trigger: str
|
||||||
|
protocol: str
|
||||||
|
phase: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataSecurity:
|
||||||
|
security_id: str
|
||||||
|
sensitivity: str
|
||||||
|
entities: str
|
||||||
|
protection: str
|
||||||
|
|
||||||
|
# 技术层
|
||||||
|
@dataclass
|
||||||
|
class TechSelection:
|
||||||
|
category: str
|
||||||
|
technology: str
|
||||||
|
version: str
|
||||||
|
purpose: str
|
||||||
|
rationale: str
|
||||||
|
alternatives_considered: str
|
||||||
|
phase: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RuntimeComponent:
|
||||||
|
component_id: str
|
||||||
|
name: str
|
||||||
|
type: str
|
||||||
|
technology: str
|
||||||
|
port: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RuntimeTopology:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Environment:
|
||||||
|
env_id: str
|
||||||
|
name: str
|
||||||
|
purpose: str
|
||||||
|
infra: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OperationalBaseline:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ReleasePlan:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
content: str
|
||||||
|
|
||||||
|
# 跨层
|
||||||
|
@dataclass
|
||||||
|
class TraceabilityLink:
|
||||||
|
trace_id: str
|
||||||
|
capability_id: str
|
||||||
|
module_id: str
|
||||||
|
entity_ids: list[str]
|
||||||
|
value_flow_ids: list[str]
|
||||||
|
notes: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ChangeLogEntry:
|
||||||
|
change_id: str
|
||||||
|
date: str
|
||||||
|
scope: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ADR:
|
||||||
|
adr_id: str
|
||||||
|
title: str
|
||||||
|
status: str
|
||||||
|
context: str
|
||||||
|
decision: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DesignDocument:
|
||||||
|
doc_id: str
|
||||||
|
title: str
|
||||||
|
version: str
|
||||||
|
status: str
|
||||||
|
owners: list[str]
|
||||||
|
upstream: list[str]
|
||||||
|
downstream: list[str]
|
||||||
|
file_path: str
|
||||||
|
|
||||||
|
# 领域层
|
||||||
|
@dataclass
|
||||||
|
class Domain:
|
||||||
|
domain_name: str
|
||||||
|
overview: str
|
||||||
|
modules: list[str]
|
||||||
|
entities: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class UbiquitousTerm:
|
||||||
|
term_id: str
|
||||||
|
term: str
|
||||||
|
english_term: str
|
||||||
|
code_symbol: str
|
||||||
|
domain: str
|
||||||
|
definition: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SharedTerm:
|
||||||
|
term_id: str
|
||||||
|
term: str
|
||||||
|
english_term: str
|
||||||
|
definition: str
|
||||||
|
used_by_domains: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Scenario:
|
||||||
|
scenario_id: str
|
||||||
|
name: str
|
||||||
|
trigger: str
|
||||||
|
actors: str
|
||||||
|
steps: str
|
||||||
|
outcome: str
|
||||||
|
related_capabilities: list[str]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DomainModule:
|
||||||
|
module_id: str
|
||||||
|
module_name: str
|
||||||
|
domain: str
|
||||||
|
description: str
|
||||||
|
layer_in_code: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DomainEntity:
|
||||||
|
entity_id: str
|
||||||
|
entity_name: str
|
||||||
|
type: str
|
||||||
|
description: str
|
||||||
|
key_attributes: str
|
||||||
|
```
|
||||||
|
|
||||||
|
**domain/value_objects.py** — 3 种值对象:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class FileStatus(str, Enum):
|
||||||
|
OK = "ok"
|
||||||
|
SPARSE = "sparse"
|
||||||
|
MISSING = "missing"
|
||||||
|
TEMPLATE_RESIDUE = "template-residue"
|
||||||
|
PLACEHOLDER_HEAVY = "placeholder-heavy"
|
||||||
|
|
||||||
|
class ArchitectureLayer(str, Enum):
|
||||||
|
BUSINESS = "business"
|
||||||
|
APPLICATION = "application"
|
||||||
|
DATA = "data"
|
||||||
|
TECHNOLOGY = "technology"
|
||||||
|
|
||||||
|
class ModuleLayer(str, Enum):
|
||||||
|
DOMAIN = "domain"
|
||||||
|
APPLICATION = "application"
|
||||||
|
INFRASTRUCTURE = "infrastructure"
|
||||||
|
INTERFACES = "interfaces"
|
||||||
|
```
|
||||||
|
|
||||||
|
**domain/services.py** — 约束规则校验 + FileStatus 判定:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class DesignValidationService:
|
||||||
|
def validate_all(entities) -> list[ConstraintViolation]:
|
||||||
|
"""执行所有约束规则,返回违规列表"""
|
||||||
|
def check_capability_module_linkage(capabilities, traceability_links) -> list
|
||||||
|
def check_entity_owner(entities) -> list
|
||||||
|
def check_traceability_references(links, capabilities, modules, entities) -> list
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def determine_file_status(content: str, file_path: str) -> FileStatus:
|
||||||
|
"""根据文件内容特征判定 FileStatus:
|
||||||
|
- missing: 文件不存在或空
|
||||||
|
- sparse: 行数 < 阈值(CSV < 2行含头, MD < 5行)
|
||||||
|
- template-residue: 检测到模板占位文本(TODO、EXAMPLE、<replace>)
|
||||||
|
- placeholder-heavy: 占位符比例 > 30%
|
||||||
|
- ok: 通过所有检查
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 MOD-PROJECT
|
||||||
|
|
||||||
|
**domain/entities.py**:
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class Project:
|
||||||
|
id: str # UUID
|
||||||
|
name: str
|
||||||
|
design_dir: str # 绝对路径
|
||||||
|
code_dir: str | None # Phase 2
|
||||||
|
created_at: datetime
|
||||||
|
```
|
||||||
|
|
||||||
|
**domain/repositories.py**:
|
||||||
|
```python
|
||||||
|
class ProjectRepository(ABC):
|
||||||
|
def list_all() -> list[Project]
|
||||||
|
def get_by_id(id: str) -> Project | None
|
||||||
|
def save(project: Project) -> None
|
||||||
|
def delete(id: str) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
**infrastructure/json_repository.py**:实现 ProjectRepository,读写 JSON 文件。
|
||||||
|
|
||||||
|
**application/services.py**:
|
||||||
|
```python
|
||||||
|
class ProjectService:
|
||||||
|
def list_projects() -> list[Project]
|
||||||
|
def create_project(name, design_dir, code_dir=None) -> Project # 验证 design_dir 存在
|
||||||
|
def get_project(id) -> Project
|
||||||
|
def delete_project(id) -> None
|
||||||
|
```
|
||||||
|
|
||||||
|
**interfaces/http/router.py**:FastAPI router,4 个端点。
|
||||||
|
|
||||||
|
### 3.4 MOD-SCANNER
|
||||||
|
|
||||||
|
**domain/entities.py**:
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class FileStatusEntry:
|
||||||
|
path: str
|
||||||
|
status: FileStatus
|
||||||
|
content_lines: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ScanSummary:
|
||||||
|
total_files: int
|
||||||
|
ok: int
|
||||||
|
sparse: int
|
||||||
|
missing: int
|
||||||
|
placeholder_heavy: int
|
||||||
|
template_residue: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ScanResult:
|
||||||
|
project_id: str
|
||||||
|
scanned_at: datetime
|
||||||
|
file_statuses: list[FileStatusEntry]
|
||||||
|
summary: ScanSummary
|
||||||
|
# 所有解析出的 Design 实体
|
||||||
|
capabilities: list[Capability]
|
||||||
|
modules: list[Module]
|
||||||
|
entities: list[Entity]
|
||||||
|
value_flows: list[ValueFlow]
|
||||||
|
user_journeys: list[UserJourney]
|
||||||
|
integrations: list[Integration]
|
||||||
|
data_flows: list[DataFlow]
|
||||||
|
traceability_links: list[TraceabilityLink]
|
||||||
|
external_systems: list[ExternalSystem]
|
||||||
|
runtime_components: list[RuntimeComponent]
|
||||||
|
tech_selections: list[TechSelection]
|
||||||
|
environments: list[Environment]
|
||||||
|
design_documents: list[DesignDocument]
|
||||||
|
change_log_entries: list[ChangeLogEntry]
|
||||||
|
adrs: list[ADR]
|
||||||
|
shared_terms: list[SharedTerm]
|
||||||
|
domains: list[Domain]
|
||||||
|
ubiquitous_terms: list[UbiquitousTerm]
|
||||||
|
scenarios: list[Scenario]
|
||||||
|
domain_modules: list[DomainModule]
|
||||||
|
domain_entities: list[DomainEntity]
|
||||||
|
data_securities: list[DataSecurity]
|
||||||
|
codebase_alignments: list[CodebaseAlignment]
|
||||||
|
# MD 文件特有
|
||||||
|
scope_and_goals: ScopeAndGoals | None
|
||||||
|
system_context: SystemContext | None
|
||||||
|
solution_layer: SolutionLayer | None
|
||||||
|
module_boundary_rule: ModuleBoundaryRule | None
|
||||||
|
runtime_topology: RuntimeTopology | None
|
||||||
|
operational_baseline: OperationalBaseline | None
|
||||||
|
release_plan: ReleasePlan | None
|
||||||
|
```
|
||||||
|
|
||||||
|
**infrastructure/parsers/**:
|
||||||
|
|
||||||
|
- `csv_parser.py`:解析 CSV 文件,按文件名映射到对应实体类型(capability-map.csv → Capability 列表)
|
||||||
|
- `md_parser.py`:解析 Markdown frontmatter (YAML),提取 doc_id/title/status/upstream/downstream → DesignDocument;特定文件解析为对应实体
|
||||||
|
- `yaml_parser.py`:解析 YAML 配置文件
|
||||||
|
- `openapi_parser.py`:解析 OpenAPI YAML → ApiContract 列表
|
||||||
|
|
||||||
|
**application/services.py**:
|
||||||
|
```python
|
||||||
|
class ScanService:
|
||||||
|
def scan(project: Project) -> ScanResult:
|
||||||
|
"""遍历 design/ → 按类型分派 Parser → 汇总实体 → 调用约束校验 → 计算 FileStatus → 组装 ScanResult"""
|
||||||
|
|
||||||
|
def get_latest_scan(project_id: str) -> ScanResult | None:
|
||||||
|
"""返回内存缓存的最近一次扫描结果"""
|
||||||
|
```
|
||||||
|
|
||||||
|
**interfaces/http/router.py**:POST/GET scan + 11 个实体查询端点(capabilities, modules, entities, integrations, value-flows, user-journeys, data-flows, external-systems, traceability-links, runtime-components + 单个实体详情端点)。
|
||||||
|
|
||||||
|
### 3.5 MOD-GRAPH
|
||||||
|
|
||||||
|
**domain/entities.py**:
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class GraphNode:
|
||||||
|
id: str
|
||||||
|
type: str # capability, module, entity, integration, ...
|
||||||
|
label: str
|
||||||
|
status: str # FileStatus or "unknown"
|
||||||
|
group_id: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GraphEdge:
|
||||||
|
source: str
|
||||||
|
target: str
|
||||||
|
relation: str # traces_to, depends_on, owns, integrates_with, ...
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GraphGroup:
|
||||||
|
id: str
|
||||||
|
label: str
|
||||||
|
layer: str # business, application, data, technology, cross-layer
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GraphView:
|
||||||
|
nodes: list[GraphNode]
|
||||||
|
edges: list[GraphEdge]
|
||||||
|
groups: list[GraphGroup]
|
||||||
|
```
|
||||||
|
|
||||||
|
**application/services.py**:
|
||||||
|
```python
|
||||||
|
class GraphService:
|
||||||
|
def build_panorama(scan_result: ScanResult) -> GraphView:
|
||||||
|
"""从 ScanResult 构建全景图:
|
||||||
|
1. 创建 5 个 group(business, application, data, technology, cross-layer)
|
||||||
|
2. 每个 Capability → node(group=business)
|
||||||
|
3. 每个 Module → node(group=application)
|
||||||
|
4. 每个 Entity → node(group=data)
|
||||||
|
5. 每个 RuntimeComponent → node(group=technology)
|
||||||
|
6. TraceabilityLink → edges(capability→module, module→entity)
|
||||||
|
7. Integration → edges(source→target)
|
||||||
|
8. Module.depends_on → edges
|
||||||
|
9. DesignDocument.upstream/downstream → edges
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_neighbors(graph_view: GraphView, node_id: str) -> GraphView:
|
||||||
|
"""返回指定节点的所有直接邻居组成的子图"""
|
||||||
|
```
|
||||||
|
|
||||||
|
**interfaces/http/router.py**:GET graph, GET neighbors。
|
||||||
|
|
||||||
|
### 3.6 MOD-EDITOR(Phase 2)
|
||||||
|
|
||||||
|
**domain/entities.py**:
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class EditableFile:
|
||||||
|
path: str
|
||||||
|
format: str # csv, md, yaml, openapi
|
||||||
|
content: str
|
||||||
|
last_modified: datetime
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AffectedFile:
|
||||||
|
path: str
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ImpactResult:
|
||||||
|
source_file: str
|
||||||
|
affected_files: list[AffectedFile]
|
||||||
|
```
|
||||||
|
|
||||||
|
**infrastructure/file_io.py**:读写设计文件。
|
||||||
|
|
||||||
|
**application/services.py**:
|
||||||
|
```python
|
||||||
|
class EditorService:
|
||||||
|
def get_file(project: Project, relative_path: str) -> EditableFile
|
||||||
|
def save_file(project: Project, relative_path: str, content: str) -> ScanResult:
|
||||||
|
"""写文件 → 触发重新扫描 → 返回新 ScanResult"""
|
||||||
|
def get_impact(project: Project, relative_path: str, scan_result: ScanResult) -> ImpactResult:
|
||||||
|
"""沿 DesignDocument.downstream + TraceabilityLink 遍历"""
|
||||||
|
```
|
||||||
|
|
||||||
|
**interfaces/http/router.py**:GET/PUT files, GET files/impact。
|
||||||
|
|
||||||
|
### 3.7 MOD-IMPL-TRACKER(Phase 2)
|
||||||
|
|
||||||
|
**domain/entities.py**:
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class ImplProgress:
|
||||||
|
module_id: str
|
||||||
|
percentage: float # 0-100
|
||||||
|
source: str # auto, llm, manual
|
||||||
|
evaluated_at: datetime
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CodeStructure:
|
||||||
|
root_path: str
|
||||||
|
directories: list[str]
|
||||||
|
files: list[str]
|
||||||
|
matched_modules: list[str]
|
||||||
|
```
|
||||||
|
|
||||||
|
**infrastructure/code_scanner.py**:扫描代码目录结构。
|
||||||
|
**infrastructure/llm_client.py**:可选 LLM API 调用。
|
||||||
|
|
||||||
|
**application/services.py**:
|
||||||
|
```python
|
||||||
|
class ImplTrackerService:
|
||||||
|
def evaluate(project: Project, scan_result: ScanResult) -> list[ImplProgress]:
|
||||||
|
"""三级评估:
|
||||||
|
1. auto:扫描 code_dir,对照 CodebaseAlignment 检查目录/文件存在性
|
||||||
|
2. llm(可选):将模块设计+代码发送 LLM 评估覆盖率
|
||||||
|
3. manual:合并用户手动覆盖
|
||||||
|
"""
|
||||||
|
def get_progress(project_id: str) -> list[ImplProgress]
|
||||||
|
def set_manual_progress(project_id: str, module_id: str, percentage: float)
|
||||||
|
```
|
||||||
|
|
||||||
|
**interfaces/http/router.py**:POST/GET impl-progress。
|
||||||
|
|
||||||
|
### 3.8 main.py(应用入口)
|
||||||
|
|
||||||
|
```python
|
||||||
|
app = FastAPI(title="Arch Design Dashboard API")
|
||||||
|
|
||||||
|
# 注册所有 router
|
||||||
|
app.include_router(project_router, prefix="/api")
|
||||||
|
app.include_router(scanner_router, prefix="/api")
|
||||||
|
app.include_router(graph_router, prefix="/api")
|
||||||
|
app.include_router(editor_router, prefix="/api")
|
||||||
|
app.include_router(impl_tracker_router, prefix="/api")
|
||||||
|
|
||||||
|
# 健康检查
|
||||||
|
@app.get("/api/health")
|
||||||
|
def health(): return {"status": "ok"}
|
||||||
|
|
||||||
|
# 全局异常处理
|
||||||
|
@app.exception_handler(NotFoundError) → 404
|
||||||
|
@app.exception_handler(ValidationError) → 400
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 前端详细设计
|
||||||
|
|
||||||
|
### 4.0 基础设施
|
||||||
|
|
||||||
|
**index.html**:SPA 入口页。
|
||||||
|
|
||||||
|
**main.ts**:创建 Vue app,安装 Pinia、Router。
|
||||||
|
|
||||||
|
**App.vue**:
|
||||||
|
```
|
||||||
|
<template>
|
||||||
|
<div class="app-layout">
|
||||||
|
<aside class="sidebar">项目列表(始终可见)</aside>
|
||||||
|
<main class="content"><router-view /></main>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
**router/index.ts**:
|
||||||
|
```typescript
|
||||||
|
routes: [
|
||||||
|
{ path: '/', component: ProjectList },
|
||||||
|
{ path: '/projects/:id', component: GraphPanorama },
|
||||||
|
{ path: '/projects/:id/editor', component: EditorPage }, // Phase 2
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**shared/api.ts**:Axios 实例,baseURL = `/api`。
|
||||||
|
|
||||||
|
**shared/types/api.ts**:TypeScript 类型定义,与 OpenAPI schema 对齐(Project, ScanResult, GraphView, GraphNode, GraphEdge, GraphGroup, Capability, Module, Entity, FileContent, ImpactResult, ImplProgress 等)。
|
||||||
|
|
||||||
|
### 4.1 MOD-FE-PROJECT
|
||||||
|
|
||||||
|
**components/ProjectList.vue**:
|
||||||
|
- 展示已注册项目列表(卡片式)
|
||||||
|
- "添加项目"按钮 → 展开表单(名称 + 设计目录路径 + 可选代码目录)
|
||||||
|
- 点击项目卡片 → router.push(`/projects/${id}`)
|
||||||
|
- 删除按钮(确认后删除)
|
||||||
|
|
||||||
|
**components/ProjectOverview.vue**:项目卡片组件。
|
||||||
|
|
||||||
|
**composables/useProject.ts**:Pinia store — projects[], currentProject, loading, error, CRUD actions。
|
||||||
|
|
||||||
|
**api/index.ts**:listProjects, createProject, getProject, deleteProject。
|
||||||
|
|
||||||
|
### 4.2 MOD-FE-GRAPH
|
||||||
|
|
||||||
|
**components/GraphPanorama.vue**:
|
||||||
|
- 进入时调用 `triggerScan` → `getGraph` 获取数据
|
||||||
|
- D3.js 力导向图,节点按 group 分区布局
|
||||||
|
- 节点颜色映射:ok=`#4CAF50`, sparse=`#FFC107`, missing=`#F44336`, template-residue=`#FF9800`, placeholder-heavy=`#9C27B0`, unknown=`#9E9E9E`
|
||||||
|
- 节点形状:capability=圆, module=方, entity=菱形, 其他=圆
|
||||||
|
- 边线条:traces_to=实线, depends_on=虚线, owns=粗实线
|
||||||
|
- 交互:
|
||||||
|
- hover → tooltip(ID, 类型, 状态, 名称)
|
||||||
|
- 单击 → 侧边 GraphDetail 面板
|
||||||
|
- 双击 → 调用 getNodeNeighbors 展示子图(下钻)
|
||||||
|
- 缩放/平移(D3 zoom behavior)
|
||||||
|
- 扫描摘要面板(total/ok/sparse/missing 统计)
|
||||||
|
|
||||||
|
**components/GraphDetail.vue**:
|
||||||
|
- 侧边滑出面板
|
||||||
|
- 显示节点属性(所有字段)
|
||||||
|
- 关联实体列表(可点击跳转)
|
||||||
|
- Phase 2:编辑按钮 → 跳转编辑器
|
||||||
|
- Phase 2:影响分析按钮 → 高亮下游节点
|
||||||
|
|
||||||
|
**composables/useGraph.ts**:Pinia store — graphView, selectedNode, scanResult, loading。
|
||||||
|
|
||||||
|
**api/index.ts**:triggerScan, getLatestScan, getGraph, getNodeNeighbors, + 实体查询 API。
|
||||||
|
|
||||||
|
### 4.3 MOD-FE-EDITOR(Phase 2)
|
||||||
|
|
||||||
|
**components/CsvEditor.vue**:
|
||||||
|
- 可编辑 HTML 表格
|
||||||
|
- 增删行
|
||||||
|
- 保存按钮 → saveFile → 图自动刷新
|
||||||
|
|
||||||
|
**components/MdEditor.vue**:
|
||||||
|
- textarea 左编辑 + 右侧 Markdown 预览
|
||||||
|
- 支持 frontmatter 高亮
|
||||||
|
- 保存按钮
|
||||||
|
|
||||||
|
**composables/useEditor.ts**:Pinia store — currentFile, impactResult, saving。
|
||||||
|
|
||||||
|
**api/index.ts**:getFile, saveFile, getFileImpact, getImplProgress, triggerImplProgress。
|
||||||
|
|
||||||
|
## 5. 部署配置
|
||||||
|
|
||||||
|
**docker-compose.yml**:
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
build: ./backend
|
||||||
|
ports: ["8900:8900"]
|
||||||
|
volumes:
|
||||||
|
- ${DESIGN_DIR}:/data/design:rw
|
||||||
|
- ${CODE_DIR:-/dev/null}:/data/code:ro
|
||||||
|
- registry-data:/data/registry
|
||||||
|
frontend:
|
||||||
|
build: ./frontend
|
||||||
|
ports: ["80:80"]
|
||||||
|
depends_on: [backend]
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
registry-data:
|
||||||
|
```
|
||||||
|
|
||||||
|
**backend/Dockerfile**:Python 3.12 + uv install + uvicorn 启动。
|
||||||
|
|
||||||
|
**frontend/Dockerfile**:Node 构建 + Nginx 服务静态文件 + 反代 `/api`。
|
||||||
|
|
||||||
|
## 6. 设计约束与边界规则
|
||||||
|
|
||||||
|
- Design 模块是纯 Python,零框架依赖
|
||||||
|
- Scanner 依赖 Design,不依赖 Graph
|
||||||
|
- Graph 依赖 Design,不依赖 Scanner(通过 ScanResult 数据传递)
|
||||||
|
- Editor 依赖 Design + Scanner + Graph
|
||||||
|
- Impl-Tracker 依赖 Design + Scanner
|
||||||
|
- 前端模块只通过 REST API 与后端通信
|
||||||
|
- 设计文件是 single source of truth,不引入额外数据库
|
||||||
|
- 代码仓库只读
|
||||||
Loading…
Reference in New Issue
Block a user