---
phase: 01-p0
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - internal/task/polling_handler.go
  - internal/model/iot_card.go
  - internal/service/client_order/service.go
autonomous: true
requirements:
  - CRITICAL-01
  - CRITICAL-02
must_haves:
  truths:
    - "parseRealnameStatus 返回 constants.RealNameStatusVerified（=1），不再返回硬编码 2"
    - "isFirstRealname 判断使用常量比较，不再使用 == 2"
    - "Model 注释与常量一致：0=未实名, 1=已实名"
    - "client_order 实名校验使用 constants.RealNameStatusVerified，不再硬编码 1"
  artifacts:
    - path: internal/task/polling_handler.go
      provides: "parseRealnameStatus 返回常量值，isFirstRealname 使用常量"
      contains: "constants.RealNameStatusVerified"
    - path: internal/model/iot_card.go
      provides: "Model 字段注释统一"
      contains: "0-未实名 1-已实名"
    - path: internal/service/client_order/service.go
      provides: "实名校验改为常量比较"
      contains: "constants.RealNameStatusVerified"
  key_links:
    - from: internal/task/polling_handler.go
      to: pkg/constants/iot.go
      via: "constants.RealNameStatusVerified"
      pattern: "constants\\.RealNameStatusVerified"
    - from: internal/service/client_order/service.go
      to: pkg/constants/iot.go
      via: "constants.RealNameStatusVerified"
      pattern: "constants\\.RealNameStatusVerified"
---

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

Purpose: 这是整个修复链路的前置条件。轮询写入 2、常量定义 1、校验用 1 三处不一致造成实名链路全面断裂。修复后实名状态全链路统一为 0=未实名、1=已实名。CRITICAL-02 依赖本 Plan 完成才能自动正确。

Output: 
- polling_handler.go 写入值改为常量 1
- iot_card.go 注释与常量统一
- client_order/service.go 校验使用常量
</objective>

<execution_context>
@$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md
@$HOME/.config/opencode/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/01-p0/01-CONTEXT.md

# 修复规格书（核心参考）
@.sisyphus/plans/修正业务-完整方案.md

<interfaces>
<!-- 从 pkg/constants/iot.go 提取的常量，executor 直接使用 -->

```go
// pkg/constants/iot.go（已确认存在，第 47-48 行附近）
const (
    RealNameStatusNotVerified = 0 // 未实名
    RealNameStatusVerified    = 1 // 已实名
)
```

<!-- polling_handler.go 当前错误代码（需改掉） -->
<!-- 第 696-700 行：parseRealnameStatus 返回 2（错误） -->
<!-- 第 170 行：isFirstRealname 使用 == 2（错误） -->

<!-- client_order/service.go 当前代码（第 115 行附近） -->
<!-- assetInfo.RealNameStatus != 1（硬编码，需改为常量） -->
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: 修复 polling_handler.go 实名状态写入值（CRITICAL-01 核心）</name>
  <files>internal/task/polling_handler.go, internal/model/iot_card.go</files>
  <action>
**修改 `internal/task/polling_handler.go`：**

① `parseRealnameStatus` 函数（第 696-700 行附近）：
```go
// 修改前
func (h *PollingHandler) parseRealnameStatus(realStatus bool) int {
    if realStatus {
        return 2 // 已实名
    }
    return 0 // 未实名
}

// 修改后（使用常量，per D-01）
func (h *PollingHandler) parseRealnameStatus(realStatus bool) int {
    if realStatus {
        return constants.RealNameStatusVerified // = 1，已实名
    }
    return constants.RealNameStatusNotVerified // = 0，未实名
}
```

② `isFirstRealname` 判断（第 170 行附近）：
```go
// 修改前
isFirstRealname := (card.RealNameStatus == 0 || card.RealNameStatus == 1) && newRealnameStatus == 2

// 修改后（使用常量比较，per D-01）
isFirstRealname := card.RealNameStatus != constants.RealNameStatusVerified &&
    newRealnameStatus == constants.RealNameStatusVerified
```

③ 全局搜索 `polling_handler.go` 及 `internal/model/dto/` 下 DTO 注释，将所有 `2=已实名`、`1实名中` 改为 `0=未实名, 1=已实名`（执行：`grep -rn "2=已实名\|1实名中\|RealNameStatus.*2" internal/model/dto/ --include="*.go"`）。

