package model

const (
	UserStatusActive   = "active"
	UserStatusLocked   = "locked"
	UserStatusDisabled = "disabled"

	JobStatusPending   = "pending"
	JobStatusRunning   = "running"
	JobStatusSucceeded = "succeeded"
	JobStatusFailed    = "failed"
	JobStatusCanceled  = "canceled"
)

type User struct {
	ID            uint   `gorm:"primaryKey" json:"id"`
	Username      string `gorm:"size:64;uniqueIndex;not null" json:"account"`
	Name          string `gorm:"size:80;not null" json:"name"`
	PasswordHash  string `gorm:"size:255;not null" json:"-"`
	Team          string `gorm:"size:80" json:"team"`
	Status        string `gorm:"size:24;index;not null;default:active" json:"status"`
	MFAEnabled    bool   `gorm:"not null;default:false" json:"mfaEnabled"`
	LastLoginAtMS *int64 `gorm:"column:last_login_at_ms" json:"lastLoginAtMs"`
	Roles         []Role `gorm:"many2many:admin_user_roles;" json:"roles"`
	CreatedAtMS   int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS   int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (User) TableName() string {
	return "admin_users"
}

type Role struct {
	ID          uint         `gorm:"primaryKey" json:"id"`
	Name        string       `gorm:"size:80;uniqueIndex;not null" json:"name"`
	Code        string       `gorm:"size:80;uniqueIndex;not null" json:"code"`
	Description string       `gorm:"size:255" json:"description"`
	Users       []User       `gorm:"many2many:admin_user_roles;" json:"-"`
	Permissions []Permission `gorm:"many2many:admin_role_permissions;" json:"permissions"`
	CreatedAtMS int64        `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64        `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (Role) TableName() string {
	return "admin_roles"
}

type Permission struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	Name        string `gorm:"size:100;not null" json:"name"`
	Code        string `gorm:"size:100;uniqueIndex;not null" json:"code"`
	Kind        string `gorm:"size:32;index;not null" json:"kind"`
	Description string `gorm:"size:255" json:"description"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (Permission) TableName() string {
	return "admin_permissions"
}

type Menu struct {
	ID             uint   `gorm:"primaryKey" json:"id"`
	ParentID       *uint  `gorm:"index" json:"parentId"`
	Title          string `gorm:"size:80;not null" json:"label"`
	Code           string `gorm:"size:100;uniqueIndex;not null" json:"code"`
	Path           string `gorm:"size:160" json:"path"`
	Icon           string `gorm:"size:64" json:"icon"`
	PermissionCode string `gorm:"size:100;index" json:"permissionCode"`
	Sort           int    `gorm:"not null;default:0" json:"sort"`
	Visible        bool   `gorm:"not null;default:true" json:"visible"`
	CreatedAtMS    int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS    int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (Menu) TableName() string {
	return "admin_menus"
}

type AppConfig struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	Group       string `gorm:"size:64;index:idx_admin_app_config_group_key,unique;not null" json:"group"`
	Key         string `gorm:"size:100;index:idx_admin_app_config_group_key,unique;not null" json:"key"`
	Value       string `gorm:"type:text" json:"value"`
	Description string `gorm:"size:255" json:"description"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppConfig) TableName() string {
	return "admin_app_configs"
}

type AppBanner struct {
	ID                uint   `gorm:"primaryKey" json:"id"`
	AppCode           string `gorm:"size:32;index:idx_admin_app_banners_app_sort,not null;default:lalu" json:"appCode"`
	CoverURL          string `gorm:"size:1024;not null" json:"coverUrl"`
	RoomSmallImageURL string `gorm:"column:room_small_image_url;size:1024;not null;default:'';comment:房间内小屏图 URL" json:"roomSmallImageUrl"`
	BannerType        string `gorm:"size:16;not null" json:"bannerType"`
	DisplayScope      string `gorm:"size:128;index:idx_admin_app_banners_display,not null;default:home;comment:显示范围，多选逗号分隔：首页、房间内或充值页" json:"displayScope"`
	Param             string `gorm:"size:2048" json:"param"`
	Status            string `gorm:"size:24;index:idx_admin_app_banners_app_sort,not null;default:active" json:"status"`
	Platform          string `gorm:"size:24;index:idx_admin_app_banners_scope,not null" json:"platform"`
	SortOrder         int    `gorm:"index:idx_admin_app_banners_app_sort,not null;default:0" json:"sortOrder"`
	RegionID          int64  `gorm:"index:idx_admin_app_banners_scope,not null;default:0" json:"regionId"`
	CountryCode       string `gorm:"size:8;index:idx_admin_app_banners_scope" json:"countryCode"`
	Description       string `gorm:"size:255" json:"description"`
	StartsAtMS        int64  `gorm:"column:starts_at_ms;not null;default:0;comment:投放开始时间，UTC epoch ms" json:"startsAtMs"`
	EndsAtMS          int64  `gorm:"column:ends_at_ms;not null;default:0;comment:投放结束时间，UTC epoch ms" json:"endsAtMs"`
	CreatedAtMS       int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS       int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppBanner) TableName() string {
	return "admin_app_banners"
}

type AppSplashScreen struct {
	ID                uint   `gorm:"primaryKey" json:"id"`
	AppCode           string `gorm:"size:32;index:idx_admin_app_splash_screens_app_sort,not null;default:lalu" json:"appCode"`
	CoverURL          string `gorm:"size:1024;not null" json:"coverUrl"`
	SplashType        string `gorm:"size:16;not null" json:"splashType"`
	Param             string `gorm:"size:2048" json:"param"`
	Status            string `gorm:"size:24;index:idx_admin_app_splash_screens_app_sort,not null;default:active" json:"status"`
	Platform          string `gorm:"size:24;index:idx_admin_app_splash_screens_scope,not null" json:"platform"`
	SortOrder         int    `gorm:"index:idx_admin_app_splash_screens_app_sort,not null;default:0" json:"sortOrder"`
	RegionID          int64  `gorm:"index:idx_admin_app_splash_screens_scope,not null;default:0" json:"regionId"`
	CountryCode       string `gorm:"size:8;index:idx_admin_app_splash_screens_scope" json:"countryCode"`
	Description       string `gorm:"size:255" json:"description"`
	DisplayDurationMS int    `gorm:"column:display_duration_ms;not null;default:3000;comment:开屏展示时长，毫秒；0 表示客户端默认值" json:"displayDurationMs"`
	StartsAtMS        int64  `gorm:"column:starts_at_ms;not null;default:0;comment:投放开始时间，UTC epoch ms" json:"startsAtMs"`
	EndsAtMS          int64  `gorm:"column:ends_at_ms;not null;default:0;comment:投放结束时间，UTC epoch ms" json:"endsAtMs"`
	CreatedAtMS       int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS       int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppSplashScreen) TableName() string {
	return "admin_app_splash_screens"
}

type AppPopup struct {
	ID                uint   `gorm:"primaryKey" json:"id"`
	AppCode           string `gorm:"size:32;not null;default:lalu;index:idx_admin_app_popups_app_sort;uniqueIndex:uk_admin_app_popups_code" json:"appCode"`
	Code              string `gorm:"size:80;not null;uniqueIndex:uk_admin_app_popups_code;comment:弹窗编码" json:"code"`
	Name              string `gorm:"size:80;not null;comment:弹窗名称" json:"name"`
	ImageURL          string `gorm:"column:image_url;size:1024;not null;default:'';comment:弹窗图片 URL，可为空" json:"imageUrl"`
	JumpType          string `gorm:"size:16;not null;comment:跳转类型，h5 或 app" json:"jumpType"`
	JumpURL           string `gorm:"column:jump_url;size:2048;not null;default:'';comment:跳转地址" json:"jumpUrl"`
	DisplayPeriodDays int    `gorm:"column:display_period_days;not null;default:0;comment:展示周期天数，0 表示每次打开都展示" json:"displayPeriodDays"`
	Status            string `gorm:"size:24;index:idx_admin_app_popups_app_sort,not null;default:active" json:"status"`
	SortOrder         int    `gorm:"index:idx_admin_app_popups_app_sort,not null;default:0" json:"sortOrder"`
	StartsAtMS        int64  `gorm:"column:starts_at_ms;not null;default:0;comment:生效开始时间，UTC epoch ms" json:"startsAtMs"`
	EndsAtMS          int64  `gorm:"column:ends_at_ms;not null;default:0;comment:生效结束时间，UTC epoch ms" json:"endsAtMs"`
	CreatedAtMS       int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS       int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppPopup) TableName() string {
	return "admin_app_popups"
}

type AppVersion struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	AppCode     string `gorm:"size:32;uniqueIndex:uk_admin_app_versions_build,not null;default:lalu" json:"appCode"`
	Platform    string `gorm:"size:24;uniqueIndex:uk_admin_app_versions_build;index:idx_admin_app_versions_latest,not null" json:"platform"`
	Version     string `gorm:"size:40;not null" json:"version"`
	BuildNumber int64  `gorm:"uniqueIndex:uk_admin_app_versions_build;index:idx_admin_app_versions_latest,not null" json:"buildNumber"`
	ForceUpdate bool   `gorm:"not null;default:false" json:"forceUpdate"`
	DownloadURL string `gorm:"size:2048;not null" json:"downloadUrl"`
	Description string `gorm:"type:text" json:"description"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppVersion) TableName() string {
	return "admin_app_versions"
}

type AppExploreTab struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	AppCode     string `gorm:"size:32;uniqueIndex:uk_admin_app_explore_tabs_tab;index:idx_admin_app_explore_tabs_app_sort,not null;default:lalu" json:"appCode"`
	Tab         string `gorm:"size:80;uniqueIndex:uk_admin_app_explore_tabs_tab,not null" json:"tab"`
	H5URL       string `gorm:"column:h5_url;size:2048;not null" json:"h5Url"`
	Enabled     bool   `gorm:"index:idx_admin_app_explore_tabs_app_sort,not null;default:true" json:"enabled"`
	SortOrder   int    `gorm:"index:idx_admin_app_explore_tabs_app_sort,not null;default:0" json:"sortOrder"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AppExploreTab) TableName() string {
	return "admin_app_explore_tabs"
}

