---
phase: 01-p0
plan: 01
subsystem: realname-status
tags: [bug-fix, constants, critical, realname]
dependency_graph:
  requires: []
  provides: [CRITICAL-01, CRITICAL-02]
  affects: [polling_handler, client_order, scheduler, iot_card_service, asset_dto]
tech_stack:
  added: []
  patterns: [constants-over-magic-numbers]
key_files:
  created: []
  modified:
    - internal/task/polling_handler.go
    - internal/model/iot_card.go
    - internal/model/dto/asset_dto.go
    - internal/polling/scheduler.go
    - internal/service/iot_card/service.go
    - internal/service/client_order/service.go
    - internal/handler/app/client_realname.go
decisions:
  - 统一使用 constants.RealNameStatusVerified(=1) 替代所有硬编码 1、2 的实名状态判断
  - scheduler.go 中 0/1/2 三态判断简化为已实名/未实名两态（符合常量设计）
metrics:
  duration_minutes: 15
  completed_date: "2026-03-27"
  tasks_completed: 2
  files_modified: 7
---

# Phase 01 Plan 01: 统一实名状态常量 Summary

**一句话总结：** 将全链路 7 处硬编码实名状态值（包括错误的 `return 2`）统一改为 `constants.RealNameStatusVerified(=1)` / `constants.RealNameStatusNotVerified(=0)`，修复 CRITICAL-01 和 CRITICAL-02。

---

## Objective Achieved

统一实名状态常量（CRITICAL-01），并修复 C 端实名校验（CRITICAL-02）。

实名链路三处不一致（轮询写入 2、常量定义 1、C 端校验 1）造成实名状态链路全面断裂，修复后全链路统一为 `0=未实名、1=已实名`。

---

## Tasks Completed

| Task | Name | Commit | Files |
|------|------|--------|-------|
| 1 | 修复 polling_handler.go 实名状态写入值（CRITICAL-01） | `1fd0072` | polling_handler.go, iot_card.go, asset_dto.go, scheduler.go, iot_card/service.go |
| 2 | 修复 C 端实名校验（CRITICAL-02） | `da50a35` | client_order/service.go, client_realname.go |

---

## Key Changes

### Task 1 — CRITICAL-01 核心修复

**① `internal/task/polling_handler.go` — `parseRealnameStatus`**

```go
// 修改前（错误：写入 2 到数据库）
func (h *PollingHandler) parseRealnameStatus(realStatus bool) int {
    if realStatus {
        return 2 // 已实名
    }
    return 0 // 未实名
}

// 修改后（正确：写入常量值 1）
func (h *PollingHandler) parseRealnameStatus(realStatus bool) int {
    if realStatus {
        return constants.RealNameStatusVerified // = 1，已实名
    }
    return constants.RealNameStatusNotVerified // = 0，未实名
}
```

**② `internal/task/polling_handler.go` — `isFirstRealname`**

```go
// 修改前（错误：硬编码 == 2 判断）
isFirstRealname := (card.RealNameStatus == 0 || card.RealNameStatus == 1) && newRealnameStatus == 2

// 修改后（正确：使用常量比较，逻辑等价但语义清晰）
isFirstRealname := card.RealNameStatus != constants.RealNameStatusVerified &&
    newRealnameStatus == constants.RealNameStatusVerified
```

**③ `internal/model/iot_card.go` — Model gorm comment**

```go
// 修改前
RealNameStatus int `gorm:"...comment:实名状态 0-未实名 1-已实名(行业卡可以保持0)" json:"real_name_status"`

// 修改后（统一注释，去除误导性括号说明）
RealNameStatus int `gorm:"...comment:实名状态 0-未实名 1-已实名" json:"real_name_status"`
```

**④ `internal/model/dto/asset_dto.go` — DTO description**

```go
// 修改前（错误：包含 1实名中 2已实名 的旧三态描述）
RealNameStatus int `json:"real_name_status" description:"实名状态：0未实名 1实名中 2已实名"`

// 修改后（正确：两态）
RealNameStatus int `json:"real_name_status" description:"实名状态：0未实名 1已实名"`
```

**⑤ `internal/polling/scheduler.go` — `getCardCondition`**

