# New-Session Handoff Prompt — Fix Compound Autoname Ordering Bug (PR-1a Follow-up)

> Copy-paste the block below into a fresh Claude Code session. Self-contained: includes branch state, bug description, fix approach, test setup, verification steps.

---

## Prompt (paste into new session)

继续处理 PR #1140 (`feat/autonumber-v2-cutover`) 的 compound autoname ordering bug。这是 PR-1a 已 merge 到 standard-autonumber 路径之后的 follow-up 修复。

### 先读

1. **Known-issue doc**（完整 repro + 根因 + 3 个 fix 选项）：
   `docs/design/autonumber-v2-known-issue-autoname-ordering.md`
2. **PR-1a 上下文**：https://github.com/pingcap-inc/MetaDrivenPlatform4AI/pull/1140 — runtime verify section（Round-8 comment）
3. **Memory**（自动加载）：`project_autonumber_v2_runtime_findings.md` + `feedback_autonumber_column_convention.md`
4. **PRD**：`docs/design/autonumber-engine-v2.md` §3.3 `keep_existing` semantics + §5.1 AssignOne

### Bug one-liner

`persistence_insert.go:64 enrichQuoteFromOpportunity` 在 `persistence_insert.go:142 assignAutoNumbers` 之前运行，把 `Quote.Name = Opportunity.Name` 填充。等 engine 跑到 Quote.Name 时 `keep_existing`（PRD §3.3）看见非空就 skip——compound autoname `{Account.BillingCountry}-QT-{YY}{MM}{DD}-{00}` 永远不渲染，实际 Quote.Name = 关联 Opportunity.Name。

同样的 ordering 问题很可能也影响 Contract.Name / Order.Name（需要排查其它 enrichment 入口）。

### 任务

1. 开 worktree：
   ```
   git worktree add -b fix/autonumber-autoname-enrichment-order .claude/worktrees/autoname-fix origin/main
   ```
   或如果 PR-1a 已 merge，从 main；未 merge 则 `from feat/autonumber-v2-cutover`。
2. 采用 **Option A**（known-issue doc §Recommended plan 推荐）：
   - 在 `backend/internal/features/records/persistence_service.go` 或 `persistence_insert.go` 加 private helper `fieldHasAutoNumberFormat(ctx, objectName, fieldName string) bool`
   - 在 `enrichQuoteFromOpportunity`（+ 同名 Order/Contract enrichers，如果有的话）的字段拷贝前 guard：`if fieldHasAutoNumberFormat(...) { continue }`
3. 先写 failing integration test（TDD RED）：
   ```
   backend/internal/features/records/persistence_insert_autoname_test.go:TestQuoteAutoname_EngineWinsOverOpportunityEnrichment
   ```
   Setup: Quote.Name 有 `auto_number_format = '{Account.BillingCountry}-QT-{YY}{MM}{DD}-{00}'`，Account.BillingCountry='JP', Opportunity.Name='Some Opp'。
   POST Quote {OpportunityId}.
   Expect `Quote.Name` ~ `JP-QT-<YYMMDD>-01`, NOT `Some Opp`.
4. Fix 后让 test 过 GREEN。
5. 补 agent-browser evidence（手工 runtime test） — 用下面的 test-setup section。
6. dual-model review（Claude go-reviewer + Codex adversarial）+ `/review "full review"`。
7. 开 PR `fix: compound autoname ordering — engine overrides enrichment`，base=main（或 feat/autonumber-v2-cutover 如果还没 merge），draft。

### 本地测试 setup（已 ready）

**TiDB**: 本地 docker 容器 `metadrivenplatform4ai-main-tidb-main-1`，`localhost:4000`，DB `nexuscrm`，无密码。

**已种 autonumber 配置**（localhost nexuscrm DB）：
```sql
-- 4 条 _System_Field autonumber_format rows:
SELECT o.ApiName obj, f.ApiName field, f.auto_number_format FROM _System_Field f
JOIN _System_Object o ON o.Id=f.ObjectId WHERE f.auto_number_format IS NOT NULL;
-- Contract.ContractNumber = {00000000}
-- Order.OrderNumber       = {00000000}
-- Quote.QuoteNumber       = {00000000}
-- Quote.Name              = {Account.BillingCountry}-QT-{YY}{MM}{DD}-{00}
```

**已 ALTER**：本地 DB 已经把 7 列从 PascalCase 改 snake_case，与 commit 45008c2a 一致。

