重构:完善 IoT 模型架构规范和数据库设计

- 完善 GORM 模型规范:货币字段使用 int64(分为单位)、JSONB 字段规范、模型结构规范
- 修复所有 IoT 模型的架构违规问题
- 更新 CLAUDE.md 开发指南,补充完整的数据库设计规范和模型示例
- 添加数据库迁移脚本(000006)用于架构重构
- 归档 OpenSpec 变更文档(2026-01-12-fix-iot-models-violations)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-12 17:43:12 +08:00
parent 4507de577b
commit 2150fb6ab9
21 changed files with 2774 additions and 263 deletions

View File

@@ -0,0 +1,152 @@
## Why
在之前的 IoT SIM 管理系统提案2026-01-12-iot-sim-management中创建的所有数据模型存在严重的架构违规问题完全没有遵循项目的核心开发规范。这些违规导致代码不一致、可维护性差、违背项目设计原则。
**核心问题:**
1. **未使用基础模型**:所有 IoT 模型都没有嵌入 `BaseModel`,缺少统一的 `creator``updater` 字段
2. **未使用 gorm.Model**:部分模型没有嵌入 `gorm.Model`,缺少标准的 `ID``CreatedAt``UpdatedAt``DeletedAt` 字段
3. **字段命名不规范**:未显式指定 `column` 标签,依赖 GORM 自动转换(违反规范)
4. **字段定义不完整**:缺少必要的数据库约束标签(`not null``uniqueIndex`、索引等)
5. **数据类型不一致**
- 货币字段使用 `float64` 而不是整数(分为单位)
- ID 字段类型不一致(`uint` vs `bigint`
- 时间字段缺少 `autoCreateTime`/`autoUpdateTime` 标签
6. **表名不符合规范**:使用复数形式(`iot_cards`)而不是项目约定的 `tb_` 前缀单数形式
7. **缺少中文注释**:部分字段缺少清晰的中文注释说明业务含义
8. **软删除支持不一致**:某些应该支持软删除的模型缺少 `gorm.Model` 嵌入
**对比现有规范模型Account、PersonalCustomer**
**正确示例Account 模型):**
```go
type Account struct {
gorm.Model // ✅ 嵌入标准模型ID、CreatedAt、UpdatedAt、DeletedAt
BaseModel `gorm:"embedded"` // ✅ 嵌入基础模型Creator、Updater
Username string `gorm:"column:username;type:varchar(50);uniqueIndex:idx_account_username,where:deleted_at IS NULL;not null;comment:用户名" json:"username"`
// ✅ 显式 column 标签
// ✅ 明确类型和长度
// ✅ 唯一索引 + 软删除过滤
// ✅ not null 约束
// ✅ 中文注释
}
func (Account) TableName() string {
return "tb_account" // ✅ tb_ 前缀 + 单数
}
```
**错误示例IotCard 模型):**
```go
type IotCard struct {
ID uint `gorm:"column:id;primaryKey;comment:IoT 卡 ID" json:"id"`
// ❌ 没有 gorm.Model
// ❌ 没有 BaseModel
// ❌ 手动定义 ID应该由 gorm.Model 提供)
// ❌ 没有 DeletedAt无法软删除
CostPrice float64 `gorm:"column:cost_price;type:decimal(10,2);default:0;comment:成本价(元)" json:"cost_price"`
// ❌ 使用 float64 而不是整数(分为单位)
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime;comment:创建时间" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime;comment:更新时间" json:"updated_at"`
// ❌ 手动定义(应该由 gorm.Model 提供)
}
func (IotCard) TableName() string {
return "iot_cards" // ❌ 复数形式,没有 tb_ 前缀
}
```
**影响范围:**
需要修复以下所有 IoT 相关模型(约 25 个模型文件):
- `internal/model/iot_card.go`IotCard
- `internal/model/device.go`Device、DeviceSimBinding
- `internal/model/number_card.go`NumberCard
- `internal/model/package.go`PackageSeries、Package、AgentPackageAllocation、PackageUsage
- `internal/model/order.go`Order
- `internal/model/commission.go`AgentHierarchy、CommissionRule、CommissionLadder、CommissionCombinedCondition、CommissionRecord、CommissionApproval、CommissionTemplate、CarrierSettlement
- `internal/model/financial.go`CommissionWithdrawalRequest、CommissionWithdrawalSetting、PaymentMerchantSetting
- `internal/model/system.go`DevCapabilityConfig、CardReplacementRequest
- `internal/model/carrier.go`Carrier
- `internal/model/data_usage.go`DataUsageRecord
- `internal/model/polling.go`PollingConfig
## What Changes
- 重构所有 IoT 相关数据模型,使其完全符合项目开发规范
- 统一所有模型的字段定义、类型、约束、注释格式
- 确保所有模型与现有用户体系模型Account、PersonalCustomer保持一致的架构风格
- 更新数据库迁移脚本以反映模型变更
## Capabilities
### Modified Capabilities
#### 核心数据模型规范化
- `iot-card`: 修改 IoT 卡业务模型 - 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_iot_card`,使用整数存储金额,完善索引和约束
- `iot-device`: 修改设备业务模型 - 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_device`,规范化所有关联字段
- `iot-number-card`: 修改号卡业务模型 - 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_number_card`,使用整数存储金额
- `iot-package`: 修改套餐管理模型 - 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名`tb_package_series``tb_package``tb_agent_package_allocation``tb_package_usage`),使用整数存储金额
- `iot-order`: 修改订单管理模型 - 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_order`,使用整数存储金额,规范化 JSONB 字段
- `iot-agent-commission`: 修改代理分佣模型 - 统一所有分佣相关模型字段定义,嵌入 BaseModel 和 gorm.Model修正表名添加 `tb_` 前缀),使用整数存储金额
#### 财务和系统模型规范化
- 修改财务相关模型CommissionWithdrawalRequest、CommissionWithdrawalSetting、PaymentMerchantSetting- 统一字段定义,使用整数存储金额,完善索引和约束
- 修改系统配置模型DevCapabilityConfig、CardReplacementRequest- 统一字段定义,嵌入 BaseModel 和 gorm.Model
- 修改运营商模型Carrier- 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_carrier`
- 修改流量记录模型DataUsageRecord- 统一字段定义,嵌入 gorm.Model修正表名为 `tb_data_usage_record`
- 修改轮询配置模型PollingConfig- 统一字段定义,嵌入 BaseModel 和 gorm.Model修正表名为 `tb_polling_config`
## Impact
**代码变更:**
- 重构约 25 个 GORM 模型文件(`internal/model/`
- 所有模型的字段定义将发生变化(字段名、类型、标签)
- 所有表名将从复数变为 `tb_` 前缀单数形式
**数据库变更:**
- 需要生成新的数据库迁移脚本以反映模型变更
- 表名变更(如 `iot_cards``tb_iot_card`
- 字段变更(如 `cost_price DECIMAL``cost_price BIGINT`,金额从元改为分)
- 新增字段(`creator``updater``deleted_at`
- 新增索引和约束
**向后兼容性:**
-**不兼容变更**:此次修复涉及破坏性变更(表名、字段类型)
- 由于 IoT 模块尚未实际部署到生产环境,可以直接修改而无需数据迁移
- 如果已有测试数据,需要编写数据迁移脚本
**业务影响:**
- 不影响现有用户体系Account、Role、Permission 等)
- 不影响个人客户模块PersonalCustomer
- IoT 模块的 Service 层和 Handler 层代码需要相应调整(字段类型变化)
**依赖关系:**
- 必须在实现 IoT 业务逻辑Handlers、Services、Stores之前修复
- 修复后才能生成正确的数据库迁移脚本
- 修复后才能生成准确的 API 文档
**文档变更:**
- 更新 `CLAUDE.md` 中的数据库设计原则和 GORM 模型字段规范
- 补充完整的字段定义规范(显式 column 标签、类型定义、注释要求)
- 添加金额字段整数存储的详细说明和示例
- 完善表名命名规范和 BaseModel 使用说明
- 确保全局规范文档与实际实现保持一致
**明确排除的范围**(本次不涉及):
- Handler 层代码修改(将在后续任务中处理)
- Service 层代码修改(将在后续任务中处理)
- Store 层代码修改(将在后续任务中处理)
- DTO 模型调整(请求/响应结构体)
- 单元测试和集成测试
- API 文档更新
**风险和注意事项:**
- 所有金额字段从 `float64` 改为 `int64`(分为单位),需要在业务逻辑中进行单位转换
- 表名变更需要确保迁移脚本正确执行
- 新增的 `creator``updater` 字段需要在业务逻辑中正确赋值
- 软删除(`DeletedAt`的引入可能需要调整查询逻辑GORM 会自动处理)