- 完善 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>
8.2 KiB
8.2 KiB
Why
在之前的 IoT SIM 管理系统提案(2026-01-12-iot-sim-management)中创建的所有数据模型存在严重的架构违规问题,完全没有遵循项目的核心开发规范。这些违规导致代码不一致、可维护性差、违背项目设计原则。
核心问题:
- 未使用基础模型:所有 IoT 模型都没有嵌入
BaseModel,缺少统一的creator和updater字段 - 未使用 gorm.Model:部分模型没有嵌入
gorm.Model,缺少标准的ID、CreatedAt、UpdatedAt、DeletedAt字段 - 字段命名不规范:未显式指定
column标签,依赖 GORM 自动转换(违反规范) - 字段定义不完整:缺少必要的数据库约束标签(
not null、uniqueIndex、索引等) - 数据类型不一致:
- 货币字段使用
float64而不是整数(分为单位) - ID 字段类型不一致(
uintvsbigint) - 时间字段缺少
autoCreateTime/autoUpdateTime标签
- 货币字段使用
- 表名不符合规范:使用复数形式(
iot_cards)而不是项目约定的tb_前缀单数形式 - 缺少中文注释:部分字段缺少清晰的中文注释说明业务含义
- 软删除支持不一致:某些应该支持软删除的模型缺少
gorm.Model嵌入
对比现有规范模型(Account、PersonalCustomer):
✅ 正确示例(Account 模型):
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 模型):
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 会自动处理)