**Server 启动**：
```bash
cat > /tmp/start-nexus.sh <<'SH'
#!/usr/bin/env bash
export TIDB_HOST=127.0.0.1 TIDB_PORT=4000 TIDB_USER=root TIDB_PASSWORD='' TIDB_DATABASE=nexuscrm
export SKIP_BOOTSTRAP=true JWT_SECRET='test-autonumber-verify' PORT=8084
export CORS_ALLOWED_ORIGINS='http://localhost:5173,http://localhost:8084'
export FRONTEND_URL='http://localhost:5173' NEXUS_ENV=''
cd /Users/amber/claude/MetaDrivenPlatform4AI/.claude/worktrees/autoname-fix/backend
go build -o /tmp/nexus-server ./cmd/server
exec /tmp/nexus-server
SH
chmod +x /tmp/start-nexus.sh
bash /tmp/start-nexus.sh > /tmp/server.log 2>&1 &
```

**Auth**:
```bash
TOKEN=$(curl -sS -X POST http://localhost:8084/services/oauth2/token \
  -H 'Origin: http://localhost:5173' \
  -d 'grant_type=password&client_id=nexuscrm-ui&client_secret=nexuscrm-ui-internal&username=admin@test.com&password=L9jPkSaG5pdDRX7WPL3V!' \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
```

**Reproduction of bug** (before fix — expect Quote.Name == "Some Opp" NOT autoname):
```bash
# Clean Quote/Opp/Account
mysql -h 127.0.0.1 -P 4000 -u root nexuscrm -e "DELETE FROM Quote; DELETE FROM Opportunity; DELETE FROM Account;
INSERT INTO _System_AutoNumberCounter (Id, FieldId, ScopeKey, NextValue) SELECT CONCAT('counter::', f.Id, '::'), f.Id, '', 1 FROM _System_Field f WHERE f.auto_number_format IS NOT NULL ON DUPLICATE KEY UPDATE NextValue=1;"

# Unrequire Quote.Name so POST without Name passes
mysql -h 127.0.0.1 -P 4000 -u root nexuscrm -e "UPDATE _System_Field f JOIN _System_Object o ON o.Id=f.ObjectId SET f.Required=0 WHERE o.ApiName='Quote' AND f.ApiName='Name';"

# Restart server (to pick up Required=0 from metadata cache)
pkill -f nexus-server; sleep 3
bash /tmp/start-nexus.sh > /tmp/server.log 2>&1 &

ACCT=$(curl -sS -X POST http://localhost:8084/services/data/v63.0/sobjects/Account \
  -H "Authorization: Bearer $TOKEN" -H 'Origin: http://localhost:5173' -H 'Content-Type: application/json' \
  -d '{"Name":"Japan Corp","BillingCountry":"JP"}')
ACCT_ID=$(echo "$ACCT" | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')

OPP=$(curl -sS -X POST http://localhost:8084/services/data/v63.0/sobjects/Opportunity \
  -H "Authorization: Bearer $TOKEN" -H 'Origin: http://localhost:5173' -H 'Content-Type: application/json' \
  -d "{\"AccountId\":\"$ACCT_ID\",\"Name\":\"Some Opp\",\"StageName\":\"Prospecting\",\"CloseDate\":\"2026-05-01\"}")
OPP_ID=$(echo "$OPP" | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')

QT=$(curl -sS -X POST http://localhost:8084/services/data/v63.0/sobjects/Quote \
  -H "Authorization: Bearer $TOKEN" -H 'Origin: http://localhost:5173' -H 'Content-Type: application/json' \
  -d "{\"OpportunityId\":\"$OPP_ID\"}")
QT_ID=$(echo "$QT" | sed -n 's/.*"id":"\([^"]*\)".*/\1/p')

# Current (buggy): Name = "Some Opp"
# After fix: Name = "JP-QT-260418-01"
mysql -h 127.0.0.1 -P 4000 -u root nexuscrm -e "SELECT Id, Name, QuoteNumber FROM Quote WHERE Id='$QT_ID';"
```

### Acceptance

- Integration test GREEN
- Manual reproduction: Quote.Name matches pattern `^JP-QT-\d{6}-\d{2}$` (not `Some Opp`)
- `go test -race -count=1 -short` on `./backend/internal/features/records/...` 全绿
- Dual-model review PASS
- PR body 包含 before/after Quote.Name 对比证据

### Constraints

- 不要 revert 任何 PR-1a 的 fix（R2/R4/R5/R6/R7/R8 commits）
- 不要改 engine 的 keep_existing 语义（这是 PRD 契约，不能动）—— 选 Option A guard enrichment
- 不要 merge；开 draft PR 让用户 review
- 按 CLAUDE.md §5.2 Local Runtime Verification Before Merge — 必须本地跑起来确认 bug 修复再请求 review
- 按用户决策：之后有问题按你的倾向（CRITICAL/HIGH 优先 Fix，LOW 可 accept + document），不重复问

开始。
