9.3 KiB
Architecture Diagram DSL Editor Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Replace the current generic architecture graph in the EasyCode diagram center with a DSL-driven layered architecture diagram editor.
Architecture: Add a pure frontend utility module that generates default DSL, parses DSL, computes layered SVG layout, and builds export SVG. Update DiagramCenterView.vue to show a dedicated architecture editor for activeDiagram === 'architecture', reusing the existing project/database load flow and front_project_diagram save endpoint.
Tech Stack: Vue 3 Composition API, Vite, Element Plus, browser SVG/Canvas export, Node-based frontend utility tests.
File Structure
- Create
easycode-web/src/utils/architectureDiagram.js: pure functions for default DSL generation, DSL parsing, layout, and SVG export. - Create
easycode-web/src/utils/architectureDiagram.test.mjs: Node tests for generation, parsing, layout stats, and SVG export. - Modify
easycode-web/src/views/DiagramCenterView.vue: render the architecture editor, bind DSL state, save/restorearchitecturediagrams, and export SVG/PNG.
Task 1: Architecture Diagram Utility
Files:
-
Create:
easycode-web/src/utils/architectureDiagram.js -
Create:
easycode-web/src/utils/architectureDiagram.test.mjs -
Step 1: Write tests for default DSL and parsing
Create easycode-web/src/utils/architectureDiagram.test.mjs with tests that import:
import assert from 'node:assert/strict'
import {
buildArchitectureDiagram,
buildArchitectureExportSvg,
buildDefaultArchitectureDsl,
parseArchitectureDsl
} from './architectureDiagram.js'
Include a sample project:
const project = {
projectName: '选课系统',
frontFramework: 'Vue 3',
backFramework: 'Spring Boot',
appBlueprint: JSON.stringify({
roles: [
{ name: '学生', permissions: ['选课', '查成绩'] },
{ name: '教师', permissions: ['课程管理', '成绩录入'] }
],
frontendMenus: [{ name: '选课大厅' }],
adminMenus: [{ name: '课程管理' }, { name: '数据统计' }]
})
}
const database = {
tables: [
{ tableName: 'course', tableComment: '课程表' },
{ tableName: 'student_course', tableComment: '选课记录' }
]
}
Assert that:
const dsl = buildDefaultArchitectureDsl(project, database)
assert.match(dsl, /用户层/)
assert.match(dsl, /表现层 - Vue 3/)
assert.match(dsl, /数据层/)
assert.match(dsl, /2 张业务表/)
const parsed = parseArchitectureDsl(dsl)
assert.equal(parsed.layers[0].title, '用户层')
assert.ok(parsed.layers.length >= 6)
assert.ok(parsed.concerns.length >= 3)
assert.ok(parsed.stats.componentCount >= 12)
- Step 2: Write tests for DSL structure, layout, and SVG export
Use this DSL:
const customDsl = `用户层
学生
选课 / 查成绩
表现层 - Vue 3 前端
Vue 3
Composition API
Vue Router 路由
接口层 - Spring MVC Controller
统一接口规范
控制器分层
横切关注点
JWT 认证
登录签发 Token
全局异常处理
统一异常响应`
Assert:
const parsed = parseArchitectureDsl(customDsl)
assert.equal(parsed.layers.length, 3)
assert.equal(parsed.layers[1].subtitle, 'Vue 3 前端')
assert.equal(parsed.layers[1].components[0].details.length, 2)
assert.equal(parsed.concerns.length, 2)
const diagram = buildArchitectureDiagram(parsed)
assert.equal(diagram.stats.layerCount, 3)
assert.equal(diagram.stats.concernCount, 2)
assert.ok(diagram.canvas.width >= 900)
assert.ok(diagram.canvas.height >= 420)
assert.equal(diagram.layers[0].components[0].title, '学生')
const svg = buildArchitectureExportSvg(diagram)
assert.match(svg, /系统架构图/)
assert.match(svg, /JWT 认证/)
assert.match(svg, /Vue 3/)
- Step 3: Run tests and confirm they fail
Run:
cd easycode-web
node src/utils/architectureDiagram.test.mjs
Expected: module not found or missing exported functions.
- Step 4: Implement
architectureDiagram.js
Implement exports:
export function buildDefaultArchitectureDsl(project = {}, database = {}) {}
export function parseArchitectureDsl(dsl = '') {}
export function buildArchitectureDiagram(parsed = {}, options = {}) {}
export function buildArchitectureExportSvg(diagram = {}, options = {}) {}
The implementation must:
-
Parse
project.appBlueprintsafely when it is JSON text. -
Produce fallback roles, services, tables, and runtime items when project data is sparse.
-
Split layer title/subtitle on
-or—. -
Treat
横切关注点asconcerns. -
Return stable
statswithlayerCount,componentCount, andconcernCount. -
Escape XML text in export SVG.
-
Step 5: Run utility tests and fix failures
Run:
cd easycode-web
node src/utils/architectureDiagram.test.mjs
Expected: all assertions pass with no output beyond the test runner's normal completion.
Task 2: Diagram Center Architecture Editor
Files:
-
Modify:
easycode-web/src/views/DiagramCenterView.vue -
Step 1: Add architecture state and imports
Import these functions:
import {
buildArchitectureDiagram,
buildArchitectureExportSvg,
buildDefaultArchitectureDsl,
parseArchitectureDsl
} from '@/utils/architectureDiagram'
Add refs:
const architectureDsl = ref('')
const architectureBlackWhite = ref(false)
const architectureSvgRef = ref(null)
Add computed values:
const parsedArchitecture = computed(() => parseArchitectureDsl(architectureDsl.value))
const architectureDiagram = computed(() => buildArchitectureDiagram(parsedArchitecture.value, {
blackWhite: architectureBlackWhite.value,
title: `${project.projectName || '项目'}系统架构图`
}))
- Step 2: Replace architecture branch with dedicated editor
In the template, add a branch before the existing custom graph branch:
<section v-else-if="activeDiagram === 'architecture'" class="architecture-editor">
<!-- editor toolbar, DSL textarea, SVG preview, export buttons -->
</section>
The editor must include:
-
left DSL panel with
el-input type="textarea"bound toarchitectureDsl; -
buttons for clear, load example, refresh preview, save;
-
right SVG preview bound to
architectureDiagram; -
top stats for
layerCountandcomponentCount; -
checkbox bound to
architectureBlackWhite; -
export buttons using SVG and PNG handlers.
-
Step 3: Add save/restore behavior
In applySavedDrafts():
- Find saved
diagramType === 'architecture'. - Parse
diagramJson. - If it contains
dsl, setarchitectureDsl. - If no saved DSL exists, set
architectureDsl = buildDefaultArchitectureDsl(project, database.value). - Restore
blackWhitefrom saved payload when present.
In loadSavedDiagram(diagram):
- When
diagram.diagramType === 'architecture', setactiveDiagram = 'architecture', apply saved DSL and display mode.
In currentDiagramPayload():
- For architecture, save:
{
diagramType: 'architecture',
title: '系统架构图',
description: 'DSL 驱动的分层系统架构图',
diagramJson: JSON.stringify({
dsl: architectureDsl.value,
graph: architectureDiagram.value,
blackWhite: architectureBlackWhite.value
})
}
- Step 4: Add architecture export handlers
Add:
function architectureSvgText() {
return buildArchitectureExportSvg(architectureDiagram.value, {
blackWhite: architectureBlackWhite.value
})
}
function downloadArchitectureSvg() {}
async function downloadArchitecturePng() {}
PNG export should follow existing downloadCurrentPng() logic: create a Blob URL, load it into Image, draw on Canvas, save with saveBlob.
- Step 5: Style the editor
Add scoped SCSS for:
.architecture-editor.architecture-workbench.architecture-dsl-panel.architecture-preview-panel.architecture-toolbar.architecture-preview-scroll.architecture-svg
The layout should be split-panel on desktop and single-column below 980px. Keep card radius at 8px or less and use restrained, workbench-style colors.
- Step 6: Run frontend build
Run:
cd easycode-web
npm run build
Expected: Vite production build completes successfully.
Task 3: Manual UI Verification
Files:
-
Existing frontend files only.
-
Step 1: Start local dev server
Run:
cd easycode-web
npm run dev -- --host 0.0.0.0
Expected: Vite serves the app and prints a local URL.
- Step 2: Open diagram center
Use an authenticated project URL:
http://localhost:<port>/project/<projectId>/diagrams
Expected:
-
system architecture tab shows DSL editor and layered preview;
-
default DSL appears when no saved architecture diagram exists;
-
editing DSL and clicking generate/refresh updates the preview;
-
saving persists and reload restores DSL;
-
SVG and PNG downloads start.
-
Step 3: Stop dev server
Stop the Vite session after verification so no long-running command remains.
Self-Review
- Spec coverage: default DSL, parsing, layered SVG, concerns sidebar, save/restore, export, and tests are covered.
- Placeholder scan: no
TBD,TODO, or vague implementation-only steps remain. - Type consistency: utility names and Vue computed/state names match across tasks.