---
name: model-standards
description: GORM Model 模型规范。创建或修改数据库模型时使用。包含模型结构、字段标签、TableName 实现等规范。
---

# Model 模型规范

**创建或修改 `internal/model/` 下的数据库模型时必须遵守本规范。**

## 触发条件

在以下情况下必须遵守本规范：
- 创建新的数据库模型
- 修改现有模型的字段
- 添加新的数据库表

## 必须遵守的模型结构

```go
// ModelName 模型名称模型
// 详细的业务说明（2-3行）
// 特殊说明（如果有）
type ModelName struct {
	gorm.Model              // 包含 ID、CreatedAt、UpdatedAt、DeletedAt
	BaseModel `gorm:"embedded"` // 包含 Creator、Updater
	Field1    string `gorm:"column:field1;type:varchar(50);not null;comment:字段1说明" json:"field1"`
	// ... 其他字段
}

// TableName 指定表名
func (ModelName) TableName() string {
	return "tb_model_name"
}
```

## 关键要点

### 必须嵌入基础模型

- ✅ **必须**嵌入 `gorm.Model` 和 `BaseModel`
- ❌ **禁止**手动定义 ID、CreatedAt、UpdatedAt、DeletedAt、Creator、Updater

### 必须添加中文注释

- ✅ **必须**为模型添加中文注释，说明业务用途（参考 `internal/model/iot_card.go`）
- ✅ **必须**在每个字段的 `comment` 标签中添加中文说明
- ✅ **必须**为导出的类型编写 godoc 格式的文档注释

### 必须实现 TableName

- ✅ **必须**实现 `TableName()` 方法
- ✅ 表名使用 `tb_` 前缀

### 字段标签规范

- ✅ 所有字段必须显式指定 `gorm:"column:field_name"` 标签
- ✅ 金额字段使用 `int64` 类型，单位为分
- ✅ 时间字段使用 `*time.Time`（可空）或 `time.Time`（必填）
- ✅ JSONB 字段需要实现 `driver.Valuer` 和 `sql.Scanner` 接口

## 完整示例

```go
// IotCard 物联网卡模型
// 记录物联网卡的基础信息、状态和套餐关联
// 支持单卡和设备绑定两种使用模式
type IotCard struct {
	gorm.Model
	BaseModel   `gorm:"embedded"`
	ICCID       string     `gorm:"column:iccid;type:varchar(20);uniqueIndex;not null;comment:ICCID卡号" json:"iccid"`
	IMSI        string     `gorm:"column:imsi;type:varchar(20);comment:IMSI号" json:"imsi"`
	Status      int        `gorm:"column:status;type:smallint;default:0;comment:状态(0:未激活,1:已激活,2:已停机)" json:"status"`
	ActivatedAt *time.Time `gorm:"column:activated_at;comment:激活时间" json:"activated_at"`
	ShopID      uint       `gorm:"column:shop_id;index;comment:所属店铺ID" json:"shop_id"`
}

// TableName 指定表名
func (IotCard) TableName() string {
	return "tb_iot_card"
}
```

## AI 助手检查清单

修改模型后必须检查：

1. ✅ 是否嵌入了 `gorm.Model` 和 `BaseModel`
2. ✅ 是否有 godoc 格式的模型注释
3. ✅ 所有字段是否有 `gorm:"column:xxx"` 标签
4. ✅ 所有字段是否有 `comment:xxx` 说明
5. ✅ 是否实现了 `TableName()` 方法
6. ✅ 表名是否使用 `tb_` 前缀
7. ✅ 金额字段是否使用 `int64`（单位：分）
