# /map-testids — Định nghĩa/backfill test-id ổn định lên component FE tái dùng & có sẵn

> Đồng hành với contract *Test Selectors* §4.5.6 của tech-doc gộp. `/generate-tech-docs` và
> `/generate-code` gán test-id cho code **mới**; lệnh này lo phần còn lại: component catalog
> **tái dùng** (id sống ở usage site; component phải *forward* được test-id) và màn
> **đã có / brownfield** đã code mà chưa có test-id. Nó reverse-document những gì đang có,
> gán id ổn định ở chỗ còn thiếu, đảm bảo component tái dùng forward được id, ghi việc
> forwarding vào figma-components catalog, patch các usage site, và ghi map §4.5.6 — để QC
> định vị element bằng id thay vì scan lúc runtime.

Usage: `/map-testids {UC-ID}`

## Gate
{{include:steps/gate.md}}

*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Đọc `.feature` FE của UC (web/app), các màn Design Spec của nó, tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` (§4.5.6 của platform, nếu có — bảng này gộp mọi UC của platform, **lọc theo cột "Serves SC" khớp SC của UC này** qua §10), và figma-components catalog cho `active_module`.*

## Context
{{include:steps/context-loader.md}}

---

## Step 0 — Platform guard

Phân giải `platform` từ `@trace.platform` / `platform_type`. Test-id là chuyện của **FE/App** — nếu `system` / backend → HALT:
```
❌ /map-testids chỉ áp dụng cho FE/App (web/app). BE không có UI test-id.
```
Phân giải attribute test-id từ `@trace.testid_attr` (hoặc theo module): web `data-testid` · React Native `testID` · Flutter `Key`/`Semantics(identifier:)` · native iOS `accessibilityIdentifier`.

## Step 1 — Thu thập element có action

Từ các step `When` trong `.feature` FE của UC + các màn Design Spec, liệt kê mọi element **có action** mà scenario chạm tới (button, input, link, select, toggle, form-submit). Bỏ qua text/label tĩnh. Với mỗi cái, phân giải component render và phân loại:
- **reused** — khớp một row trong figma-components catalog (component design-system dùng chung);
- **existing** — component riêng của feature đã có trong codebase (brownfield);
- **new** — chưa code (để `/generate-code` lo; chỉ ghi lại id dự kiến).

## Step 2 — Phân giải test-id ổn định cho mỗi element

- **Existing/brownfield:** đọc file component. Nếu element **đã** có test-id (trong attribute của platform) → **reverse-document** nó (dùng lại as-is). Nếu không, gán theo quy ước `{uc-lower}-{screen}-{element}-{type}` (vd `ft001-login-submit-btn`). Không bao giờ nhúng số scenario.
- **Reused:** id được áp ở **usage site** (không bake vào component dùng chung) → gán theo cùng quy ước.
- **Cross-platform:** nếu §4.5.6 của platform **kia** (block `web`/`app` trong cùng tech-doc gộp) đã có id cho cùng element logic, **dùng lại id value đó** (chỉ attribute khác theo platform) để web và app nhất quán và logic QC tái dùng được.

## Step 3 — Đảm bảo component tái dùng forward được test-id (catalog)

Với mỗi component **reused** có action, tra section **`## Test-ID Forwarding`** của catalog (`{paths.domain_knowledge_dir}/figma-components/{active_module}.md`):
- **Đã ghi prop forwarding** → dùng nó ở usage site (Step 4).
- **Chưa ghi** → kiểm tra source component:
  - Đã forward (spread `...props` / có prop `testId`/`testID` / truyền attribute qua) → **ghi** prop vào bảng Test-ID Forwarding của catalog.
  - **Không** forward → **patch component MỘT LẦN** để nhận + forward test-id (web: thêm prop `testId` → render `data-testid={testId}`; RN: `testID`; Flutter: truyền `Key`/`Semantics(identifier:)`; iOS: `accessibilityIdentifier`), rồi ghi vào catalog.

In mọi row catalog được thêm và mọi component dùng chung được patch (chúng đụng code dùng chung — nêu ra để review).

## Step 4 — Patch usage site (chỉ EXTEND)

Với mỗi element có action trong các màn **existing/reused** của UC này, thêm test-id ở usage site — attribute thô cho element thường, hoặc prop forwarding cho component tái dùng — với id từ Step 2. **EXTEND mode:** chỉ đụng attribute/prop; không refactor gì khác. Bỏ qua element đã mang đúng id (idempotent).

## Step 5 — Ghi/làm mới map §4.5.6 Test Selectors

Tạo hoặc cập nhật §4.5.6 (block platform tương ứng) trong tech-doc gộp `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md`:
- Nếu tech-doc tồn tại → cập nhật bảng §4.5.6 của platform này (thêm block §4.5 cho platform nếu chưa có).
- Nếu **chưa** tồn tại (pure brownfield) → ghi một file tối thiểu: header `@trace` (gồm `@trace.testid_attr`) + §4.5.6. `/generate-tech-docs` điền các section còn lại sau; nó không được ghi đè các id §4.5.6 mà lệnh này đã ghi.

Mỗi row: `Test-ID | Element | Component (reused/existing/new) | Action | Serves SC`.

## Step 6 — Handoff

Nếu tech-design sống trong spec repo dùng chung (`spec_source` được set), commit + push (2 tầng) như `/generate-tech-docs`. Patch component dùng chung đi vào FE service submodule (push 2 tầng, xem Sync & Update §4.4).

## Output

{{include:steps/report-footer.md}}

```
/map-testids Hoàn tất — {UC-ID} ({platform})
Elements: {N} mapped — {reused} reused · {existing} existing (backfilled) · {new} để dành cho /generate-code
Forwarding: {M} component dùng chung được patch để forward test-id · {K} row catalog được ghi
§4.5.6: {paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md updated ({N} selectors, {platform})
Next: /review-tech-docs {tech-design}   ← review map §4.5.6 + patch component dùng chung
      /qc-design-test {UC-ID}            ← QC giờ định vị bằng test-id (không scan)
```