type HostAgencySalaryPolicy struct {
	ID      uint   `gorm:"primaryKey" json:"id"`
	AppCode string `gorm:"size:32;uniqueIndex:uk_admin_host_agency_salary_policy_name;index:idx_admin_host_agency_salary_policy_region,not null;default:lalu" json:"appCode"`
	Name    string `gorm:"size:120;uniqueIndex:uk_admin_host_agency_salary_policy_name;not null" json:"name"`
	// RegionID 是第一阶段的政策适用边界；结算时按用户所属区域命中唯一 active 政策。
	RegionID int64  `gorm:"uniqueIndex:uk_admin_host_agency_salary_policy_name;index:idx_admin_host_agency_salary_policy_region,not null" json:"regionId"`
	Status   string `gorm:"size:24;index:idx_admin_host_agency_salary_policy_region,not null;default:disabled" json:"status"`
	// SettlementMode 只配置结算节奏，等级金额仍按累计值保存，实际发放由后续结算任务计算差额。
	SettlementMode string `gorm:"size:24;not null;default:daily" json:"settlementMode"`
	// SettlementTriggerMode 区分自动任务与后台人工结算；手动政策发布后仍可被查询，但不会被 cron 自动发薪。
	SettlementTriggerMode string `gorm:"column:settlement_trigger_mode;size:24;not null;default:automatic" json:"settlementTriggerMode"`
	// 比例字段使用 decimal 字符串承载，避免金币、钻石、美元换算出现 float 精度误差。
	GiftCoinToDiamondRatio   string `gorm:"column:gift_coin_to_diamond_ratio;type:decimal(18,6);not null;default:1.000000" json:"giftCoinToDiamondRatio"`
	ResidualDiamondToUSDRate string `gorm:"column:residual_diamond_to_usd_rate;type:decimal(24,12);not null;default:0.000000000000" json:"residualDiamondToUsdRate"`
	// 时间范围采用 epoch ms 半开区间，EffectiveToMS=0 表示长期有效。
	EffectiveFromMS  int64  `gorm:"column:effective_from_ms;index:idx_admin_host_agency_salary_policy_region,not null;default:0" json:"effectiveFromMs"`
	EffectiveToMS    int64  `gorm:"column:effective_to_ms;not null;default:0" json:"effectiveToMs"`
	Description      string `gorm:"size:255;not null;default:''" json:"description"`
	CreatedByAdminID uint   `gorm:"column:created_by_admin_id;not null;default:0" json:"createdByAdminId"`
	UpdatedByAdminID uint   `gorm:"column:updated_by_admin_id;not null;default:0" json:"updatedByAdminId"`
	// 发布字段只记录 admin 配置同步到 wallet 运行快照的结果；结算仍只读取 wallet-service 自己的运行表。
	PublishStatus      string                  `gorm:"column:publish_status;size:24;not null;default:draft" json:"publishStatus"`
	PublishError       string                  `gorm:"column:publish_error;size:255;not null;default:''" json:"publishError"`
	PublishedAtMS      int64                   `gorm:"column:published_at_ms;not null;default:0" json:"publishedAtMs"`
	PublishedByAdminID uint                    `gorm:"column:published_by_admin_id;not null;default:0" json:"publishedByAdminId"`
	CreatedAtMS        int64                   `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS        int64                   `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
	Levels             []HostAgencySalaryLevel `gorm:"foreignKey:PolicyID" json:"levels"`
}

