Files
yidaima/RuoYi-Vue/docs/superpowers/plans/2026-07-07-architecture-diagram-dsl-editor.md

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/restore architecture diagrams, 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.appBlueprint safely 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 横切关注点 as concerns.

  • Return stable stats with layerCount, componentCount, and concernCount.

  • 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 to architectureDsl;

  • buttons for clear, load example, refresh preview, save;

  • right SVG preview bound to architectureDiagram;

  • top stats for layerCount and componentCount;

  • 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, set architectureDsl.
  • If no saved DSL exists, set architectureDsl = buildDefaultArchitectureDsl(project, database.value).
  • Restore blackWhite from saved payload when present.

In loadSavedDiagram(diagram):

  • When diagram.diagramType === 'architecture', set activeDiagram = '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.