**修改 `internal/model/iot_card.go`：**

找到第 30 行附近 `RealNameStatus` 字段的 gorm comment：
```go
// 修改前
RealNameStatus int `gorm:"...; comment:实名状态 0-未实名 1-已实名(行业卡可以保持0)"`

// 修改后（统一，per D-01）
RealNameStatus int `gorm:"...; comment:实名状态 0-未实名 1-已实名"`
```

修改完成后执行：`go build ./...`，确认编译通过，提交一个独立 commit（per D-05）。
  </action>
  <verify>
    <automated>go build ./... && rg "return 2" internal/task/polling_handler.go && echo "FAIL: 仍存在 return 2" || echo "PASS: return 2 已消除"</automated>
  </verify>
  <done>
    - polling_handler.go 中 parseRealnameStatus 不再 return 2，改为 return constants.RealNameStatusVerified
    - isFirstRealname 不再用 == 2，改为 == constants.RealNameStatusVerified
    - iot_card.go 注释统一为 0-未实名 1-已实名
    - go build ./... 编译通过
  </done>
</task>

<task type="auto">
  <name>Task 2: 修复 C 端实名校验（CRITICAL-02）</name>
  <files>internal/service/client_order/service.go</files>
  <action>
**修改 `internal/service/client_order/service.go`（第 115 行附近）：**

找到实名校验判断：
```go
// 修改前（硬编码 1，本质上是 A-1 修完后 DB 里是 1 才会正确，但语义要用常量）
if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != 1 {
    return errors.New(errors.CodeForbidden, "请先完成实名认证")
}

// 修改后（使用常量，per CRITICAL-02 规格）
if packagesNeedRealname(validationResult.Packages) && assetInfo.RealNameStatus != constants.RealNameStatusVerified {
    return errors.New(errors.CodeForbidden, "请先完成实名认证")
}
```

同时检查同文件和 `polling_handler.go:982` 是否有其他硬编码 `!= 1` 的实名判断（`rg "RealNameStatus.*!= 1\|!= 1.*RealNameStatus" internal/`），若有，同样改为常量。

确认 constants 包已正确 import（若未 import，在 import 块补充 `pkgpath/constants`）。

修改完成后执行：`go build ./...`，编译通过后提交独立 commit（per D-05）。
  </action>
  <verify>
    <automated>go build ./... && rg "RealNameStatus != 1" internal/service/client_order/service.go && echo "FAIL: 仍有硬编码" || echo "PASS: 硬编码已消除"</automated>
  </verify>
  <done>
    - client_order/service.go 实名校验改为 constants.RealNameStatusVerified
    - go build ./... 编译通过
    - rg 确认不再有 != 1 的硬编码实名判断
  </done>
</task>

</tasks>

<verification>
整体验收（两个任务完成后）：

```bash
# 1. 编译验证
go build ./...

# 2. 确认 parseRealnameStatus 不再写 2
rg "return 2" internal/task/polling_handler.go

# 3. 确认实名判断全部使用常量
rg "RealNameStatusVerified" internal/task/polling_handler.go internal/service/client_order/service.go

# 4. 搜索遗漏的硬编码
rg "newRealnameStatus == 2\|RealNameStatus == 2\|RealNameStatus != 1" internal/ --include="*.go"
```

人工验收（参见修正业务-完整方案.md 方案 A 验收清单 A-1、A-2）：
- DBHub 执行：`SELECT DISTINCT real_name_status FROM tb_iot_card ORDER BY 1;`
  - 预期：只存在 0 和 1，不存在 2
</verification>

<success_criteria>
1. `go build ./...` 编译通过，无错误
2. `parseRealnameStatus(true)` 返回 1（constants.RealNameStatusVerified），不再返回 2
3. `isFirstRealname` 不再使用 == 2 判断
4. `client_order/service.go` 实名校验使用常量，不再硬编码 1
5. Model 注释与常量定义一致
6. 两个独立 commit 已提交
</success_criteria>

<output>
完成后创建 `.planning/phases/01-p0/01-01-SUMMARY.md`，记录：
- 修改了哪些文件（文件路径 + 改动说明）
- 关键代码片段（修改前后对比）
- 编译验证结果
- CRITICAL-01 和 CRITICAL-02 完成状态
</output>
