# 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 "
数据产品目录
" in catalog
assert "产品治理与运营
" 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 ``, add:
```vue
```
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
产品治理与运营
```
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.