Quellcode durchsuchen

docs: plan enterprise identity navigation move

马小龙 vor 2 Tagen
Ursprung
Commit
a5c2831975

+ 205 - 0
docs/superpowers/plans/2026-08-19-enterprise-identity-navigation-move.md

@@ -0,0 +1,205 @@
+# Enterprise Identity Navigation Move 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:** Move the enterprise identity management entry from Data Research to System Management without changing its URL, component, permission, or runtime behavior.
+
+**Architecture:** This is a router-data-only migration. A structural source contract will identify top-level and child route objects by their route names, prove the old parent no longer owns the entry, and prove the System Management parent owns exactly one compatible `企业身份与 SSO` entry.
+
+**Tech Stack:** Vue 2 router metadata, Python pytest source contracts, Vue CLI production build, Docker Compose local UAT.
+
+---
+
+## File Structure
+
+- Create `tests/test_enterprise_identity_navigation_contract.py`: structural parent, compatibility, order, and uniqueness contract.
+- Modify `frontend/src/router/routes.js`: move and rename the existing navigation object; no page or API changes.
+
+### Task 1: Define the failing navigation ownership contract
+
+**Files:**
+- Create: `tests/test_enterprise_identity_navigation_contract.py`
+- Test: `tests/test_enterprise_identity_navigation_contract.py`
+
+- [ ] **Step 1: Write the structural test**
+
+```python
+from pathlib import Path
+
+
+ROOT = Path(__file__).resolve().parents[1]
+ROUTES = ROOT / "frontend/src/router/routes.js"
+
+
+def _route_block(source: str, *, indent: int, name: str) -> str:
+    start_token = " " * indent + "{\n"
+    end_token = "\n" + " " * indent + "},"
+    name_token = " " * (indent + 2) + f"name: '{name}'"
+    name_at = source.index(name_token)
+    start = source.rfind(start_token, 0, name_at)
+    end = source.find(end_token, name_at)
+    assert start >= 0 and end >= 0
+    return source[start : end + len(end_token)]
+
+
+def test_enterprise_identity_is_owned_only_by_system_management():
+    routes = ROUTES.read_text(encoding="utf-8")
+    data_research = _route_block(routes, indent=4, name="data-governance")
+    system = _route_block(routes, indent=4, name="systemManage")
+
+    assert "systemEnterpriseIdentity" not in data_research
+    assert routes.count("name: 'systemEnterpriseIdentity'") == 1
+
+    identity = _route_block(system, indent=8, name="systemEnterpriseIdentity")
+    assert "title: '企业身份与 SSO'" in identity
+    assert "label: '企业身份与 SSO'" in identity
+    assert "path: '/systemManage/enterprise-identity'" in identity
+    assert "component: 'systemManage/enterpriseIdentity'" in identity
+    assert "permissions: ['identity:manage']" in identity
+    assert "icon: 'mdi-account-key-outline'" in identity
+    assert "sort: 2" in identity
+
+
+def test_system_management_navigation_order_is_stable():
+    routes = ROUTES.read_text(encoding="utf-8")
+    system = _route_block(routes, indent=4, name="systemManage")
+    names = [
+        "systemUserManage",
+        "systemEnterpriseIdentity",
+        "systemResponsibilityManage",
+        "systemGovernanceAudit",
+        "systemAgentGovernance",
+    ]
+    positions = [system.index(f"name: '{name}'") for name in names]
+    assert positions == sorted(positions)
+    for sort, name in enumerate(names, start=1):
+        block = _route_block(system, indent=8, name=name)
+        assert f"sort: {sort}" in block
+```
+
+- [ ] **Step 2: Verify RED**
+
+Run: `PYTHONPATH=. .venv/bin/pytest -q tests/test_enterprise_identity_navigation_contract.py`
+
+Expected: FAIL because `systemEnterpriseIdentity` still belongs to the Data Research route and is absent from System Management.
+
+- [ ] **Step 3: Commit the RED contract**
+
+```bash
+git add tests/test_enterprise_identity_navigation_contract.py
+git commit -m "test: define enterprise identity menu ownership"
+```
+
+### Task 2: Move the compatible route record
+
+**Files:**
+- Modify: `frontend/src/router/routes.js`
+- Test: `tests/test_enterprise_identity_navigation_contract.py`
+
+- [ ] **Step 1: Remove the existing child from Data Research**
+
+Delete only the child object whose route name is `systemEnterpriseIdentity` from the `data-governance` children array. Do not modify the surrounding Data Research routes.
+
+- [ ] **Step 2: Insert the compatible child under System Management**
+
+Insert this object immediately after `systemUserManage`:
+
+```javascript
+{
+  hidden: 0,
+  type: 1,
+  title: '企业身份与 SSO',
+  path: '/systemManage/enterprise-identity',
+  children: [],
+  label: '企业身份与 SSO',
+  sort: 2,
+  component: 'systemManage/enterpriseIdentity',
+  meta: {
+    title: '企业身份与 SSO',
+    icon: 'mdi-account-key-outline',
+    permissions: ['identity:manage']
+  },
+  name: 'systemEnterpriseIdentity',
+  alwaysShow: 0
+}
+```
+
+Change the following System Management sort values:
+
+- `systemResponsibilityManage`: `2` to `3`
+- `systemGovernanceAudit`: `3` to `4`
+- `systemAgentGovernance`: `4` to `5`
+
+- [ ] **Step 3: Verify GREEN and regression scope**
+
+Run:
+
+```bash
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_enterprise_identity_navigation_contract.py \
+  tests/test_phase3_wp02_enterprise_identity_contract.py \
+  tests/test_frontend_rbac_contract.py \
+  tests/test_architecture_artifacts.py
+```
+
+Expected: all tests pass; existing path and `identity:manage` assertions remain green.
+
+- [ ] **Step 4: Build the frontend**
+
+Run: `npm --prefix frontend run build`
+
+Expected: exit 0 with no route resolution error.
+
+- [ ] **Step 5: Commit the router migration**
+
+```bash
+git add frontend/src/router/routes.js
+git commit -m "feat: move enterprise identity to system management"
+```
+
+### Task 3: Deploy and verify the local UAT frontend
+
+**Files:**
+- Verify: `deploy/docker/docker-compose.yml`
+- Verify: `frontend/src/router/routes.js`
+
+- [ ] **Step 1: Rebuild only the frontend**
+
+Run: `docker compose -f deploy/docker/docker-compose.yml up -d --build frontend`
+
+Expected: the frontend container is recreated and becomes healthy; persisted identity and application data remain unchanged.
+
+- [ ] **Step 2: Verify health and compatible deep link**
+
+Run:
+
+```bash
+docker compose -f deploy/docker/docker-compose.yml ps
+curl -fsS http://localhost:18183/systemManage/enterprise-identity >/dev/null
+curl -fsS http://localhost:15500/api/system/health >/dev/null
+```
+
+Expected: frontend, backend, Kestra, n8n, runner, and storage services remain healthy; both HTTP checks succeed.
+
+- [ ] **Step 3: Verify the visible menu after authentication**
+
+Confirm that:
+
+1. `数据研发` no longer displays `企业身份`.
+2. `系统管理` displays `企业身份与 SSO` after `用户管理`.
+3. Opening it preserves `/systemManage/enterprise-identity` and shows the existing `企业身份与 SSO` page with `待企业 IdP UAT`.
+
+- [ ] **Step 4: Final checks**
+
+Run:
+
+```bash
+git diff --check
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_enterprise_identity_navigation_contract.py \
+  tests/test_phase3_wp02_enterprise_identity_contract.py \
+  tests/test_frontend_rbac_contract.py \
+  tests/test_architecture_artifacts.py
+```
+
+Expected: all focused tests pass and `git diff --check` emits no output.