2026-08-19-data-product-navigation-naming.md 8.9 KB

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:

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
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
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:

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.

  • Step 2: Add the catalog heading

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.

  • Step 3: Rename the governance heading

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.

  • 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:

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
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
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
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
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
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
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.