Quellcode durchsuchen

docs: plan Kestra and n8n navigation separation

马小龙 vor 3 Tagen
Ursprung
Commit
f9f22181ff

+ 266 - 0
docs/superpowers/plans/2026-08-18-data-factory-kestra-n8n-navigation-separation.md

@@ -0,0 +1,266 @@
+# Data Factory Kestra / n8n Navigation Separation 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:** Give governed Kestra production deployment and legacy n8n management independent Data Factory navigation and page lifecycles.
+
+**Architecture:** Move the Kestra deployment component out of the n8n workflow directory and expose it through a dedicated internal route. Keep the two n8n surfaces explicitly marked as legacy, preserve their current adapters, and protect the separation with source-level navigation contracts plus a production frontend build and Docker smoke test.
+
+**Tech Stack:** Vue 2, Vue Router, Vuetify, Python pytest contract tests, Docker Compose.
+
+---
+
+## File Structure
+
+- Create `tests/test_data_factory_orchestration_navigation_contract.py`: owns the engine-separation navigation contract.
+- Modify `tests/test_data_rule_frontend_contract.py`: points the existing governed deployment assertions at the new Kestra page.
+- Modify `frontend/src/router/routes.js`: defines independent Kestra and legacy n8n menu entries.
+- Create `frontend/src/views/dataFactory/productionLineDeployment/index.vue`: dedicated Kestra production deployment page, moved from the n8n directory.
+- Modify `frontend/src/views/dataFactory/workflow/index.vue`: retains only n8n workflow list, executions, and health.
+- Remove `frontend/src/views/dataFactory/workflow/ProductionLineDeployment.vue`: eliminates the physical page coupling.
+
+### Task 1: Add the failing navigation-separation contract
+
+**Files:**
+- Create: `tests/test_data_factory_orchestration_navigation_contract.py`
+- Test: `tests/test_data_factory_orchestration_navigation_contract.py`
+
+- [ ] **Step 1: Write the failing contract**
+
+```python
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+ROUTES = ROOT / "frontend/src/router/routes.js"
+N8N_PAGE = ROOT / "frontend/src/views/dataFactory/workflow/index.vue"
+KESTRA_PAGE = ROOT / "frontend/src/views/dataFactory/productionLineDeployment/index.vue"
+
+
+def test_data_factory_exposes_independent_kestra_and_legacy_n8n_navigation():
+    routes = ROUTES.read_text(encoding="utf-8")
+    assert "数据生产线投产" in routes
+    assert "'/dataFactory/production-line-deployment'" in routes
+    assert "dataFactory/productionLineDeployment" in routes
+    assert "n8n 生产线管理(待下线)" in routes
+    assert "n8n 工作流管理(待下线)" in routes
+    assert routes.index("数据生产线投产") < routes.index("n8n 生产线管理(待下线)")
+
+
+def test_kestra_page_is_not_owned_by_the_n8n_workflow_page():
+    legacy = N8N_PAGE.read_text(encoding="utf-8")
+    kestra = KESTRA_PAGE.read_text(encoding="utf-8")
+    assert "ProductionLineDeployment" not in legacy
+    assert "数据生产线投产" not in legacy
+    assert "工作流列表" in legacy
+    assert "执行记录" in legacy
+    assert "健康检查" in legacy
+    assert "DATA FACTORY · GOVERNED RELEASE" in kestra
+    assert "Kestra revision" in kestra
+```
+
+- [ ] **Step 2: Run the contract and verify RED**
+
+Run: `PYTHONPATH=. .venv/bin/pytest -q tests/test_data_factory_orchestration_navigation_contract.py`
+
+Expected: FAIL because the dedicated Kestra route/page does not exist and the n8n page still imports `ProductionLineDeployment`.
+
+- [ ] **Step 3: Commit the RED contract**
+
+```bash
+git add tests/test_data_factory_orchestration_navigation_contract.py
+git commit -m "test: define Kestra and n8n navigation boundary"
+```
+
+### Task 2: Create the dedicated Kestra page and remove the n8n tab coupling
+
+**Files:**
+- Create: `frontend/src/views/dataFactory/productionLineDeployment/index.vue`
+- Remove: `frontend/src/views/dataFactory/workflow/ProductionLineDeployment.vue`
+- Modify: `frontend/src/views/dataFactory/workflow/index.vue`
+- Modify: `tests/test_data_rule_frontend_contract.py`
+
+- [ ] **Step 1: Move the governed deployment component**
+
+Move `frontend/src/views/dataFactory/workflow/ProductionLineDeployment.vue` byte-for-byte to `frontend/src/views/dataFactory/productionLineDeployment/index.vue`. Its imports use the `@/api/dataRules` alias, so the move does not change runtime dependencies.
+
+- [ ] **Step 2: Remove the Kestra tab from the legacy n8n page**
+
+Make `frontend/src/views/dataFactory/workflow/index.vue` contain only:
+
+```vue
+<v-tabs v-model="tab" @change="handleTabChange">
+  <v-tab>工作流列表</v-tab>
+  <v-tab>执行记录</v-tab>
+  <v-tab>健康检查</v-tab>
+</v-tabs>
+```
+
+Remove the `ProductionLineDeployment` import, component registration, and tab item. Keep `ExecutionRecord :tab="tab"` aligned with the new three-tab index.
+
+- [ ] **Step 3: Point the existing governed frontend contract at the new page**
+
+Change the constants in `tests/test_data_rule_frontend_contract.py` to:
+
+```python
+FACTORY = Path(
+    "frontend/src/views/dataFactory/productionLineDeployment/index.vue"
+)
+FACTORY_INDEX = FACTORY
+```
+
+The existing assertions continue to prove deployment, canary, activation, rollback, evidence, and readiness behavior.
+
+- [ ] **Step 4: Run focused tests**
+
+Run:
+
+```bash
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_data_factory_orchestration_navigation_contract.py \
+  tests/test_data_rule_frontend_contract.py
+```
+
+Expected: navigation test still fails only because the new router entry is absent; existing governed deployment assertions pass at the new location.
+
+### Task 3: Add independent router entries and legacy labels
+
+**Files:**
+- Modify: `frontend/src/router/routes.js`
+- Test: `tests/test_data_factory_orchestration_navigation_contract.py`
+
+- [ ] **Step 1: Insert the Kestra entry before the legacy entries**
+
+Add a Data Factory child with this contract:
+
+```javascript
+{
+  meun: '',
+  code: '',
+  hidden: 0,
+  rootId: 972,
+  icon: '',
+  remark: '',
+  type: 1,
+  title: '数据生产线投产',
+  local: '',
+  path: '/dataFactory/production-line-deployment',
+  urls: '',
+  children: [],
+  enName: 'Kestra Production Deployment',
+  id: 979,
+  redirect: '',
+  level: 2,
+  openPath: '',
+  active: '',
+  label: '数据生产线投产',
+  sort: 5,
+  parentId: 972,
+  effectiveStatus: true,
+  parentName: 'dataFactory',
+  component: 'dataFactory/productionLineDeployment',
+  meta: {
+    keepAlive: false,
+    allowClick: false,
+    roles: [],
+    enName: 'Kestra Production Deployment',
+    icon: '',
+    editModules: false,
+    title: '数据生产线投产',
+    fullScreen: false,
+    target: false,
+    effectiveStatus: true
+  },
+  name: 'productionLineDeployment',
+  style: '',
+  alwaysShow: 0,
+  metastr: '{"keepAlive":false,"allowClick":false,"enName":"Kestra Production Deployment","editModules":false,"title":"数据生产线投产","fullScreen":false,"target":false}',
+  open: null
+}
+```
+
+- [ ] **Step 2: Rename the two n8n entries without changing behavior**
+
+Update the current external entry label/title to `n8n 生产线管理(待下线)` while retaining `process.env.VUE_APP_N8N_URL` and `target: true`.
+
+Update the current internal workflow entry label/title to `n8n 工作流管理(待下线)` while retaining `/dataFactory/workflow`, component `dataFactory/workflow`, and `target: false`.
+
+- [ ] **Step 3: Run RED-to-GREEN contract tests**
+
+Run:
+
+```bash
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_data_factory_orchestration_navigation_contract.py \
+  tests/test_data_rule_frontend_contract.py \
+  tests/test_cleanup_contract.py \
+  tests/test_architecture_artifacts.py
+```
+
+Expected: PASS.
+
+- [ ] **Step 4: Commit the implementation**
+
+```bash
+git add \
+  frontend/src/router/routes.js \
+  frontend/src/views/dataFactory/workflow/index.vue \
+  frontend/src/views/dataFactory/productionLineDeployment/index.vue \
+  frontend/src/views/dataFactory/workflow/ProductionLineDeployment.vue \
+  tests/test_data_rule_frontend_contract.py
+git commit -m "feat: separate Kestra and legacy n8n navigation"
+```
+
+### Task 4: Build, deploy, and verify the local UAT frontend
+
+**Files:**
+- Verify: `frontend/`
+- Verify: `deploy/docker/docker-compose.yml`
+
+- [ ] **Step 1: Build the production frontend**
+
+Run: `npm --prefix frontend run build`
+
+Expected: exit 0 with a generated production bundle and no route-resolution error.
+
+- [ ] **Step 2: Rebuild and restart only the frontend service**
+
+Run: `docker compose -f deploy/docker/docker-compose.yml up -d --build frontend`
+
+Expected: frontend and its dependencies remain healthy; backend, Kestra, and n8n state are preserved.
+
+- [ ] **Step 3: Verify service health and deep links**
+
+Run:
+
+```bash
+docker compose -f deploy/docker/docker-compose.yml ps
+curl -fsS http://localhost:18183/dataFactory/production-line-deployment >/dev/null
+curl -fsS http://localhost:18183/dataFactory/workflow >/dev/null
+```
+
+Expected: frontend is healthy and both internal routes return the SPA document.
+
+- [ ] **Step 4: Browser acceptance**
+
+Verify in the local UAT UI:
+
+1. `数据工厂 > 数据生产线投产` opens the governed Kestra page.
+2. `数据工厂 > n8n 生产线管理(待下线)` opens the current n8n URL.
+3. `数据工厂 > n8n 工作流管理(待下线)` shows only three n8n tabs.
+4. Refreshing either internal deep link does not produce a 404.
+
+- [ ] **Step 5: Run final source checks and commit any generated contract update**
+
+Run:
+
+```bash
+git diff --check
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_data_factory_orchestration_navigation_contract.py \
+  tests/test_data_rule_frontend_contract.py \
+  tests/test_cleanup_contract.py \
+  tests/test_architecture_artifacts.py
+```
+
+Expected: all tests pass and `git diff --check` emits no output.