```go
// 修改前（错误：使用硬编码 0/1/2 三态判断）
if card.RealNameStatus == 0 || card.RealNameStatus == 1 {
    return "not_real_name"
}
if card.RealNameStatus == 2 {
    // ...
}

// 修改后（正确：两态常量判断）
if card.RealNameStatus != constants.RealNameStatusVerified {
    return "not_real_name"
}
if card.RealNameStatus == constants.RealNameStatusVerified {
    // ...
}
```

**⑥ `internal/service/iot_card/service.go` — `parseGatewayRealnameStatus`**

```go
// 修改前（错误：返回硬编码 2）
// true=已实名(2)，false=未实名(0)
func parseGatewayRealnameStatus(realStatus bool) int {
    if realStatus { return 2 }
    return 0
}

// 修改后（正确：返回常量）
// true=已实名(1)，false=未实名(0)
func parseGatewayRealnameStatus(realStatus bool) int {
    if realStatus { return constants.RealNameStatusVerified }
    return constants.RealNameStatusNotVerified
}
```

---

### Task 2 — CRITICAL-02 修复

**① `internal/service/client_order/service.go`**

```go
// 修改前（硬编码 1，语义不清晰）
if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != 1 {

// 修改后（常量比较，语义明确）
if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != constants.RealNameStatusVerified {
```

**② `internal/handler/app/client_realname.go`**

```go
// 修改前（硬编码 1）
if targetCard.RealNameStatus == 1 {

// 修改后（常量）
if targetCard.RealNameStatus == constants.RealNameStatusVerified {
```

---

## Verification Results

```
✅ go build ./...      — 编译通过，无错误
✅ return 2 已消除     — polling_handler.go 中不再有 return 2
✅ 常量使用确认        — polling_handler.go 和 client_order/service.go 均使用 constants.RealNameStatusVerified
✅ 无遗漏硬编码        — rg 未发现 newRealnameStatus==2 / RealNameStatus==2 / RealNameStatus!=1
```

---

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 2 - 缺失修复] 修复 asset_dto.go DTO description**
- **Found during:** Task 1 全局搜索
- **Issue:** `asset_dto.go` 的 `RealNameStatus` description 仍含旧三态描述 `1实名中 2已实名`
- **Fix:** 更新为 `0未实名 1已实名`
- **Files modified:** `internal/model/dto/asset_dto.go`
- **Commit:** `1fd0072`

**2. [Rule 2 - 缺失修复] 修复 scheduler.go 硬编码三态判断**
- **Found during:** Task 1 全局搜索
- **Issue:** `scheduler.go:getCardCondition` 使用 `RealNameStatus == 0 || == 1 || == 2` 硬编码
- **Fix:** 改为 `!= constants.RealNameStatusVerified` / `== constants.RealNameStatusVerified`
- **Files modified:** `internal/polling/scheduler.go`
- **Commit:** `1fd0072`

**3. [Rule 2 - 缺失修复] 修复 iot_card/service.go 另一处 return 2**
- **Found during:** Task 1 全局搜索
- **Issue:** `parseGatewayRealnameStatus` 函数也返回硬编码 `2`，与 polling_handler.go 同等问题
- **Fix:** 改为常量返回
- **Files modified:** `internal/service/iot_card/service.go`
- **Commit:** `1fd0072`

**4. [Rule 2 - 缺失修复] 修复 client_realname.go Handler 层硬编码**
- **Found during:** Task 2 全局搜索
- **Issue:** `client_realname.go:128` Handler 层 `== 1` 硬编码实名判断
- **Fix:** 改为 `constants.RealNameStatusVerified`
- **Files modified:** `internal/handler/app/client_realname.go`
- **Commit:** `da50a35`

---

## Requirements Completed

- ✅ **CRITICAL-01**: 实名状态常量统一（DB 写入值 2 vs 常量 1，所有链路断裂）— 已修复
- ✅ **CRITICAL-02**: C 端实名校验修复（依赖 CRITICAL-01）— 已修复

---

## Self-Check: PASSED

- ✅ `internal/task/polling_handler.go` — 已修改并提交
- ✅ `internal/model/iot_card.go` — 已修改并提交
- ✅ `internal/service/client_order/service.go` — 已修改并提交
- ✅ commit `1fd0072` — 存在（Task 1）
- ✅ commit `da50a35` — 存在（Task 2）
