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.
tests/test_data_product_navigation_naming_contract.py to protect the exact new labels, stable routes, and page headings.frontend/src/router/routes.js to update only the two visible route titles and serialized title metadata.frontend/src/views/dataService/dataProduct/index.vue to add the visible 数据产品目录 heading.frontend/src/views/dataService/productGovernance/index.vue to rename its visible heading.tests/test_product_governance_contract.py so its UI capability assertion follows the new page title without changing domain terminology elsewhere.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:
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
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.
git add tests/test_data_product_navigation_naming_contract.py
git commit -m "test: define data product navigation names"
Files:
frontend/src/router/routes.jsfrontend/src/views/dataService/dataProduct/index.vuefrontend/src/views/dataService/productGovernance/index.vueModify: tests/test_product_governance_contract.py
[ ] Step 1: Rename the two route presentation blocks
In the dataProduct route object, replace only the presentation values:
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:
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.
Immediately inside the data-product page's root container, before <m-filter>, add:
<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.
Change only the existing hero heading:
<h1 class="text-h4 font-weight-bold mb-2">产品治理与运营</h1>
Leave the lifecycle description and all governance tabs/actions unchanged.
In test_api_and_frontend_cover_the_complete_product_governance_surface, replace the first visible capability string only:
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.
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.
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.
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"
Files: Verification only.
docker compose -f deploy/docker/docker-compose.yml up -d --build frontend
Expected: the frontend container becomes healthy and the backend remains healthy.
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.
Using the local approved test account, verify:
数据产品目录 and 产品治理与运营 in the original order./dataService/dataProduct displays 数据产品目录 and the existing list/actions./dataService/productGovernance displays 产品治理与运营 and the existing governance tabs.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.