func (HostAgencySalaryPolicy) TableName() string {
	return "admin_host_agency_salary_policies"
}

type HostAgencySalaryLevel struct {
	ID       uint `gorm:"primaryKey" json:"id"`
	PolicyID uint `gorm:"uniqueIndex:uk_admin_host_agency_salary_level;index:idx_admin_host_agency_salary_level_policy,not null" json:"policyId"`
	// LevelNo 是累计工资差额结算的顺序锚点，必须在同一 policy 下唯一。
	LevelNo int32 `gorm:"column:level_no;uniqueIndex:uk_admin_host_agency_salary_level;not null" json:"level"`
	// RequiredDiamonds 保存主播当月钻石门槛，月底清空逻辑不在 admin-server 第一阶段执行。
	RequiredDiamonds int64 `gorm:"column:required_diamonds;index:idx_admin_host_agency_salary_level_policy,not null" json:"requiredDiamonds"`
	// 三个权益字段保存“达到该等级后的累计值”，结算任务只发本次等级与已结算等级之间的差额。
	HostSalaryUSD   string `gorm:"column:host_salary_usd;type:decimal(12,2);not null;default:0.00" json:"hostSalaryUsd"`
	HostCoinReward  int64  `gorm:"column:host_coin_reward;not null;default:0" json:"hostCoinReward"`
	AgencySalaryUSD string `gorm:"column:agency_salary_usd;type:decimal(12,2);not null;default:0.00" json:"agencySalaryUsd"`
	Status          string `gorm:"size:24;not null;default:active" json:"status"`
	SortOrder       int32  `gorm:"column:sort_order;not null;default:0" json:"sortOrder"`
	CreatedAtMS     int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS     int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (HostAgencySalaryLevel) TableName() string {
	return "admin_host_agency_salary_policy_levels"
}

type TeamSalaryPolicy struct {
	ID      uint   `gorm:"primaryKey" json:"id"`
	AppCode string `gorm:"size:32;uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null;default:lalu" json:"appCode"`
	// PolicyType 当前只允许 bd/admin；拆表会让两类策略后续结算扩展变重，所以用类型字段保持同一套配置 API。
	PolicyType string `gorm:"column:policy_type;size:24;uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null" json:"policyType"`
	Name       string `gorm:"size:120;uniqueIndex:uk_admin_team_salary_policy_name;not null" json:"name"`
	// RegionID 沿用 Host 政策的区域边界，保证同一区域组织链路可以命中同一套工资配置。
	RegionID int64  `gorm:"uniqueIndex:uk_admin_team_salary_policy_name;index:idx_admin_team_salary_policy_scope,not null" json:"regionId"`
	Status   string `gorm:"size:24;index:idx_admin_team_salary_policy_scope,not null;default:disabled" json:"status"`
	// SettlementTriggerMode 决定次月 5 日窗口由自动任务处理还是进入后台人工批量结算池。
	SettlementTriggerMode string `gorm:"column:settlement_trigger_mode;size:24;not null;default:automatic" json:"settlementTriggerMode"`
	// BD/Admin 都按完整自然月统计，结算日期固定为次月 5 日；这里不再提供日结/半月结节奏字段。
	EffectiveFromMS  int64             `gorm:"column:effective_from_ms;index:idx_admin_team_salary_policy_scope,not null;default:0" json:"effectiveFromMs"`
	EffectiveToMS    int64             `gorm:"column:effective_to_ms;not null;default:0" json:"effectiveToMs"`
	Description      string            `gorm:"size:255;not null;default:''" json:"description"`
	CreatedByAdminID uint              `gorm:"column:created_by_admin_id;not null;default:0" json:"createdByAdminId"`
	UpdatedByAdminID uint              `gorm:"column:updated_by_admin_id;not null;default:0" json:"updatedByAdminId"`
	CreatedAtMS      int64             `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS      int64             `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
	Levels           []TeamSalaryLevel `gorm:"foreignKey:PolicyID" json:"levels"`
}

func (TeamSalaryPolicy) TableName() string {
	return "admin_team_salary_policies"
}

type TeamSalaryLevel struct {
	ID       uint `gorm:"primaryKey" json:"id"`
	PolicyID uint `gorm:"uniqueIndex:uk_admin_team_salary_level;index:idx_admin_team_salary_level_policy,not null" json:"policyId"`
	// LevelNo 是差额结算锚点，当前等级累计工资减去已结算累计工资就是本次应发金额。
	LevelNo int32 `gorm:"column:level_no;uniqueIndex:uk_admin_team_salary_level;not null" json:"level"`
	// ThresholdUSD 对 BD 表示下属 Agency 管理主播 Host Salary 合计门槛，对 Admin 表示下属 BD Salary 合计门槛。
	ThresholdUSD string `gorm:"column:threshold_usd;type:decimal(12,2);index:idx_admin_team_salary_level_policy,not null;default:0.00" json:"thresholdUsd"`
	// RatePercent 保存运营看到的百分比数字，例如 8 表示 8%，结算时再换算成比例。
	RatePercent string `gorm:"column:rate_percent;type:decimal(9,4);not null;default:0.0000" json:"ratePercent"`
	// SalaryUSD 是达到该等级后的累计应得工资，实际入账仍按差额结算。
	SalaryUSD   string `gorm:"column:salary_usd;type:decimal(12,2);not null;default:0.00" json:"salaryUsd"`
	Status      string `gorm:"size:24;not null;default:active" json:"status"`
	SortOrder   int32  `gorm:"column:sort_order;not null;default:0" json:"sortOrder"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (TeamSalaryLevel) TableName() string {
	return "admin_team_salary_policy_levels"
}

type RefreshToken struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	UserID      uint   `gorm:"index;not null" json:"userId"`
	TokenHash   string `gorm:"size:128;uniqueIndex;not null" json:"-"`
	UserAgent   string `gorm:"size:255" json:"userAgent"`
	IP          string `gorm:"size:64" json:"ip"`
	ExpiresAtMS int64  `gorm:"column:expires_at_ms;index;not null" json:"expiresAtMs"`
	RevokedAtMS *int64 `gorm:"column:revoked_at_ms" json:"revokedAtMs"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (RefreshToken) TableName() string {
	return "admin_refresh_tokens"
}

type LoginLog struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	Username    string `gorm:"size:64;index" json:"username"`
	UserID      *uint  `gorm:"index" json:"userId"`
	IP          string `gorm:"size:64" json:"ip"`
	UserAgent   string `gorm:"size:255" json:"userAgent"`
	Status      string `gorm:"size:32;index;not null" json:"status"`
	Message     string `gorm:"size:255" json:"message"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
}

func (LoginLog) TableName() string {
	return "admin_login_logs"
}

type OperationLog struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	RequestID   string `gorm:"size:64;index;not null;default:''" json:"requestId"`
	UserID      uint   `gorm:"index;not null" json:"userId"`
	Username    string `gorm:"size:64;index;not null" json:"username"`
	Action      string `gorm:"size:80;index;not null" json:"action"`
	Resource    string `gorm:"size:120;index" json:"resource"`
	ResourceID  string `gorm:"size:80;index;not null;default:''" json:"resourceId"`
	Method      string `gorm:"size:12" json:"method"`
	Path        string `gorm:"size:180" json:"path"`
	IP          string `gorm:"size:64" json:"ip"`
	UserAgent   string `gorm:"size:255;not null;default:''" json:"userAgent"`
	Status      string `gorm:"size:32;index;not null" json:"status"`
	HTTPStatus  int    `gorm:"not null;default:0" json:"httpStatus"`
	RiskLevel   string `gorm:"size:24;index;not null;default:normal" json:"riskLevel"`
	LatencyMS   int64  `gorm:"not null;default:0" json:"latencyMs"`
	Detail      string `gorm:"type:text" json:"detail"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
}

func (OperationLog) TableName() string {
	return "admin_operation_logs"
}

type DataScope struct {
	ID          uint   `gorm:"primaryKey" json:"id"`
	RoleID      uint   `gorm:"index;not null" json:"roleId"`
	ScopeType   string `gorm:"size:40;index;not null" json:"scopeType"`
	ScopeValue  string `gorm:"size:120;index;not null" json:"scopeValue"`
	CreatedAtMS int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (DataScope) TableName() string {
	return "admin_data_scopes"
}

type AdminJob struct {
	ID            uint   `gorm:"primaryKey" json:"id"`
	Type          string `gorm:"size:80;index;not null" json:"type"`
	Status        string `gorm:"size:32;index;not null" json:"status"`
	PayloadJSON   string `gorm:"type:text" json:"payload"`
	ResultJSON    string `gorm:"type:text" json:"result"`
	Error         string `gorm:"type:text" json:"error"`
	Attempt       int    `gorm:"not null;default:0" json:"attempt"`
	MaxAttempts   int    `gorm:"not null;default:3" json:"maxAttempts"`
	LockedBy      string `gorm:"size:120;index;not null;default:''" json:"lockedBy"`
	LockedUntilMS *int64 `gorm:"column:locked_until_ms;index" json:"lockedUntilMs"`
	ArtifactPath  string `gorm:"size:255;not null;default:''" json:"artifactPath"`
	CreatedBy     uint   `gorm:"index;not null" json:"createdBy"`
	CreatedByName string `gorm:"size:64;index;not null" json:"createdByName"`
	StartedAtMS   *int64 `gorm:"column:started_at_ms" json:"startedAtMs"`
	FinishedAtMS  *int64 `gorm:"column:finished_at_ms" json:"finishedAtMs"`
	CreatedAtMS   int64  `gorm:"column:created_at_ms;autoCreateTime:milli" json:"createdAtMs"`
	UpdatedAtMS   int64  `gorm:"column:updated_at_ms;autoUpdateTime:milli" json:"updatedAtMs"`
}

func (AdminJob) TableName() string {
	return "admin_jobs"
}
