ソースを参照

docs: plan data product navigation naming

马小龙 2 日 前
コミット
fa99dd4148

+ 241 - 0
docs/superpowers/plans/2026-08-19-data-product-navigation-naming.md

@@ -0,0 +1,241 @@
+# Data Product Navigation Naming 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:** Rename the two Data Service product entries to `数据产品目录` and `产品治理与运营` consistently without changing URLs, APIs, permissions, or product-governance behavior.
+
+**Architecture:** This is a frontend terminology-only change. A dedicated contract first locks the visible labels, stable route identity, and page headings; implementation then updates the route metadata and the two Vue page headings while preserving all operational code.
+
+**Tech Stack:** Vue 2, Vuetify, Python 3, pytest, Docker Compose, Playwright CLI.
+
+---
+
+## File Structure
+
+- Create `tests/test_data_product_navigation_naming_contract.py` to protect the exact new labels, stable routes, and page headings.
+- Modify `frontend/src/router/routes.js` to update only the two visible route titles and serialized title metadata.
+- Modify `frontend/src/views/dataService/dataProduct/index.vue` to add the visible `数据产品目录` heading.
+- Modify `frontend/src/views/dataService/productGovernance/index.vue` to rename its visible heading.
+- Modify `tests/test_product_governance_contract.py` so its UI capability assertion follows the new page title without changing domain terminology elsewhere.
+
+### Task 1: Lock the Naming Boundary with a Failing Contract
+
+**Files:**
+- Create: `tests/test_data_product_navigation_naming_contract.py`
+
+- [ ] **Step 1: Write the scoped route and page contract**
+
+Create a helper that extracts a direct Data Service child route by its exact `name` marker, then add:
+
+```python
+from pathlib import Path
+
+ROOT = Path(__file__).resolve().parents[1]
+ROUTES = ROOT / "frontend/src/router/routes.js"
+CATALOG = ROOT / "frontend/src/views/dataService/dataProduct/index.vue"
+GOVERNANCE = ROOT / "frontend/src/views/dataService/productGovernance/index.vue"
+
+
+def child_block(source: str, name: str) -> str:
+    marker = f"          name: '{name}',"
+    name_index = source.index(marker)
+    start = source.rfind("        {", 0, name_index)
+    end = source.index("        },", name_index) + len("        },")
+    return source[start:end]
+
+
+def test_data_service_product_routes_use_clear_names_and_stable_identity():
+    routes = ROUTES.read_text(encoding="utf-8")
+    catalog = child_block(routes, "dataProduct")
+    governance = child_block(routes, "productGovernance")
+
+    for value in ("title", "label"):
+        assert f"{value}: '数据产品目录'" in catalog
+        assert f"{value}: '产品治理与运营'" in governance
+    assert "path: '/dataService/dataProduct'" in catalog
+    assert "component: 'dataService/dataProduct'" in catalog
+    assert "path: '/dataService/productGovernance'" in governance
+    assert "component: 'dataService/productGovernance'" in governance
+    assert "permissions: ['data-products:read']" in governance
+    assert '"title":"数据产品目录"' in catalog
+    assert '"title":"产品治理与运营"' in governance
+
+
+def test_data_service_product_pages_match_navigation_names():
+    catalog = CATALOG.read_text(encoding="utf-8")
+    governance = GOVERNANCE.read_text(encoding="utf-8")
+    assert "<h1" in catalog and ">数据产品目录</h1>" in catalog
+    assert "<h1" in governance and ">产品治理与运营</h1>" in governance
+    assert "查看和使用数据工厂产出的数据产品" in catalog
+    assert "围绕责任人、申请审批、数据合同、产品合格证和用户反馈" in governance
+```
+
+- [ ] **Step 2: Run RED**
+
+```bash
+PYTHONPATH=. .venv/bin/pytest -q tests/test_data_product_navigation_naming_contract.py
+```
+
+Expected: both tests fail because the old menu titles remain and the data-product page has no visible heading.
+
+- [ ] **Step 3: Commit the RED contract**
+
+```bash
+git add tests/test_data_product_navigation_naming_contract.py
+git commit -m "test: define data product navigation names"
+```
+
+### Task 2: Apply the Consistent Visible Names
+
+**Files:**
+- Modify: `frontend/src/router/routes.js`
+- Modify: `frontend/src/views/dataService/dataProduct/index.vue`
+- Modify: `frontend/src/views/dataService/productGovernance/index.vue`
+- Modify: `tests/test_product_governance_contract.py`
+
+- [ ] **Step 1: Rename the two route presentation blocks**
+
+In the `dataProduct` route object, replace only the presentation values:
+
+```javascript
+title: '数据产品目录'
+label: '数据产品目录'
+meta: {
+  title: '数据产品目录'
+}
+metastr: '{"keepAlive":false,"allowClick":false,"enName":"data Product","editModules":false,"title":"数据产品目录","fullScreen":false,"target":false}'
+```
+
+In the `productGovernance` object, replace only the presentation values:
+
+```javascript
+title: '产品治理与运营'
+label: '产品治理与运营'
+meta: {
+  title: '产品治理与运营'
+}
+metastr: '{"keepAlive":false,"allowClick":false,"permissions":["data-products:read"],"enName":"data product governance","editModules":false,"title":"产品治理与运营","fullScreen":false,"target":false}'
+```
+
+Do not change either route's `path`, `name`, `component`, permission array, ID, parent, or sort value.
+
+- [ ] **Step 2: Add the catalog heading**
+
+Immediately inside the data-product page's root container, before `<m-filter>`, add:
+
+```vue
+<div class="mb-4">
+  <h1 class="text-h4 font-weight-bold mb-2">数据产品目录</h1>
+  <p class="mb-0 grey--text text--darken-1">查看和使用数据工厂产出的数据产品。</p>
+</div>
+```
+
+Leave all filters, table actions, preview, download, refresh, registration, and deletion logic unchanged.
+
+- [ ] **Step 3: Rename the governance heading**
+
+Change only the existing hero heading:
+
+```vue
+<h1 class="text-h4 font-weight-bold mb-2">产品治理与运营</h1>
+```
+
+Leave the lifecycle description and all governance tabs/actions unchanged.
+
+- [ ] **Step 4: Align the existing frontend contract**
+
+In `test_api_and_frontend_cover_the_complete_product_governance_surface`, replace the first visible capability string only:
+
+```python
+for capability in (
+    "产品治理与运营",
+    "通用申请",
+    "数据合同",
+    "产品合格证",
+    "用户反馈",
+    "不会自动下发数据权限",
+):
+    assert capability in view
+```
+
+Do not replace domain-language references in migrations, architecture documents, WP14 backlog, work-center object labels, or audit categories.
+
+- [ ] **Step 5: Run GREEN and affected contracts**
+
+```bash
+PYTHONPATH=. .venv/bin/pytest -q \
+  tests/test_data_product_navigation_naming_contract.py \
+  tests/test_product_governance_contract.py \
+  tests/test_work_center_contract.py \
+  tests/test_frontend_rbac_contract.py \
+  tests/test_architecture_artifacts.py
+```
+
+Expected: all collected tests pass without new skips.
+
+- [ ] **Step 6: Build and inspect the diff**
+
+```bash
+npm --prefix frontend run build
+git diff --check
+git diff -- frontend/src/router/routes.js \
+  frontend/src/views/dataService/dataProduct/index.vue \
+  frontend/src/views/dataService/productGovernance/index.vue \
+  tests/test_product_governance_contract.py \
+  tests/test_data_product_navigation_naming_contract.py
+```
+
+Expected: build exits 0; the diff contains only the intended terminology and catalog heading changes.
+
+- [ ] **Step 7: Commit**
+
+```bash
+git add frontend/src/router/routes.js \
+  frontend/src/views/dataService/dataProduct/index.vue \
+  frontend/src/views/dataService/productGovernance/index.vue \
+  tests/test_product_governance_contract.py
+git commit -m "feat: clarify data product navigation names"
+```
+
+### Task 3: Deploy and Verify Local UAT
+
+**Files:** Verification only.
+
+- [ ] **Step 1: Rebuild the frontend**
+
+```bash
+docker compose -f deploy/docker/docker-compose.yml up -d --build frontend
+```
+
+Expected: the frontend container becomes healthy and the backend remains healthy.
+
+- [ ] **Step 2: Verify health and stable deep links**
+
+```bash
+docker compose -f deploy/docker/docker-compose.yml ps
+curl -fsS http://localhost:15500/api/system/health
+curl -fsS http://localhost:18183/dataService/dataProduct >/dev/null
+curl -fsS http://localhost:18183/dataService/productGovernance >/dev/null
+```
+
+Expected: backend status is healthy and both original URLs return HTTP 200.
+
+- [ ] **Step 3: Perform authenticated browser UAT**
+
+Using the local approved test account, verify:
+
+1. Data Service menu displays `数据产品目录` and `产品治理与运营` in the original order.
+2. `/dataService/dataProduct` displays `数据产品目录` and the existing list/actions.
+3. `/dataService/productGovernance` displays `产品治理与运营` and the existing governance tabs.
+4. Both pages survive refresh, with no new console errors.
+5. No API, database, permission, route path, or external service operation is changed or invoked.
+
+- [ ] **Step 4: Record final state**
+
+```bash
+git log --oneline -5
+git status --short
+git diff --check
+```
+
+Expected: naming commits are present, staged/tracked diff is empty, and unrelated untracked user assets remain untouched.