Documentation
¶
Index ¶
- Constants
- func EnvFromTags(tags []string) string
- func MatchEnv(tags []string, env string) bool
- func MatchTag(tags []string, tag string) bool
- func NormalizeTags(tags []string) []string
- func ParseTags(raw string) []string
- func ValidArtifactStorageChannelType(t ArtifactStorageChannelType) bool
- func ValidAssetType(t AssetType) bool
- func ValidBackupStorageType(t BackupStorageType) bool
- func ValidChannelID(s string) bool
- func ValidInstanceRole(r InstanceRole) bool
- func ValidMetricScope(s MetricScope) bool
- type AgentCallLog
- type AgentToken
- type AgentTransferTicket
- type AlertChannel
- type AlertEvent
- type AlertRule
- type ArtifactMigration
- type ArtifactMigrationFailure
- type ArtifactPackage
- type ArtifactReconcileDiff
- type ArtifactReconcileRun
- type ArtifactReconcileSetting
- type ArtifactSource
- type ArtifactStorageChannel
- type ArtifactStorageChannelType
- type ArtifactVersion
- type Asset
- type AssetStorageState
- type AssetType
- type AuditLog
- type AuthSetupLock
- type Backup
- type BackupMode
- type BackupStatus
- type BackupStorage
- type BackupStorageType
- type BackupType
- type BanRecord
- type BanScope
- type Bot
- type BotDesiredState
- type BotLoadActionResult
- type BotLoadActionResultStatus
- type BotLoadBatch
- type BotLoadBatchState
- type BotLoadCommandCheckpoint
- type BotLoadCommandCheckpointStatus
- type BotLoadMetricSample
- type BotLoadRunEvent
- type BotLoadRunEventType
- type BotLoadRunState
- type BotLoadTemplate
- type BotLoadVerdict
- type BotStatus
- type BotStressSession
- type BotStressSessionStatus
- type BusinessEvent
- type ClientChannel
- type ClientDistDaily
- type ClientDistEvent
- type ClientDistSnapshot
- type ClientIPRule
- type ClientMachine
- type ClientProtectionAction
- type ClientPullKey
- type ClientRuntimeState
- type ClientSecurityCounter
- type ClientSecurityGroup
- type ClientSecurityHello
- type ClientSecurityProfile
- type ClientSecurityRiskEvent
- type ClientTelemetry
- type ClientTelemetryDaily
- type ClientVersion
- type EconomyBalanceMirror
- type EconomyLedgerEntry
- type FileVersion
- type Group
- type GroupInstance
- type GroupMember
- type GroupMemberRole
- type GroupQuota
- type Instance
- type InstanceConfigVersion
- type InstanceCrashSnapshot
- type InstanceGroupMember
- type InstanceGroupNode
- type InstanceRole
- type InstanceStatus
- type InstanceType
- type LogEntry
- type LogLevel
- type LogSource
- type MetricRollup1h
- type MetricRollup5m
- type MetricSampleRaw
- type MetricScope
- type MetricSeries
- type Network
- type NetworkMember
- type Node
- type NodeEnrollToken
- type NodeJDK
- type NodePMConfig
- type NodeRuntime
- type NodeStatus
- type Notification
- type NotificationLevel
- type OrphanRuntime
- type OrphanRuntimeStatus
- type PMRegistry
- type PlatformSetting
- type ProcessMetricSnapshot
- type ProcessType
- type Schedule
- type ScheduleExecutionLog
- type ScheduleLogStatus
- type SelfUpdateCheckCache
- type ServerRegistration
- type Task
- type TaskLog
- type TaskState
- type Template
- type User
- type UserInvitation
- type UserRole
- type UserStatus
Constants ¶
const ( AlertLevelInfo = "info" AlertLevelWarn = "warn" AlertLevelCritical = "critical" )
告警级别(FR-085)。按严重度递增,用于路由与展示着色。
const ( // AlertTriggerMetric 指标阈值(节点 cpu/memory/disk,FR-011 原型)。 AlertTriggerMetric = "metric" // AlertTriggerInstanceCrash 实例崩溃(state_change → CRASHED)。 AlertTriggerInstanceCrash = "instance_crash" // AlertTriggerNodeOffline 节点离线(心跳超时被标记 offline)。 AlertTriggerNodeOffline = "node_offline" // AlertTriggerLogKeyword 日志关键字(实例 stdout/stderr 命中关键字)。 AlertTriggerLogKeyword = "log_keyword" // AlertTriggerPlayerEvent 玩家事件(接 FR-066 PlayerEventService)。 AlertTriggerPlayerEvent = "player_event" // AlertTriggerBackupFailed 备份失败。 AlertTriggerBackupFailed = "backup_failed" )
告警触发类型(FR-085)。在 FR-011 的指标阈值之外扩展为多触发源。
const ( ChannelTypeWebhook = "webhook" ChannelTypeEmail = "email" ChannelTypeDingtalk = "dingtalk" ChannelTypeWecom = "wecom" ChannelTypeFeishu = "feishu" ChannelTypeDiscord = "discord" ChannelTypeTelegram = "telegram" ChannelTypeInApp = "inapp" )
通知通道类型(FR-085)。在通用 webhook 之外扩展主流 IM / 邮件 / 站内。
const ( // ArtifactReconcileRunning 对账进行中(异步执行,前端轮询)。 ArtifactReconcileRunning = "running" // ArtifactReconcileSucceeded 对账完成,差异明细已落库。 ArtifactReconcileSucceeded = "succeeded" // ArtifactReconcileFailed 对账失败(存储遍历报错 / CP 重启中断),ErrorMessage 带原因。 ArtifactReconcileFailed = "failed" )
对账运行状态(FR-349,见 spec artifact-s3-reconcile §3.2)。
const ( // ArtifactReconcileTriggerManual 面板手动触发。 ArtifactReconcileTriggerManual = "manual" // ArtifactReconcileTriggerScheduled 定期任务触发。 ArtifactReconcileTriggerScheduled = "scheduled" )
对账触发方式。
const ( // ArtifactDiffMissing 缺失:索引有、S3 无——下载必 404 的高危项。 ArtifactDiffMissing = "missing" // ArtifactDiffOrphan 孤儿:S3 有、索引无——白占存储。 ArtifactDiffOrphan = "orphan" )
差异类别。
const ( // ArtifactDiffOpen 待处置。 ArtifactDiffOpen = "open" // ArtifactDiffResolved 已处置(ResolvedAction 记方式)。 ArtifactDiffResolved = "resolved" )
差异处置状态。
const ( // ArtifactDiffActionMarkedLost 缺失 → 资产已标记失效(StorageState=lost)。 ArtifactDiffActionMarkedLost = "marked_lost" // ArtifactDiffActionCleaned 孤儿 → S3 对象已清理删除。 ArtifactDiffActionCleaned = "cleaned" // ArtifactDiffActionStale 差异已过时(run 后资产被删/迁移、或同键对象已被新上传合法引用), // 处置时守卫命中,不动资产也不删对象(FR-349 处置安全性,见 spec §3.5)。 ArtifactDiffActionStale = "stale" )
差异处置方式。
const ( // ServerProbePackageKey 是 ServerProbe 制品包的稳定机器键(FR-409)。 ServerProbePackageKey = "serverprobe" // ArtifactProviderGitHubRelease 是 GitHub Releases 来源 provider。 ArtifactProviderGitHubRelease = "github-release" // ArtifactProviderLocalUpload 是平台管理员上传到 CP 制品库的来源 provider。 ArtifactProviderLocalUpload = "local-upload" )
const ( MetricNodeCPUPct = "node_cpu_pct" MetricNodeMemUsed = "node_mem_used" MetricNodeMemTotal = "node_mem_total" MetricNodeDiskUsed = "node_disk_used" MetricNodeDiskTotal = "node_disk_total" MetricNodeNetRxRate = "node_net_rx_rate" MetricNodeNetTxRate = "node_net_tx_rate" MetricNodeLoad = "node_load" // 1 分钟 load average(FR-062) // FR-401:由 FR-400 已认证 Heartbeat 当前快照沉淀的共享 Bot Worker 运行时指标。 // 它们属于节点维度,不代表任一 Bot 或压测会话独占的资源。 MetricWorkerProcessRSSBytes = "worker_process_rss_bytes" MetricWorkerProcessCPUPct = "worker_process_cpu_pct" MetricBotWorkerRSSBytes = "bot_worker_rss_bytes" MetricBotWorkerCPUPct = "bot_worker_cpu_pct" MetricBotActiveCount = "bot_active_count" MetricBotConnectingCount = "bot_connecting_count" MetricBotCapacityMax = "bot_capacity_max" MetricBotEventLoopP95MS = "bot_event_loop_p95_ms" MetricInstTPS = "inst_tps" MetricInstMSPT = "inst_mspt" MetricInstPlayersOnline = "inst_players_online" MetricInstHeapUsed = "inst_heap_used" MetricInstHeapMax = "inst_heap_max" MetricInstThreads = "inst_threads" MetricInstCPUPct = "inst_cpu_pct" MetricInstUptime = "inst_uptime" MetricWorldLoadedChunks = "world_loaded_chunks" MetricWorldEntities = "world_entities" MetricWorldTileEntities = "world_tile_entities" )
指标键(metric_key)。完整语义见 docs/specs/timeseries-metrics/api.md。
const ( // TaskKindJDKInstall JDK 一键下载安装任务(FR-183 首批载体,见 ADR-040)。 TaskKindJDKInstall = "jdk_install" // TaskKindPkgInstall 全局包安装/升级任务(FR-307)。 TaskKindPkgInstall = "pkg_install" // TaskKindRuntimeInstall 非 JDK 运行时一键下载安装任务(FR-299,首批 Node.js)。 // 复用 jdk_install 的异步任务模式;终态副作用落 model.NodeRuntime。 TaskKindRuntimeInstall = "runtime_install" // TaskKindProvision 一键搭建后端子服任务(FR-319):与其它 kind 不同,执行体在 CP 后台 // goroutine(下载在 worker、编排在 CP),进度/终态由 CP 直写而非 worker 心跳快照。 TaskKindProvision = "provision" // TaskKindImport 导入现有服务器(migrate 搬迁)任务(FR-323,CP 后台 goroutine)。 TaskKindImport = "import" // TaskKindClone 克隆实例(拷贝工作目录)任务(FR-323,CP 后台 goroutine)。 TaskKindClone = "clone" // TaskKindBackupCreate 备份创建(打包工作目录)任务(FR-323,CP 后台 goroutine)。 TaskKindBackupCreate = "backup_create" // TaskKindBackupRestore 备份恢复(回放备份链)任务(FR-323,CP 后台 goroutine)。 TaskKindBackupRestore = "backup_restore" // TaskKindArtifactMigrate 制品存量迁移任务(FR-348,CP 后台 goroutine): // 逐制品搬运到目标存储渠道(先改记录再删源),全程一次仅允许一个在途。 TaskKindArtifactMigrate = "artifact_migrate" )
任务种类常量(kind)。新增长任务类型时在此登记。
const AssetBackendLocal = "local"
AssetBackendLocal 本地存储后端标识(默认)。
const AssetBackendS3 = "s3"
AssetBackendS3 S3 兼容对象存储后端标识(FR-347,见 ADR-073)。
const EnvTagPrefix = "env:"
EnvTagPrefix 是「环境维度」复用 Tags 字段的约定前缀(FR-047)。 不新增独立字段/迁移:环境用 `env:dev` / `env:test` / `env:prod` 形式的标签表达, 一个实例至多取首个 env 标签作为其环境,其余 env 标签忽略(避免歧义)。
const SelfUpdateCheckCacheID = 1
SelfUpdateCheckCacheID 是单行缓存的固定主键。
Variables ¶
This section is empty.
Functions ¶
func EnvFromTags ¶
EnvFromTags 返回实例的环境维度值(去掉 `env:` 前缀后的部分),取首个 env 标签。 无 env 标签时返回空串,表示「未分环境」。
func MatchTag ¶
MatchTag 判断实例标签集合是否精确包含指定标签。 tag 传空串表示不按标签过滤(恒为真)。用于「按任意标签筛选」, 区别于环境维度(环境只认 env: 前缀的首个值)。
func NormalizeTags ¶
NormalizeTags 规范化标签集合:去首尾空白、丢弃空项、去重并保持首次出现顺序。 大小写敏感(与 Network 群组名一致),不做小写折叠。
func ParseTags ¶
ParseTags 把实例持久化的 Tags(JSON 字符串数组)解析为规范化切片。 兼容空串/非法 JSON:返回空切片而非报错,避免历史脏数据阻断列表查询。 规范化:去首尾空白、丢弃空项、去重保序——与下方 NormalizeTags 行为一致, 保证「读出来再写回去」幂等。
func ValidArtifactStorageChannelType ¶ added in v0.18.0
func ValidArtifactStorageChannelType(t ArtifactStorageChannelType) bool
ValidArtifactStorageChannelType 校验渠道类型是否在允许枚举内。
func ValidBackupStorageType ¶
func ValidBackupStorageType(t BackupStorageType) bool
ValidBackupStorageType 校验后端类型是否在允许枚举内(local 仅用于占位,不作为远程后端创建)。
func ValidChannelID ¶
ValidChannelID 校验频道 slug 合法性:仅小写字母/数字/连字符,首字符为字母或数字,长度 2-64。
func ValidInstanceRole ¶
func ValidInstanceRole(r InstanceRole) bool
ValidInstanceRole 校验角色是否在允许枚举内。
func ValidMetricScope ¶
func ValidMetricScope(s MetricScope) bool
ValidMetricScope 校验 scope 是否在允许枚举内。
Types ¶
type AgentCallLog ¶ added in v0.20.0
type AgentCallLog struct {
ID uint `gorm:"primaryKey" json:"id"`
// TokenID 鉴权成功后的 agent token 主键。
TokenID uint `gorm:"not null;index:idx_agent_call_token_created,priority:1;index" json:"tokenId"`
// TokenName 冗余快照(吊销后仍可读)。
TokenName string `gorm:"type:varchar(128);not null" json:"tokenName"`
// Action 与 service.AgentAction* 或 MCP 事件对齐(如 agent.whoami)。
Action string `gorm:"type:varchar(64);not null;index:idx_agent_call_action_created,priority:1" json:"action"`
// Capability 本次授权实际使用的能力标签(V2 capability 或 V1 legacy.*);会话事件可空。
Capability string `gorm:"type:varchar(64)" json:"capability,omitempty"`
// Client 调用方:mcp | jmagent | curl | unknown(优先 X-JM-Agent-Client)。
Client string `gorm:"type:varchar(32);not null;default:unknown" json:"client"`
// Transport 可选:streamable_http | sse | http | 空。
Transport string `gorm:"type:varchar(32)" json:"transport,omitempty"`
// TargetType 目标类型(instance/node 等,可空)。
TargetType string `gorm:"type:varchar(32)" json:"targetType,omitempty"`
// TargetID 目标 ID 字符串(可空)。
TargetID string `gorm:"type:varchar(64)" json:"targetId,omitempty"`
// Success 是否成功(策略 403 记 false;业务失败亦 false)。
Success bool `json:"success"`
// Error 失败时截断短文(禁 Token 明文)。
Error string `gorm:"type:varchar(512)" json:"error,omitempty"`
// LatencyMs 处理耗时毫秒。
LatencyMs uint `json:"latencyMs"`
// IP 客户端 IP。
IP string `gorm:"type:varchar(64)" json:"ip"`
// CreatedAt 写入时间;复合索引供按 token/时间、action/时间查询。
CreatedAt time.Time `gorm:"index:idx_agent_call_token_created,priority:2;index:idx_agent_call_action_created,priority:2;index" json:"createdAt"`
}
AgentCallLog Agent 调用流水(FR-390 / FR-395,见 ADR-076/080)。 覆盖 /api/v1/agent/* Ops 读+写与 MCP tool;与人类 audit 表独立。 token_name 为签发时名称快照,吊销后仍可读;error 截断短文,禁 Token 明文。
type AgentToken ¶ added in v0.20.0
type AgentToken struct {
ID uint `gorm:"primaryKey" json:"id"`
// Name 运营可见名称。
Name string `gorm:"type:varchar(128);not null" json:"name"`
// TokenHash 明文的 SHA-256 十六进制小写。库内不存明文。
TokenHash string `gorm:"column:token_hash;type:char(64);uniqueIndex;not null" json:"-"`
// TokenPrefix 明文前缀(如 jmat_ab12),仅供列表识别。
TokenPrefix string `gorm:"column:token_prefix;type:varchar(16);not null" json:"tokenPrefix"`
// ScopedInstanceIDs 可访问实例 ID 列表(JSON 数组)。空表示「未授权任何实例读/写」——默认从严。
ScopedInstanceIDs string `gorm:"column:scoped_instance_ids;type:text" json:"scopedInstanceIds"`
// ScopedNodeIDs 可访问节点 ID 列表(JSON 数组)。空表示未授权任何节点。
ScopedNodeIDs string `gorm:"column:scoped_node_ids;type:text" json:"scopedNodeIds"`
// WriteAllowlist 写操作白名单(JSON 字符串数组),如 ["instance.life","node.maintenance"]。
// 仅 V1 策略使用;V2 保持空并改用 Capabilities。
WriteAllowlist string `gorm:"column:write_allowlist;type:text" json:"writeAllowlist"`
// PolicyVersion 策略版本:1=V1 写白名单;2=V2 capability。既有记录默认 1。
PolicyVersion int `gorm:"column:policy_version;not null;default:1" json:"policyVersion"`
// Capabilities V2 能力分组(JSON 字符串数组)。仅 policy_version=2 使用。
Capabilities string `gorm:"column:capabilities;type:text" json:"capabilities,omitempty"`
// ExpiresAt 过期时间;到期即校验失败。
ExpiresAt time.Time `gorm:"not null;index" json:"expiresAt"`
// Revoked 吊销标记;true 即立即失效。
Revoked bool `gorm:"default:false;not null;index" json:"revoked"`
// LastUsedAt 最近一次成功鉴权时间(可选更新)。
LastUsedAt *time.Time `json:"lastUsedAt"`
CreatedAt time.Time `json:"createdAt"`
// CreatedBy 签发该 token 的平台管理员用户 ID。
CreatedBy uint `json:"createdBy"`
}
AgentToken Agent 专用令牌(FR-384 / FR-395,见 ADR-076/080)。 落库只存 SHA-256 哈希;明文仅签发时一次性返回,不可二次读取。 与人类 JWT 分离:scope(实例/节点白名单)+ V1 write_allowlist / V2 capabilities 约束 agent 能力面。
type AgentTransferTicket ¶ added in v0.21.0
type AgentTransferTicket struct {
Digest string `gorm:"primaryKey;type:char(64)"`
ExpiresAt time.Time `gorm:"not null;index"`
ConsumedAt *time.Time `gorm:"index"`
CreatedAt time.Time
}
AgentTransferTicket 保存传输票据的摘要与消费状态,确保重启及多进程部署下仍保持一次性语义。
type AlertChannel ¶
type AlertChannel struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
Type string `gorm:"type:varchar(32);not null" json:"type"`
Enabled bool `gorm:"default:true" json:"enabled"`
// Config 通道连接配置的 JSON 串。各类型字段不同(见 service/channel_notifier.go ChannelConfig):
// webhook/dingtalk/wecom/feishu/discord: {"url":"${ENV}"}(URL 含 access_token/secret,强制 ${ENV} 引用)
// telegram: {"token":"${ENV}","chatId":"..."}
// email: {"host","port","username","password":"${ENV}","from","to"}
// inapp: {}(无外部配置)
// 凭证子字段(URL/token/password)强制经 ${ENV_VAR} 引用,CreateChannel/UpdateChannel 时校验、发送时解析。
Config string `gorm:"type:text" json:"config"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
AlertChannel 通知通道(FR-085)。一个通道是一个可复用的通知出口, 多条规则可路由到同一通道。敏感凭证字段(webhook 地址含 secret、SMTP 密码、bot token) 必须以 ${ENV_VAR} 形式引用环境变量,不得硬编码明文(见 .claude/rules/config-files.md)。
func (*AlertChannel) BeforeCreate ¶
func (c *AlertChannel) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成 UUID。
type AlertEvent ¶
type AlertEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
RuleID uint `gorm:"not null;index" json:"ruleId"`
TargetID uint `json:"targetId"`
// Level/TriggerType 冗余快照规则当时的级别与类型,便于历史筛选(规则可能被改/删)。
Level string `gorm:"type:varchar(16);default:warn" json:"level"`
TriggerType string `gorm:"type:varchar(32);default:metric" json:"triggerType"`
// DedupKey 去抖键(rule + target + 触发标识)。聚合窗口内复发更新同一活跃事件而非新建。
DedupKey string `gorm:"type:varchar(256);index" json:"-"`
Value float64 `json:"value"`
Message string `gorm:"type:varchar(512)" json:"message"`
// Count 聚合计数:去抖窗口内该告警被触发的次数(≥1)。
Count int `gorm:"default:1" json:"count"`
Resolved bool `gorm:"default:false" json:"resolved"`
FiredAt time.Time `json:"firedAt"`
// LastFiredAt 最近一次复发时间(聚合时更新)。
LastFiredAt *time.Time `json:"lastFiredAt"`
ResolvedAt *time.Time `json:"resolvedAt"`
// ── 确认 / 已读(FR-085)──
Acknowledged bool `gorm:"default:false" json:"acknowledged"`
AcknowledgedBy *uint `json:"acknowledgedBy"`
AcknowledgedAt *time.Time `json:"acknowledgedAt"`
// Read 站内已读状态(仅影响未读角标,不影响确认)。
Read bool `gorm:"default:false" json:"read"`
Rule AlertRule `gorm:"foreignKey:RuleID" json:"rule,omitempty"`
}
AlertEvent 告警事件(FR-011 + FR-085 扩展)。
type AlertRule ¶
type AlertRule struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
// TriggerType 触发类型(FR-085):metric|instance_crash|node_offline|log_keyword|player_event|backup_failed。
// 为兼容 FR-011 存量规则,空值按 metric 处理。
TriggerType string `gorm:"type:varchar(32);default:metric" json:"triggerType"`
// Level 告警级别(FR-085):info|warn|critical。空值按 warn 处理。
Level string `gorm:"type:varchar(16);default:warn" json:"level"`
TargetType string `gorm:"type:varchar(32);not null" json:"targetType"` // node, instance
TargetID *uint `json:"targetId"` // nil 表示全局
// ── metric 触发专用(FR-011)──
Metric string `gorm:"type:varchar(64)" json:"metric"` // cpu, memory, disk
Operator string `gorm:"type:varchar(4)" json:"operator"` // >, <, >=, <=, ==
Threshold float64 `json:"threshold"`
DurationSec int `gorm:"default:0" json:"durationSec"`
// ── 非指标触发专用(FR-085)──
// Keyword 日志关键字触发的匹配子串(log_keyword)。
Keyword string `gorm:"type:varchar(256)" json:"keyword"`
// EventMatch 玩家事件触发的子类型(player_event):join|quit|chat|cross_server,空=任意。
EventMatch string `gorm:"type:varchar(64)" json:"eventMatch"`
// ── 聚合 / 静默 / 路由(FR-085)──
// ChannelIDs 路由目标通道 ID 列表的 JSON 串(如 "[1,2]")。空=不发外部通知(仍入事件库 + 站内)。
ChannelIDs string `gorm:"type:varchar(256)" json:"channelIds"`
// DedupWindowSec 去抖聚合窗口(秒)。同一告警键在窗口内重复触发只通知一次、累计计数。0=不去抖。
DedupWindowSec int `gorm:"default:0" json:"dedupWindowSec"`
// SilenceStart/SilenceEnd 静默窗口("HH:MM" 24h,本地时区)。落在窗口内触发的告警不发外部通知(仍入库)。
// 支持跨午夜(start > end,如 23:00→07:00)。两者皆空=不静默。
SilenceStart string `gorm:"type:varchar(8)" json:"silenceStart"`
SilenceEnd string `gorm:"type:varchar(8)" json:"silenceEnd"`
// NotifyRecover 恢复时是否发送恢复通知(仅对可恢复的触发类型:metric/instance_crash/node_offline)。
NotifyRecover bool `json:"notifyRecover"`
// NotifyType/NotifyTarget 兼容 FR-011 的单 webhook 直发(未配置 ChannelIDs 时回退)。
NotifyType string `gorm:"type:varchar(32)" json:"notifyType"`
NotifyTarget string `gorm:"type:varchar(512)" json:"-"`
Enabled bool `gorm:"default:true" json:"enabled"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
AlertRule 告警规则(FR-011 + FR-085 扩展)。
type ArtifactMigration ¶ added in v0.18.0
type ArtifactMigration struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"type:varchar(64);uniqueIndex;not null" json:"taskId"`
// TargetChannelID 目标渠道(重试 = 对同目标重新发起的解析源)。
TargetChannelID uint `gorm:"not null;index" json:"targetChannelId"`
// Total 快照内全部 client-file 存量数。
Total int `gorm:"not null;default:0" json:"total"`
// Migrated 本次任务实际搬运成功数。
Migrated int `gorm:"not null;default:0" json:"migrated"`
// Failed 本次任务失败条数(明细见 ArtifactMigrationFailure)。
Failed int `gorm:"not null;default:0" json:"failed"`
// Skipped 发起时已在目标渠道数(续跑时「上轮已迁」体现于此)。
Skipped int `gorm:"not null;default:0" json:"skipped"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ArtifactMigration 一次制品存量迁移任务的登记与实时计数(FR-348,底座见 ADR-073)。 task_id 1:1 关联 tasks 行(kind=artifact_migrate)。计数独立成行而非塞 Task.Result/Detail: 失败任务无 result、Detail 被阶段文本覆写,独立行保证「总数/已迁/失败/跳过」随迁移逐条 持久推进,前端渠道页可精确展示。
type ArtifactMigrationFailure ¶ added in v0.18.0
type ArtifactMigrationFailure struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"type:varchar(64);not null;index" json:"taskId"`
AssetID uint `json:"assetId"`
// SHA256 制品内容寻址键(定位失败制品)。
SHA256 string `gorm:"type:char(64);not null" json:"sha256"`
Filename string `gorm:"type:varchar(255)" json:"filename"`
Size int64 `json:"size"`
Reason string `gorm:"type:text" json:"reason"`
CreatedAt time.Time `json:"createdAt"`
}
ArtifactMigrationFailure 迁移失败明细(FR-348):逐条落库可查(制品 sha256 + 原因), 按 task_id 隔离(每次任务独立一批);重试 = 重新发起同目标迁移。
type ArtifactPackage ¶ added in v0.21.0
type ArtifactPackage struct {
ID uint `gorm:"primaryKey" json:"id"`
Key string `gorm:"type:varchar(128);not null;uniqueIndex" json:"key"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
AssetType AssetType `gorm:"type:varchar(32);not null" json:"assetType"`
DefaultVersionID uint `gorm:"default:0;index" json:"defaultVersionId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ArtifactPackage 是可版本化的逻辑制品,不保存二进制字节。 实际文件仍由 Asset 的 CAS 负责,旧制品消费者无需迁移。
type ArtifactReconcileDiff ¶ added in v0.18.0
type ArtifactReconcileDiff struct {
ID uint `gorm:"primaryKey" json:"id"`
RunID uint `gorm:"not null;index" json:"runId"`
ChannelID uint `gorm:"not null;index" json:"channelId"`
// Kind missing | orphan。
Kind string `gorm:"type:varchar(16);not null;index" json:"kind"`
// AssetID missing:资产 ID;orphan:0(对象不在索引,无资产可指)。
AssetID uint `json:"assetId"`
// SHA256 missing:资产内容寻址键;orphan 空。
SHA256 string `gorm:"type:char(64)" json:"sha256"`
// ObjectKey CAS 相对键(missing=Asset.RelPath;orphan=剥渠道前缀后的对象键)。
ObjectKey string `gorm:"type:varchar(512);not null" json:"objectKey"`
Size int64 `json:"size"`
// LastModified orphan:S3 对象 Last-Modified;missing nil。
LastModified *time.Time `json:"lastModified"`
// Status open | resolved。
Status string `gorm:"type:varchar(16);not null;default:open" json:"status"`
ResolvedAt *time.Time `json:"resolvedAt"`
// ResolvedAction marked_lost | cleaned | stale。
ResolvedAction string `gorm:"type:varchar(32)" json:"resolvedAction"`
// ResolveError 清理失败原因(保持 open 供重试)。
ResolveError string `gorm:"type:varchar(512)" json:"resolveError"`
CreatedAt time.Time `json:"createdAt"`
}
ArtifactReconcileDiff 差异明细(缺失/孤儿),随 run 落库,处置后翻 resolved(FR-349)。
type ArtifactReconcileRun ¶ added in v0.18.0
type ArtifactReconcileRun struct {
ID uint `gorm:"primaryKey" json:"id"`
ChannelID uint `gorm:"not null;index" json:"channelId"`
// ChannelName 渠道名快照:渠道后续改名/删除不影响历史报告可读。
ChannelName string `gorm:"type:varchar(128)" json:"channelName"`
// Status running | succeeded | failed。
Status string `gorm:"type:varchar(16);not null" json:"status"`
// TriggeredBy manual | scheduled。
TriggeredBy string `gorm:"type:varchar(16);not null" json:"triggeredBy"`
StartedAt time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
// IndexCount 索引侧扫描条数(该渠道 s3 资产数,含已 lost)。
IndexCount int `json:"indexCount"`
// ObjectCount 对象侧扫描条数(渠道 prefix 下 CAS client-file 命名空间内)。
ObjectCount int `json:"objectCount"`
// MatchedCount 两侧一致数(仅计数不落明细)。
MatchedCount int `json:"matchedCount"`
MissingCount int `json:"missingCount"`
OrphanCount int `json:"orphanCount"`
// ErrorMessage failed 时的原因(截断 512)。
ErrorMessage string `gorm:"type:varchar(512)" json:"errorMessage"`
CreatedAt time.Time `json:"createdAt"`
}
ArtifactReconcileRun 一次制品索引 ↔ S3 对象清单的对账运行记录(FR-349)。 逐 s3 渠道对账;local 不对账(本地文件系统由 CAS 自管)。面板查最近 N 次。
type ArtifactReconcileSetting ¶ added in v0.18.0
type ArtifactReconcileSetting struct {
ID uint `gorm:"primaryKey" json:"id"`
// Enabled 定期对账开关,默认开。
Enabled bool `gorm:"not null;default:true" json:"enabled"`
// IntervalHours 周期小时数,默认 24(每日),钳制 [1,720]。
IntervalHours int `gorm:"not null;default:24" json:"intervalHours"`
// NextRunAt 下次定期触发时间;禁用时 nil。首个周期从启用/启动时刻起算(不在启动瞬间扫存储)。
NextRunAt *time.Time `json:"nextRunAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ArtifactReconcileSetting 定期对账设置(单行 id=1,服务 firstOrCreate 兜底;FR-349)。
type ArtifactSource ¶ added in v0.21.0
type ArtifactSource struct {
ID uint `gorm:"primaryKey" json:"id"`
PackageID uint `gorm:"not null;index;uniqueIndex:idx_artifact_sources_package_name" json:"packageId"`
Provider string `gorm:"type:varchar(64);not null;index" json:"provider"`
Name string `gorm:"type:varchar(255);not null;uniqueIndex:idx_artifact_sources_package_name" json:"name"`
Config string `gorm:"type:text;not null" json:"config"`
Enabled bool `gorm:"default:true;not null" json:"enabled"`
LastSyncedAt *time.Time `json:"lastSyncedAt"`
LastError string `gorm:"type:varchar(512)" json:"lastError"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ArtifactSource 是某制品包的版本来源;Config 只保存 provider 的非敏感配置 JSON。
type ArtifactStorageChannel ¶ added in v0.18.0
type ArtifactStorageChannel struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128);not null;uniqueIndex" json:"name"`
Type ArtifactStorageChannelType `gorm:"type:varchar(16);not null" json:"type"`
// Endpoint S3 主机[:端口],容带 scheme(适配器剥离)。
Endpoint string `gorm:"type:varchar(512)" json:"endpoint"`
// Bucket S3 桶名。
Bucket string `gorm:"type:varchar(255)" json:"bucket"`
// Region SigV4 region,缺省 us-east-1。
Region string `gorm:"type:varchar(64)" json:"region"`
// Prefix 对象键前缀;真实对象键 = <Prefix>/<CAS 相对路径>。
Prefix string `gorm:"type:varchar(255)" json:"prefix"`
// AccessKeyEnc/SecretKeyEnc AES-256-GCM 可逆加密密文(base64)。
// json:"-":任何 API 响应不回明文也不回密文,列表以 Has* 布尔示意。
AccessKeyEnc string `gorm:"type:text" json:"-"`
SecretKeyEnc string `gorm:"type:text" json:"-"`
// UseSSL S3 走 https;false 走 http(rustfs/MinIO 内网常态)。
// 不用 gorm default:true,否则 GORM 会把显式 false(零值)覆盖回 true(同 BackupStorage 先例)。
UseSSL bool `json:"useSsl"`
// PresignTTLSeconds 预签名 URL 有效期秒数,默认 600(10 分钟),service 钳制 [60, 3600]。
PresignTTLSeconds int `gorm:"default:600;not null" json:"presignTtlSeconds"`
// Active 活跃渠道标记:写路径唯一路由开关(全表恰一条,service 事务保证)。
Active bool `gorm:"default:false;not null" json:"active"`
// Builtin 内置「本机存储」渠道:不可删、不可编辑,兜底活跃。
Builtin bool `gorm:"default:false;not null" json:"builtin"`
// LastTest* 最近一次已存渠道连通性测试结果;表单临时测试不写入。
LastTestAt *time.Time `json:"lastTestAt,omitempty"`
LastTestOk bool `json:"lastTestOk"`
LastTestMessage string `gorm:"type:varchar(255)" json:"lastTestMessage"`
// HasAccessKey/HasSecretKey 列表标示凭证已配(不回明文/密文),service 填充。
HasAccessKey bool `gorm:"-" json:"hasAccessKey"`
HasSecretKey bool `gorm:"-" json:"hasSecretKey"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ArtifactStorageChannel 制品存储渠道(FR-347,见 ADR-073,修订 ADR-011 存储节)。
与备份域 BackupStorage 独立(消费方不同:备份配置下发 Worker 执行,本渠道由 CP 自身 上传/签名消费)。凭证面板直填、AES-256-GCM 可逆加密落库(复用 FR-192 KeyEncryptor 基建),与备份域的 ${ENV_VAR} 引用形态分道(理由见 ADR-073 决策 4)。
活跃语义:全表恰一条 Active(service 事务保证),仅作用于**新上传**的 client-file 制品落点;存量 Asset 按自身 StorageBackend + StorageChannelID 自述读取。 硬删除(无软删列):被 Asset 引用/内置/活跃的渠道禁删,名称删除即释放。
type ArtifactStorageChannelType ¶ added in v0.18.0
type ArtifactStorageChannelType string
ArtifactStorageChannelType 制品存储渠道类型(FR-347,见 ADR-073)。
const ( // ArtifactStorageLocal 本地数据根 CAS(内置渠道独占,恒可用)。 ArtifactStorageLocal ArtifactStorageChannelType = "local" // ArtifactStorageS3 S3 兼容对象存储(AWS S3 / MinIO / rustfs 等)。 ArtifactStorageS3 ArtifactStorageChannelType = "s3" )
type ArtifactVersion ¶ added in v0.21.0
type ArtifactVersion struct {
ID uint `gorm:"primaryKey" json:"id"`
PackageID uint `gorm:"not null;index" json:"packageId"`
SourceID uint `gorm:"not null;index;uniqueIndex:idx_artifact_versions_source_version" json:"sourceId"`
Version string `gorm:"type:varchar(128);not null;uniqueIndex:idx_artifact_versions_source_version" json:"version"`
ReleaseRef string `gorm:"type:varchar(255);not null" json:"releaseRef"`
AssetName string `gorm:"type:varchar(255);not null" json:"assetName"`
ExpectedSHA256 string `gorm:"type:char(64);not null" json:"expectedSha256"`
SourceURL string `gorm:"type:varchar(1024);not null" json:"sourceUrl"`
AssetID uint `gorm:"default:0;index" json:"assetId"`
CachedAt *time.Time `json:"cachedAt"`
LastError string `gorm:"type:varchar(512)" json:"lastError"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
Asset *Asset `gorm:"foreignKey:AssetID" json:"asset,omitempty"`
}
ArtifactVersion 记录来源的一条语义版本;AssetID 非零才表示字节已通过校验并入 CAS。
type Asset ¶
type Asset struct {
ID uint `gorm:"primaryKey" json:"id"`
Type AssetType `gorm:"type:varchar(32);not null;index;uniqueIndex:idx_assets_type_sha256" json:"type"`
// Name 人类可读名称(如 "paper-1.20.4"),非寻址键。
Name string `gorm:"type:varchar(255);index" json:"name"`
// Version 版本标记(如 "1.20.4-435"),可空。
Version string `gorm:"type:varchar(128)" json:"version"`
// Filename 入库时的原始文件名,决定存储扩展名与下载名。
Filename string `gorm:"type:varchar(255)" json:"filename"`
// SHA256 内容寻址 + 去重键(十六进制小写)。
SHA256 string `gorm:"type:char(64);not null;index;uniqueIndex:idx_assets_type_sha256" json:"sha256"`
// MD5 辅助完整性校验(十六进制小写)。
MD5 string `gorm:"type:char(32)" json:"md5"`
// Size 字节数。
Size int64 `gorm:"not null" json:"size"`
// ContentType MIME 类型。
ContentType string `gorm:"type:varchar(128)" json:"contentType"`
// SourceURL 来源地址(下载入库时记录),可空。
SourceURL string `gorm:"type:varchar(1024)" json:"sourceUrl"`
// Metadata 类型相关的扩展元数据(JSON 字符串)。
Metadata string `gorm:"type:text" json:"metadata"`
// StorageState 冷热/外置状态,默认 hot。
StorageState AssetStorageState `gorm:"type:varchar(32);default:hot;not null" json:"storageState"`
// StorageBackend 存储后端标识,默认 local。
StorageBackend string `gorm:"type:varchar(64);default:local;not null" json:"storageBackend"`
// StorageChannelID 外置存储渠道引用(FR-347,见 ADR-073):0=本地/无渠道(历史行为),
// >0 时指向 artifact_storage_channels.id——位置由记录自述,不由全局活跃状态推断。
StorageChannelID uint `gorm:"default:0;not null;index" json:"storageChannelId"`
// RefCount 引用计数,>0 时禁止删除(被模板/实例占用)。
RefCount int `gorm:"default:0;not null" json:"refCount"`
// RelPath 物理文件相对数据根的路径(var/artifacts/<type>/<ab>/<sha256><ext>),便携登记。
RelPath string `gorm:"type:varchar(512)" json:"relPath"`
CreatedAt time.Time `json:"createdAt"`
LastUsedAt *time.Time `json:"lastUsedAt"`
}
Asset 制品库资产索引(内容寻址 + 类型化元数据)。 sha256 既是寻址键也是去重键:同 (type, sha256) 复用同一条记录与同一份物理文件。 参见 ADR-011: 制品库——类型分区的内容寻址与资产模型。
type AssetStorageState ¶
type AssetStorageState string
AssetStorageState 制品存储状态,驱动归档/外置生命周期(归档策略为后续 FR,此处先立模型)。
const ( // AssetStorageHot 热数据,存于本地 var/artifacts。 AssetStorageHot AssetStorageState = "hot" // AssetStorageArchived 已归档(仍由平台管理,位置变化)。 AssetStorageArchived AssetStorageState = "archived" // AssetStorageExternal 外置到对象存储等后端。 AssetStorageExternal AssetStorageState = "external" // AssetStorageLost 失效:索引在、外置对象缺失,下载不可用(FR-349 对账「标记失效」处置写入; // 重传同内容文件去重命中即补传对象并复位 external,自愈语义见 artifact-s3-reconcile spec §3.6)。 AssetStorageLost AssetStorageState = "lost" )
type AssetType ¶
type AssetType string
AssetType 制品类型。类型间物理分目录、类型内按 sha256 去重。参见 ADR-011。
const ( // AssetTypeCore MC 服务器核心 jar(Paper/Spigot/Velocity 等)。 AssetTypeCore AssetType = "core" // AssetTypePlugin 插件 jar。 AssetTypePlugin AssetType = "plugin" // AssetTypeImage 图片。 AssetTypeImage AssetType = "image" // AssetTypeVideo 视频。 AssetTypeVideo AssetType = "video" // AssetTypeArchive 归档包(zip/tar 等)。 AssetTypeArchive AssetType = "archive" // AssetTypeBlob 通用二进制。 AssetTypeBlob AssetType = "blob" // AssetTypeClientFile 客户端分发制品(OTA 单文件压缩/原文)。 // 内容寻址键 = 制品(压缩后)自身 sha256,即 manifest files[].artifact.sha256(FR-087,见 ADR-022)。 AssetTypeClientFile AssetType = "client-file" // AssetTypeClientPack 客户端分发 .jmpack 容器(zstd 压缩段拼接 + Ed25519 签名,FR-097,见 ADR-021/022)。 AssetTypeClientPack AssetType = "client-pack" // AssetTypeClientCore updater-core jar 制品(集中版本管理,FR-193,见 ADR-045)。 // 内容寻址键 = core jar 制品(压缩后)自身 sha256,即 manifest agent.core.platforms[os].artifact.sha256。 // 一份 jar 三平台通用(ADR-021):上传一份,manifest 生成时 fan-out 填各 platform 键。 AssetTypeClientCore AssetType = "client-core" // AssetTypeClientUpdaterCore updater-core jar 归档制品(FR-259,见 updater-arch-simplification spec §D)。 // make embed-client-updater 构建的新 core jar 入库归档为此类型(不覆盖旧版,内容寻址天然多版本)。 // 频道选定版本(ClientChannel.SelectedCoreSHA256)指向本类型制品的 sha256,coreEndpoint 据此返回版本信息。 AssetTypeClientUpdaterCore AssetType = "client-updater-core" // AssetTypeServerProbe 由制品版本库管理的 ServerProbe 探针 jar(FR-409)。 AssetTypeServerProbe AssetType = "server-probe" )
type AuditLog ¶
type AuditLog struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
UserID uint `gorm:"not null;index" json:"userId"`
Action string `gorm:"type:varchar(64);not null" json:"action"` // instance.start, user.create, etc.
TargetType string `gorm:"type:varchar(32)" json:"targetType"` // instance, user, group
TargetID string `gorm:"type:varchar(64)" json:"targetId"`
Detail string `gorm:"type:text" json:"detail"` // JSON
IP string `gorm:"type:varchar(64)" json:"ip"`
// Failed 操作是否失败(FR-321:失败操作也留痕并带错误内容)。语义取「失败」而非「成功」:
// 失败是非零值 true,规避 GORM 零值列不进 INSERT 的坑(存 success 时 false 会被 default 吃掉),
// 且历史行零值天然=未失败,无需迁移回填。
Failed bool `json:"failed"`
// Error 失败时的错误内容(响应 error body 截断,FR-321)。
Error string `gorm:"type:varchar(512)" json:"error"`
CreatedAt time.Time `json:"createdAt"`
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
}
AuditLog 审计日志。
type AuthSetupLock ¶ added in v0.21.0
type AuthSetupLock struct {
Key string `gorm:"type:varchar(64);primaryKey"`
CreatedAt time.Time `json:"not null"`
}
AuthSetupLock 是首次管理员初始化的数据库互斥锁。 单行主键约束保证并发请求或多进程部署中只有一个请求能完成初始化。
type Backup ¶
type Backup struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
InstanceID uint `gorm:"not null;index" json:"instanceId"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
FilePath string `gorm:"type:varchar(512)" json:"filePath"`
FileSizeMB float64 `gorm:"default:0" json:"fileSizeMb"`
Type BackupType `gorm:"default:0" json:"type"`
Mode BackupMode `gorm:"default:0" json:"mode"`
Status BackupStatus `gorm:"default:0" json:"status"`
// ParentID 增量备份的父备份 ID,串成备份链;全量备份为 nil(FR-056)。
ParentID *uint `gorm:"index" json:"parentId,omitempty"`
// Manifest 本次备份完成后工作目录的完整文件清单(JSON 序列化的 manifest 数组)。
// 作为下一次增量的基准与链式恢复的依据,由 Worker 返回、CP 持久化。
Manifest string `gorm:"type:text" json:"-"`
// StorageID 远程存储后端 ID;nil 表示存于节点本地数据根(FR-057)。
StorageID *uint `gorm:"index" json:"storageId,omitempty"`
// StorageKey 上传到远程后端的对象键;本地备份为空(FR-057)。
StorageKey string `gorm:"type:varchar(512)" json:"storageKey,omitempty"`
// Checksum 归档 tar.gz 的 SHA-256,用于恢复前完整性校验(FR-171)。
Checksum string `gorm:"type:char(64)" json:"checksum,omitempty"`
// ChecksumAlgo 校验算法,当前固定 sha256(FR-171)。
ChecksumAlgo string `gorm:"type:varchar(16)" json:"checksumAlgo,omitempty"`
CreatedAt time.Time `json:"createdAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
Backup 备份记录。
type BackupMode ¶
type BackupMode int
BackupMode 备份模式:全量或增量(FR-056)。 与 BackupType(触发来源)正交:手动/定时备份均可为全量或增量。
const ( BackupModeFull BackupMode = 0 // 全量:打包工作目录全部文件 BackupModeIncremental BackupMode = 1 // 增量:仅打包相对父备份变化的文件 )
type BackupStatus ¶
type BackupStatus int
BackupStatus 备份状态。
const ( BackupStatusPending BackupStatus = 0 // 待处理 BackupStatusInProgress BackupStatus = 1 // 进行中 BackupStatusCompleted BackupStatus = 2 // 完成 BackupStatusFailed BackupStatus = 3 // 失败 )
type BackupStorage ¶
type BackupStorage struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
// ActiveNameKey 仅活跃记录保存名称,软删时置 NULL;SQLite/MySQL 均允许唯一索引中的多个 NULL。
ActiveNameKey *string `gorm:"type:varchar(128);uniqueIndex:uniq_backup_storage_active_name_key" json:"-"`
Type BackupStorageType `gorm:"type:varchar(32);not null" json:"type"`
// Endpoint S3 endpoint / WebDAV 基地址 / SFTP host[:port]。
Endpoint string `gorm:"type:varchar(512)" json:"endpoint"`
// Bucket S3 bucket(其余类型忽略)。
Bucket string `gorm:"type:varchar(255)" json:"bucket"`
// Region S3 region(SigV4 用,缺省 us-east-1)。
Region string `gorm:"type:varchar(64)" json:"region"`
// Prefix 对象键/远程目录前缀,便于多实例/多平台共用一个后端。
Prefix string `gorm:"type:varchar(255)" json:"prefix"`
// AccessKeyEnv 访问密钥的环境变量引用(如 ${JIANMANAGER_BACKUP_S3_AK})。
AccessKeyEnv string `gorm:"type:varchar(255)" json:"accessKeyEnv"`
// SecretKeyEnv 密钥的环境变量引用(如 ${JIANMANAGER_BACKUP_S3_SK})。
SecretKeyEnv string `gorm:"type:varchar(255)" json:"secretKeyEnv"`
// UseSSL S3 是否启用 TLS。默认由应用层(router/service)设为 true;
// 不用 gorm default:true,否则 GORM 会把显式 false(零值)覆盖回 true。
UseSSL bool `json:"useSsl"`
// LastTest* 保存已落库后端最近一次连通性测试结果;表单临时测试不写入。
LastTestAt *time.Time `json:"lastTestAt,omitempty"`
LastTestOk bool `json:"lastTestOk"`
LastTestMessage string `gorm:"type:varchar(255)" json:"lastTestMessage"`
// BackupCount/UsedBytes 为 FR-152 列表聚合展示字段,不落库。
BackupCount int64 `gorm:"-" json:"backupCount"`
UsedBytes int64 `gorm:"-" json:"usedBytes"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
BackupStorage 备份远程存储后端配置(FR-057)。
凭证字段(AccessKey/SecretKey)按 .claude/rules/config-files.md 规范以 ${ENV_VAR} 形式存储, 不落明文;下发 Worker 前由 service 从环境变量解析为明文(CP 拥有配置)。参见 ADR-011 对齐。
type BackupStorageType ¶
type BackupStorageType string
BackupStorageType 备份远程存储后端类型(FR-057)。 与制品库 Asset.StorageBackend 的语义对齐:local 表示节点本地数据根,其余为外置后端。
const ( // BackupStorageLocal 本地:备份仅留在节点数据根 var/backups(默认)。 BackupStorageLocal BackupStorageType = "local" // BackupStorageS3 S3 兼容对象存储(AWS S3 / MinIO / 阿里 OSS 等)。 BackupStorageS3 BackupStorageType = "s3" // BackupStorageSFTP SFTP/SSH 远程主机。 BackupStorageSFTP BackupStorageType = "sftp" // BackupStorageWebDAV WebDAV 服务。 BackupStorageWebDAV BackupStorageType = "webdav" )
type BackupType ¶
type BackupType int
BackupType 备份类型。
const ( BackupTypeManual BackupType = 0 // 手动 BackupTypeScheduled BackupType = 1 // 定时 )
type BanRecord ¶
type BanRecord struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
// PlayerName 被封禁玩家名(大小写按客户端原样存储)。
PlayerName string `gorm:"type:varchar(64);not null;index" json:"playerName"`
// Reason 封禁原因(下发给 RCON ban 命令并入库留档)。
Reason string `gorm:"type:varchar(512)" json:"reason"`
// Scope 封禁范围:network / instance / global。
Scope BanScope `gorm:"type:varchar(16);not null;default:global" json:"scope"`
// ScopeID 范围目标 ID:network 时为 NetworkID,instance 时为 InstanceID,global 时为 0。
ScopeID uint `gorm:"default:0" json:"scopeId"`
// OperatorID 执行封禁的用户 ID(关联审计)。
OperatorID uint `gorm:"not null;index" json:"operatorId"`
// Active 是否仍被本平台视为生效;解封置 false,保留记录用于追溯。
Active bool `gorm:"default:true;index" json:"active"`
// CreatedAt 封禁时间。
CreatedAt time.Time `json:"createdAt"`
// UnbannedAt 解封时间;未解封为 nil。
UnbannedAt *time.Time `json:"unbannedAt"`
// Operator 关联用户,便于列表展示操作者用户名。
Operator User `gorm:"foreignKey:OperatorID" json:"operator,omitempty"`
}
BanRecord 玩家封禁记录(FR-054)。
RCON 是无状态命令通道,封禁执行后服务端自身的 banned-players 文件才是权威来源; 本表是 JianManager 侧的可查询审计台账:谁、何时、为何、对哪个范围封禁了某玩家, 以及该封禁当前是否仍被本平台视为生效(解封时置 Active=false 而非删除,保留历史)。
type Bot ¶
type Bot struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
InstanceID uint `gorm:"not null;index" json:"instanceId"`
StressSessionID *uint `gorm:"index" json:"stressSessionId,omitempty"`
ExecutorNodeID *uint `gorm:"index;index:idx_bots_executor_generation,priority:1" json:"executorNodeId,omitempty"`
LoadBatchID *uint `gorm:"index" json:"loadBatchId,omitempty"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
Status BotStatus `gorm:"type:varchar(32);default:pending" json:"status"`
// DesiredState 是 CP 对 Bot 的期望运行态(running/stopped),与 runtime Status 分离(FR-365)。
DesiredState BotDesiredState `gorm:"type:varchar(16);not null;default:stopped;index" json:"desiredState"`
WorkerEpoch string `gorm:"type:varchar(36);not null;default:''" json:"workerEpoch"`
WorkerEpochGeneration int64 `gorm:"not null;default:0" json:"workerEpochGeneration"`
LastEventSeq int64 `gorm:"not null;default:0" json:"lastEventSeq"`
LastSeenAt *time.Time `json:"lastSeenAt,omitempty"`
ConnectedAt *time.Time `json:"connectedAt,omitempty"`
DesiredStateGeneration int64 `gorm:"not null;default:1;index:idx_bots_executor_generation,priority:2" json:"desiredStateGeneration"`
ConfigHash string `gorm:"type:char(64);not null;default:''" json:"configHash"`
// ReconnectCount 累计成功触发的自动重连次数,服务端恢复后不清零(FR-365)。
ReconnectCount int `gorm:"not null;default:0" json:"reconnectCount"`
CohortKey string `gorm:"type:varchar(64);not null;default:''" json:"cohortKey"`
// LastError 最近一次委托 Worker 失败的原因(如 bot-worker 依赖未装、节点未连)。
// 委托成功即清空;status=error 时前端据此显示可操作指引,杜绝「创建 201 但永远 pending 零反馈」。
LastError string `gorm:"type:text" json:"lastError,omitempty"`
Config string `gorm:"type:text" json:"config"` // JSON: server, port, auth
Behavior string `gorm:"type:varchar(64)" json:"behavior"`
WorkerID string `gorm:"type:varchar(128)" json:"workerId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// Instance 表示被测目标实例和权限归属,不代表 Bot 实际执行位置。
Instance Instance `gorm:"foreignKey:InstanceID" json:"-"`
// ExecutorNode 是实际运行 Bot Worker 的节点;为空时兼容回退 Instance.NodeID。
ExecutorNode *Node `gorm:"foreignKey:ExecutorNodeID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT" json:"executorNode,omitempty"`
// LoadBatch 是分布式运行所属批次;删除批次时保留 Bot 并清空关联。
LoadBatch *BotLoadBatch `gorm:"foreignKey:LoadBatchID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL" json:"-"`
// StressSession 所属压测会话;删除会话时保留 Bot,并清空关联。
StressSession *BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL" json:"-"`
}
Bot Mineflayer Bot。
type BotDesiredState ¶ added in v0.20.0
type BotDesiredState string
BotDesiredState 是 CP 对 Bot 的期望状态(desired-state 真源,FR-365)。
const ( BotDesiredRunning BotDesiredState = "running" BotDesiredStopped BotDesiredState = "stopped" )
type BotLoadActionResult ¶ added in v0.19.0
type BotLoadActionResult struct {
ID uint `gorm:"primaryKey" json:"id"`
StressSessionID uint `gorm:"not null;index" json:"stressSessionId"`
BotID uint `gorm:"not null;index" json:"botId"`
CohortKey string `gorm:"type:varchar(64);not null" json:"cohortKey"`
StepID string `gorm:"type:varchar(64);not null" json:"stepId"`
ActionRunID string `gorm:"type:char(36);not null;uniqueIndex" json:"actionRunId"`
Attempt int `gorm:"not null" json:"attempt"`
Status BotLoadActionResultStatus `gorm:"type:varchar(16);not null;index" json:"status"`
ErrorCode string `gorm:"type:varchar(64)" json:"errorCode,omitempty"`
Message string `gorm:"type:text" json:"message,omitempty"`
DurationMS int64 `gorm:"not null;default:0" json:"durationMs"`
CorrelationToken string `gorm:"type:varchar(128);index" json:"correlationToken,omitempty"`
StartedAt time.Time `gorm:"not null" json:"startedAt"`
EndedAt *time.Time `json:"endedAt,omitempty"`
ResultJSON string `gorm:"type:longtext" json:"resultJson,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
StressSession BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
Bot Bot `gorm:"foreignKey:BotID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
}
BotLoadActionResult 持久化场景动作开始与首个终态。
type BotLoadActionResultStatus ¶ added in v0.19.0
type BotLoadActionResultStatus string
BotLoadActionResultStatus 是场景动作结果状态。
const ( BotLoadActionRunning BotLoadActionResultStatus = "running" BotLoadActionSucceeded BotLoadActionResultStatus = "succeeded" BotLoadActionFailed BotLoadActionResultStatus = "failed" BotLoadActionTimedOut BotLoadActionResultStatus = "timed_out" BotLoadActionCancelled BotLoadActionResultStatus = "cancelled" )
type BotLoadBatch ¶ added in v0.19.0
type BotLoadBatch struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
StressSessionID uint `gorm:"not null;index;uniqueIndex:uniq_bot_load_batch_ordinal" json:"stressSessionId"`
ExecutorNodeID uint `gorm:"not null;index" json:"executorNodeId"`
Ordinal int `gorm:"not null;uniqueIndex:uniq_bot_load_batch_ordinal" json:"ordinal"`
PlannedCount int `gorm:"not null" json:"plannedCount"`
AcceptedCount int `gorm:"default:0" json:"acceptedCount"`
ConnectedCount int `gorm:"default:0" json:"connectedCount"`
FailedCount int `gorm:"default:0" json:"failedCount"`
State BotLoadBatchState `gorm:"type:varchar(16);default:planned;index" json:"state"`
IdempotencyKey string `gorm:"type:varchar(128);uniqueIndex;not null" json:"idempotencyKey"`
ConnectStartAt time.Time `json:"connectStartAt"`
ConnectIntervalMS int `gorm:"not null" json:"connectIntervalMs"`
LastError string `gorm:"type:text" json:"lastError,omitempty"`
StartedAt *time.Time `json:"startedAt,omitempty"`
EndedAt *time.Time `json:"endedAt,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
StressSession BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
ExecutorNode Node `gorm:"foreignKey:ExecutorNodeID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT" json:"executorNode,omitempty"`
}
BotLoadBatch 记录一次压测运行在单个执行节点上的确定性分片。
func (*BotLoadBatch) BeforeCreate ¶ added in v0.19.0
func (b *BotLoadBatch) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成批次 UUID。
type BotLoadBatchState ¶ added in v0.19.0
type BotLoadBatchState string
BotLoadBatchState 分布式 Bot 批次状态。
const ( BotLoadBatchPlanned BotLoadBatchState = "planned" BotLoadBatchDispatching BotLoadBatchState = "dispatching" BotLoadBatchRunning BotLoadBatchState = "running" BotLoadBatchStopped BotLoadBatchState = "stopped" BotLoadBatchFailed BotLoadBatchState = "failed" )
type BotLoadCommandCheckpoint ¶ added in v0.20.0
type BotLoadCommandCheckpoint struct {
ID uint `gorm:"primaryKey" json:"id"`
StressSessionID uint `gorm:"not null;index" json:"stressSessionId"`
BotID *uint `gorm:"index" json:"botId,omitempty"`
RunUUID string `gorm:"type:char(36);not null;uniqueIndex:uniq_bot_load_cmd_ckpt_key" json:"runUuid"`
BotUUID string `gorm:"type:char(36);not null;uniqueIndex:uniq_bot_load_cmd_ckpt_key" json:"botUuid"`
StepID string `gorm:"type:varchar(64);not null;uniqueIndex:uniq_bot_load_cmd_ckpt_key" json:"stepId"`
CommandID string `gorm:"type:varchar(64);not null;uniqueIndex:uniq_bot_load_cmd_ckpt_key" json:"commandId"`
Occurrence int `gorm:"not null;uniqueIndex:uniq_bot_load_cmd_ckpt_key" json:"occurrence"`
Generation int64 `gorm:"not null" json:"generation"`
ScheduleRunID string `gorm:"type:char(36);not null;index" json:"scheduleRunId"`
ActionRunID string `gorm:"type:char(36);not null;index" json:"actionRunId"`
PlannedAtUnixMs *int64 `json:"plannedAtUnixMs,omitempty"`
SentAtUnixMs *int64 `json:"sentAtUnixMs,omitempty"`
Attempt int `gorm:"not null;default:0" json:"attempt"`
Status BotLoadCommandCheckpointStatus `gorm:"type:varchar(32);not null;index" json:"status"`
ErrorCode string `gorm:"type:varchar(64)" json:"errorCode,omitempty"`
EndedAt *time.Time `json:"endedAt,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
StressSession BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
}
BotLoadCommandCheckpoint 是 FR-369 命令编排 occurrence 账本。
func (*BotLoadCommandCheckpoint) BeforeCreate ¶ added in v0.20.0
func (c *BotLoadCommandCheckpoint) BeforeCreate(tx *gorm.DB) error
BeforeCreate 自动填充生成时间;ID 由数据库生成。
type BotLoadCommandCheckpointStatus ¶ added in v0.20.0
type BotLoadCommandCheckpointStatus string
BotLoadCommandCheckpointStatus 是命令编排 checkpoint 状态机。
const ( BotLoadCommandCheckpointPrepared BotLoadCommandCheckpointStatus = "prepared" BotLoadCommandCheckpointScheduled BotLoadCommandCheckpointStatus = "scheduled" BotLoadCommandCheckpointSent BotLoadCommandCheckpointStatus = "sent" BotLoadCommandCheckpointFailed BotLoadCommandCheckpointStatus = "failed" BotLoadCommandCheckpointTimedOut BotLoadCommandCheckpointStatus = "timed_out" BotLoadCommandCheckpointCancelled BotLoadCommandCheckpointStatus = "cancelled" )
type BotLoadMetricSample ¶ added in v0.20.0
type BotLoadMetricSample struct {
ID uint `gorm:"primaryKey" json:"id"`
StressSessionID uint `` /* 132-byte string literal not displayed */
SampledAt time.Time `gorm:"not null;uniqueIndex:uniq_bot_load_metric_sample,priority:2" json:"sampledAt"`
StageIndex int `gorm:"not null;index:idx_bot_load_metric_stage,priority:2" json:"stageIndex"`
CountsJSON string `gorm:"type:longtext;not null" json:"countsJson"`
CommandJSON string `gorm:"type:longtext;not null" json:"commandJson"`
BarrierJSON string `gorm:"type:longtext;not null" json:"barrierJson"`
ExecutorJSON string `gorm:"type:longtext;not null" json:"executorJson"`
LatencyJSON string `gorm:"type:longtext;not null" json:"latencyJson"`
ErrorsJSON string `gorm:"type:longtext;not null" json:"errorsJson"`
// TargetLegacyJSON 可选 legacy 指标;缺失时 null,不写 0。
TargetLegacyJSON *string `gorm:"type:longtext" json:"targetLegacyJson,omitempty"`
CreatedAt time.Time `json:"createdAt"`
StressSession BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
}
BotLoadMetricSample 是 FR-370 每运行 5 秒一行的聚合指标样本。
func (BotLoadMetricSample) TableName ¶ added in v0.20.0
func (BotLoadMetricSample) TableName() string
TableName 固定表名。
type BotLoadRunEvent ¶ added in v0.20.0
type BotLoadRunEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
StressSessionID uint `` /* 179-byte string literal not displayed */
RunUUID string `gorm:"type:char(36);not null" json:"runUuid"`
Type BotLoadRunEventType `gorm:"type:varchar(32);not null;index:idx_bot_load_run_event_type,priority:2" json:"type"`
OccurredAt time.Time `gorm:"not null;index:idx_bot_load_run_event_time,priority:2" json:"occurredAt"`
StageIndex *int `json:"stageIndex,omitempty"`
ActionRunID *string `gorm:"type:char(36);index:idx_bot_load_run_event_action,priority:2" json:"actionRunId,omitempty"`
BotUUID *string `gorm:"type:char(36);index:idx_bot_load_run_event_bot,priority:2" json:"botUuid,omitempty"`
ExecutorNodeID *uint `gorm:"index:idx_bot_load_run_event_executor,priority:2" json:"executorNodeId,omitempty"`
StepID *string `gorm:"type:varchar(64);index:idx_bot_load_run_event_step,priority:2" json:"stepId,omitempty"`
PayloadJSON string `gorm:"type:longtext;not null" json:"payloadJson"`
LegacyJSON *string `gorm:"type:longtext" json:"legacyJson,omitempty"`
CreatedAt time.Time `json:"createdAt"`
StressSession BotStressSession `gorm:"foreignKey:StressSessionID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
}
BotLoadRunEvent 是 FR-370 运行历史事件(append-only,不随 metric TTL 删除)。
func (BotLoadRunEvent) TableName ¶ added in v0.20.0
func (BotLoadRunEvent) TableName() string
TableName 固定表名。
type BotLoadRunEventType ¶ added in v0.20.0
type BotLoadRunEventType string
BotLoadRunEventType 是 append-only 运行事件类型。
const ( BotLoadRunEventRunState BotLoadRunEventType = "run-state" BotLoadRunEventStage BotLoadRunEventType = "stage" BotLoadRunEventBarrier BotLoadRunEventType = "barrier" BotLoadRunEventScenarioAction BotLoadRunEventType = "scenario-action" BotLoadRunEventCommandSchedule BotLoadRunEventType = "command-schedule" BotLoadRunEventCommandSend BotLoadRunEventType = "command-send" BotLoadRunEventWorkerHealth BotLoadRunEventType = "worker-health" BotLoadRunEventExecutorCrash BotLoadRunEventType = "executor-crash" BotLoadRunEventSafetyStop BotLoadRunEventType = "safety-stop" BotLoadRunEventReportReady BotLoadRunEventType = "report-ready" )
type BotLoadRunState ¶ added in v0.20.0
type BotLoadRunState string
BotLoadRunState 是 FR-370 运行状态机枚举。
const ( BotLoadRunPending BotLoadRunState = "pending" BotLoadRunPreflighting BotLoadRunState = "preflighting" BotLoadRunReady BotLoadRunState = "ready" BotLoadRunStarting BotLoadRunState = "starting" BotLoadRunRunning BotLoadRunState = "running" BotLoadRunDegraded BotLoadRunState = "degraded" BotLoadRunStopping BotLoadRunState = "stopping" BotLoadRunCancelling BotLoadRunState = "cancelling" BotLoadRunCompleted BotLoadRunState = "completed" BotLoadRunFailed BotLoadRunState = "failed" BotLoadRunCancelled BotLoadRunState = "cancelled" )
type BotLoadTemplate ¶ added in v0.20.0
type BotLoadTemplate struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
CreatedBy uint `gorm:"not null;index;uniqueIndex:uniq_bot_load_tpl_active_name,priority:1" json:"createdBy"`
// ActiveNameKey 为 trim 后名称 UTF-8 的 SHA-256 hex;软删时置 null 以允许复用名称。
ActiveNameKey *string `gorm:"type:char(64);uniqueIndex:uniq_bot_load_tpl_active_name,priority:2" json:"-"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
Description string `gorm:"type:text;not null" json:"description"`
CommandSchedule string `gorm:"type:longtext;not null" json:"commandSchedule"`
LoadProfile string `gorm:"type:longtext;not null" json:"loadProfile"`
Thresholds string `gorm:"type:longtext;not null" json:"thresholds"`
Tags string `gorm:"type:longtext;not null" json:"tags"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Creator User `gorm:"foreignKey:CreatedBy;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT" json:"-"`
}
BotLoadTemplate 是 FR-370 命令压测可复用模板(个人所有权,不绑定目标实例)。
func (*BotLoadTemplate) BeforeCreate ¶ added in v0.20.0
func (t *BotLoadTemplate) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成 UUID。
func (BotLoadTemplate) TableName ¶ added in v0.20.0
func (BotLoadTemplate) TableName() string
TableName 固定表名。
type BotLoadVerdict ¶ added in v0.20.0
type BotLoadVerdict string
BotLoadVerdict 是运行判定结果。
const ( BotLoadVerdictPending BotLoadVerdict = "pending" BotLoadVerdictPassed BotLoadVerdict = "passed" BotLoadVerdictFailed BotLoadVerdict = "failed" BotLoadVerdictAborted BotLoadVerdict = "aborted" )
type BotStressSession ¶
type BotStressSession struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
InstanceID uint `gorm:"not null;index" json:"instanceId"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
NamePrefix string `gorm:"type:varchar(64);not null" json:"namePrefix"`
Status BotStressSessionStatus `gorm:"type:varchar(32);default:pending;index" json:"status"`
BotCount int `gorm:"not null" json:"botCount"`
Behavior string `gorm:"type:varchar(64)" json:"behavior"`
Config string `gorm:"type:text" json:"config"`
OrchestrationYAML string `gorm:"type:text" json:"orchestrationYaml,omitempty"`
OrchestrationSummary string `gorm:"type:text" json:"orchestrationSummary,omitempty"`
ScenarioSnapshot string `gorm:"type:longtext" json:"scenarioSnapshot,omitempty"`
CommandScheduleSnap string `gorm:"type:longtext" json:"commandScheduleSnapshot,omitempty"`
AllocationPlan string `gorm:"type:text" json:"allocationPlan,omitempty"`
SchemaVersion int `gorm:"type:smallint;not null;default:1;index" json:"schemaVersion"`
// FR-370 V2 专属列:schemaVersion=1 历史行允许 null,schemaVersion=2 由 service 强制完整。
TemplateID *uint `gorm:"index" json:"templateId,omitempty"`
LoadProfile string `gorm:"type:longtext" json:"loadProfile,omitempty"`
Thresholds string `gorm:"type:longtext" json:"thresholds,omitempty"`
RunState *BotLoadRunState `gorm:"type:varchar(32);index" json:"runState,omitempty"`
CurrentStage *int `json:"currentStage,omitempty"`
Verdict *BotLoadVerdict `gorm:"type:varchar(16);index" json:"verdict,omitempty"`
MaxStableBots *int `json:"maxStableBots,omitempty"`
FailureSummary string `gorm:"type:longtext" json:"failureSummary,omitempty"`
ReportSummary string `gorm:"type:longtext" json:"reportSummary,omitempty"`
Succeeded int `gorm:"default:0" json:"succeeded"`
Failed int `gorm:"default:0" json:"failed"`
LastError string `gorm:"type:text" json:"lastError,omitempty"`
StartedAt *time.Time `json:"startedAt,omitempty"`
EndedAt *time.Time `json:"endedAt,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Instance Instance `gorm:"foreignKey:InstanceID" json:"instance,omitempty"`
Template *BotLoadTemplate `gorm:"foreignKey:TemplateID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL" json:"-"`
}
BotStressSession Bot 压测会话。
func (*BotStressSession) BeforeCreate ¶
func (s *BotStressSession) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成 UUID。
type BotStressSessionStatus ¶
type BotStressSessionStatus string
BotStressSessionStatus 压测会话状态(V1 兼容列;V2 与 run_state 同事务映射)。
const ( BotStressSessionPending BotStressSessionStatus = "pending" BotStressSessionRunning BotStressSessionStatus = "running" BotStressSessionStopped BotStressSessionStatus = "stopped" BotStressSessionError BotStressSessionStatus = "error" )
type BusinessEvent ¶
type BusinessEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
// Domain 业务域命名空间(economy/inventory…);与来源 scope、DedupKey 组成唯一去重键。
Domain string `gorm:"type:varchar(32);not null;uniqueIndex:idx_be_scope_dedup,priority:1;index:idx_be_domain_time,priority:1" json:"domain"`
// DedupKey 业务事件去重锚点(经济域为 mce ledgerId,只有 node→zone 内唯一)。
DedupKey string `gorm:"column:dedup_key;type:varchar(128);not null;uniqueIndex:idx_be_scope_dedup,priority:4" json:"dedupKey"`
// Action 业务事件子类型(economy_change…),供下游分流/展示。
Action string `gorm:"type:varchar(64);not null" json:"action"`
// NodeUUID 事件来源节点(经济多区/多节点聚合的 node→zone 维度起点)。
NodeUUID string `gorm:"column:node_uuid;type:varchar(64);not null;uniqueIndex:idx_be_scope_dedup,priority:2;index:idx_be_node" json:"nodeUuid"`
// ZoneID 经济事件的 mce 区;其它业务域为空串。账本 ID 只在 node→zone 内去重。
ZoneID string `gorm:"column:zone_id;type:varchar(64);not null;default:'';uniqueIndex:idx_be_scope_dedup,priority:3" json:"zoneId,omitempty"`
// InstanceUUID 事件来源实例(探针所在子服实例)。
InstanceUUID string `gorm:"column:instance_uuid;type:varchar(64);index:idx_be_instance" json:"instanceUuid"`
// Operator 操作者身份透传位(FR-121 业务写横切硬化时回填"哪个管理员/为什么";自发事件为空)。
Operator string `gorm:"type:varchar(128)" json:"operator,omitempty"`
// PayloadJSON 业务信封原始载荷 JSON(CP 不解析语义,原样留存供下游/审计;经济域同时落结构化专表)。
PayloadJSON string `gorm:"column:payload_json;type:text" json:"payloadJson"`
// OccurredAt 业务侧事件发生时间(epoch 毫秒,来自探针信封;0 表示未携带)。
OccurredAt int64 `gorm:"column:occurred_at;index:idx_be_domain_time,priority:2" json:"occurredAt"`
// CreatedAt CP 落库时间。
CreatedAt time.Time `json:"createdAt"`
}
BusinessEvent 是 JBIS 通用业务事件信封表(插件无关汇聚底座,FR-116 底座 / FR-122,见 ADR-028)。
探针经反向 WS 桥上报的业务域事件(economy/inventory…)一律按本表落库:CP **插件无关**,只认 domain/action/payload 信封 + dedupKey,不理解具体业务语义。按 (Domain, NodeUUID, ZoneID, DedupKey) 唯一去重应对桥的 **至少一次投递**与跨节点重试(同键重发 insert-or-ignore,不重复计数)。新增业务域**无需改表**。
数据所有权(架构不变量):JM 只存汇聚镜像 + 操作审计,业务真源仍在各插件存储;本表是"汇聚镜像"的通用底座, 高价值域(经济)另有结构化专表(EconomyBalanceMirror / EconomyLedgerEntry)供高效查询与对账。
type ClientChannel ¶
type ClientChannel struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 频道 slug:对外标识与端点路径段,全局唯一。约束 `^[a-z0-9][a-z0-9-]{1,63}$`。
ChannelID string `gorm:"column:channel_id;type:varchar(64);uniqueIndex;not null" json:"channelId"`
// Name 展示名。
Name string `gorm:"type:varchar(128);not null" json:"name"`
// Description 描述,可空。
Description string `gorm:"type:varchar(512)" json:"description"`
// CurrentVersion 当前 latest 版本指针占位;0=未发布。本 FR 仅建字段,编排见 FR-088。
CurrentVersion int `gorm:"default:0;not null" json:"currentVersion"`
// Deprecated: PinnedCoreVersion 原为频道 pin 的 updater-core 版本号(FR-193 初版,已随反转废弃,见 ADR-045 改写)。
// updater-core 现由 CP 内嵌默认版本自动驱动 manifest agent.core,运营不再 pin/管理。保留此列(加性、默认 0)
// 仅为兼容存量库、避免无谓迁移;不再被任何运营端点写入、不参与 manifest 生成。
PinnedCoreVersion int `gorm:"default:0;not null" json:"-"`
// SelectedCoreSHA256 频道选定的 updater-core 归档制品 sha256(FR-259,见 updater-arch-simplification spec §D)。
// 指向 type=client-updater-core 的 Asset.SHA256;空=未选定(coreEndpoint 回退最新归档版本)。
// 运营经 PUT /client-channels/:id/updater-core/selected 切换,客户端下次启动查 coreEndpoint 即用选定版本。
SelectedCoreSHA256 string `gorm:"column:selected_core_sha256;type:char(64)" json:"-"`
// SelectedCoreVersion 是频道级 core 分发版本号,每次切换选定 SHA 时递增。
// 楔子只按 version 递增决定是否下载,所以选回旧 SHA 回滚时不能返回旧 Asset.Version。
SelectedCoreVersion int `gorm:"column:selected_core_version;default:0;not null" json:"-"`
ProtectionMode string `gorm:"column:protection_mode;type:varchar(32);default:normal;not null" json:"protectionMode"`
ProtectionPolicyJSON string `gorm:"column:protection_policy_json;type:text" json:"-"`
ProtectionUpdatedAt *time.Time `gorm:"column:protection_updated_at" json:"protectionUpdatedAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
ClientChannel 客户端分发频道:每服/每整合包一个,作为 manifest/制品端点的对外标识与路由键。 ChannelID 为运营者指定的 slug(URL 段),CurrentVersion 为 latest 版本指针占位(FR-088 编排)。 参见 ADR-022、FR-086。
type ClientDistDaily ¶
type ClientDistDaily struct {
ID uint `gorm:"primaryKey" json:"id"`
// Day UTC 日期 YYYY-MM-DD。与 channel/version/kind 组成唯一键。
Day string `gorm:"type:char(10);not null;uniqueIndex:idx_cdd_day_chan_ver_kind" json:"day"`
// ChannelID 频道 slug。
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;uniqueIndex:idx_cdd_day_chan_ver_kind" json:"channelId"`
// Version manifest 版本(artifact 聚合为 0)。
Version int `gorm:"not null;uniqueIndex:idx_cdd_day_chan_ver_kind" json:"version"`
// Kind manifest | artifact。
Kind string `gorm:"type:varchar(16);not null;uniqueIndex:idx_cdd_day_chan_ver_kind" json:"kind"`
// Requests 当日该维度请求数。
Requests int64 `gorm:"default:0;not null" json:"requests"`
// Bytes 当日该维度总字节数。
Bytes int64 `gorm:"default:0;not null" json:"bytes"`
}
ClientDistDaily 客户端分发按日聚合(FR-093)。**长保留**,写时增量 upsert;供下载量趋势 + 版本分布(FR-095)。
type ClientDistEvent ¶
type ClientDistEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 频道 slug。
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;index:idx_cde_channel_time" json:"channelId"`
// MachineID 客户端机器码(不可信)。
MachineID string `gorm:"column:machine_id;type:varchar(128);index" json:"machineId"`
// IP 来源 IP(限流/分布主维度)。
IP string `gorm:"type:varchar(64);index" json:"ip"`
// Kind 事件类型:manifest | artifact。
Kind string `gorm:"type:varchar(16);not null" json:"kind"`
// Version manifest 拉取的版本号(artifact 事件为 0,制品跨版本共享)。
Version int `gorm:"default:0;not null" json:"version"`
// ArtifactSHA 制品 sha256(仅 artifact 事件)。
ArtifactSHA string `gorm:"column:artifact_sha;type:char(64)" json:"artifactSha"`
// Bytes 响应字节数。
Bytes int64 `gorm:"default:0;not null" json:"bytes"`
// Status HTTP 状态码(200/206/304/404…)。
Status int `gorm:"default:0;not null" json:"status"`
// ErrCode 语义错误码(FR-249)。成功事件为空;失败事件填与响应 error 字段一致的码
// (INVALID_CLIENT_KEY/NO_LATEST_VERSION/ARTIFACT_NOT_FOUND/SIGN_KEY_NOT_CONFIGURED/CHANNEL_NOT_FOUND/INTERNAL_ERROR)。
ErrCode string `gorm:"column:err_code;type:varchar(48);index" json:"errCode"`
// ErrReason 可读错误原因(FR-265)。
ErrReason string `gorm:"column:err_reason;type:varchar(255)" json:"errReason"`
// Method HTTP 方法(FR-265 日志详情)。
Method string `gorm:"type:varchar(8)" json:"method"`
// Path 请求路径(含 query,FR-265 日志详情)。
Path string `gorm:"type:varchar(1024)" json:"path"`
// RequestBody 请求体预览(FR-265 排障详情,最多保存短文本;凭证类字段不写入)。
RequestBody string `gorm:"column:request_body;type:text" json:"-"`
// ResponseBody 响应体预览(FR-265 排障详情,最多保存短文本;二进制响应不写入)。
ResponseBody string `gorm:"column:response_body;type:text" json:"-"`
// RequestHeadersJSON 请求头 JSON(FR-265)。凭证类头不落库。
RequestHeadersJSON string `gorm:"column:request_headers_json;type:text" json:"-"`
// ResponseHeadersJSON 响应头 JSON(FR-265)。凭证类头不落库。
ResponseHeadersJSON string `gorm:"column:response_headers_json;type:text" json:"-"`
// ETag 响应 ETag 快捷列(FR-265)。
ETag string `gorm:"column:etag;type:varchar(128)" json:"etag"`
// DurationMs 处理耗时(毫秒)。
DurationMs int64 `gorm:"column:duration_ms;default:0;not null" json:"durationMs"`
// CreatedAt 事件时间(清理基准)。
CreatedAt time.Time `gorm:"index:idx_cde_channel_time" json:"createdAt"`
}
ClientDistEvent 客户端分发拉取/下载明细事件(FR-093,见 ADR-023)。 **短保留 + 滚动清理**(数据量治理);供按 IP/机器码/频道/版本/时间检索与近窗去重分布。 机器码/IP 客户端可伪造、不可信,仅追踪统计。
type ClientDistSnapshot ¶
type ClientDistSnapshot struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 频道 slug;与 BucketTS 组成唯一键。空串=跨频道/制品共享桶。
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;default:'';uniqueIndex:idx_cds_channel_bucket,priority:1" json:"channelId"`
// BucketTS 小时桶起点(UTC,整小时对齐)。与 ChannelID 唯一;单列索引供区间扫描/TTL 清理。
BucketTS time.Time `gorm:"not null;uniqueIndex:idx_cds_channel_bucket,priority:2;index:idx_cds_bucket" json:"bucketTs"`
// 拉取侧(源 client_dist_event)。
ManifestPulls int64 `gorm:"default:0;not null" json:"manifestPulls"` // 桶内 manifest 拉取次数
ArtifactPulls int64 `gorm:"default:0;not null" json:"artifactPulls"` // 桶内制品拉取次数
DownloadBytes int64 `gorm:"default:0;not null" json:"downloadBytes"` // 桶内总响应字节
// ActiveMachines 桶内 machineId 精确去重计数(排空串)。machineId 不可信(ADR-023),仅统计近似;
// 跨桶不可简单求和(同客户端跨小时会重复),跨区间去重口径见 ADR-049 §4。
ActiveMachines int64 `gorm:"default:0;not null" json:"activeMachines"`
// VersionDist 版本分布 JSON map[version]count(manifest 拉取按 version 计数)。
VersionDist string `gorm:"column:version_dist;type:text" json:"-"`
// PlatformDist 平台分布 JSON map[os]count(来源遥测 os 字段)。
PlatformDist string `gorm:"column:platform_dist;type:text" json:"-"`
// 更新侧(源 client_telemetry,按 result 分桶计数)。
UpdateTotal int64 `gorm:"default:0;not null" json:"updateTotal"`
UpdateSuccess int64 `gorm:"default:0;not null" json:"updateSuccess"`
UpdateFailStatic int64 `gorm:"column:update_fail_static;default:0;not null" json:"updateFailStatic"` // 断网兜底启动
UpdateRolledBack int64 `gorm:"column:update_rolled_back;default:0;not null" json:"updateRolledBack"`
UpdateError int64 `gorm:"default:0;not null" json:"updateError"`
// LagDist 版本滞后分布 JSON map[lag]count(current_version - toVersion,下界 0;遥测 toVersion>0 时计)。
LagDist string `gorm:"column:lag_dist;type:text" json:"-"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ClientDistSnapshot 客户端分发观测时序快照:每「频道 × 小时桶」一行(FR-217,见 ADR-049)。
由后台任务把 client_dist_event(FR-093)+ client_telemetry(FR-094)离线卷积而来, 与玩家热路径的写时聚合(client_dist_daily/client_telemetry_daily)解耦——观测富维度交给离线卷积, 热路径零新增负担。ChannelID 可为空串(制品端点跨频道共享、明细 channel 可空 → 归入空频道桶; 查询「总」时含之)。分布维度以 JSON map 存 TEXT 列,免随版本/平台/滞后基数增长改表结构。
type ClientIPRule ¶
type ClientIPRule struct {
ID uint `gorm:"primaryKey" json:"id"`
// CIDR IP 或 CIDR(单 IP 视作 /32、/128)。
CIDR string `gorm:"column:cidr;type:varchar(64);not null" json:"cidr"`
// Mode deny | allow。
Mode string `gorm:"type:varchar(8);not null" json:"mode"`
// Note 规则备注。
Note string `gorm:"type:varchar(255)" json:"note"`
// CreatedBy 创建者用户 ID(审计辅助)。
CreatedBy uint `gorm:"default:0;not null" json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
}
ClientIPRule 客户端分发端点 IP 防护规则(FR-096,见 ADR-023)。运行时可改、入审计。
mode=deny:匹配即拒(黑名单,deny 始终优先);mode=allow:存在任一 allow 规则即进入**白名单模式** (仅匹配 allow 的 IP 放行)。CIDR 支持单 IP(视作 /32、/128)或网段。
type ClientMachine ¶
type ClientMachine struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 所属频道 slug。与 MachineID 组成唯一键。
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;uniqueIndex:idx_client_machines_channel_machine" json:"channelId"`
// MachineID 客户端机器码(SHA-256 十六进制,不可逆)。库内仅存哈希。
MachineID string `gorm:"column:machine_id;type:varchar(128);not null;uniqueIndex:idx_client_machines_channel_machine" json:"machineId"`
// HitCount 该机器码在本频道的累计拉取命中次数(弱一致统计)。
HitCount int64 `gorm:"default:0;not null" json:"hitCount"`
// FirstSeen 首次登记时间。
FirstSeen time.Time `json:"firstSeen"`
// LastSeen 最近一次登记时间。
LastSeen time.Time `json:"lastSeen"`
}
ClientMachine 客户端机器码登记(FR-092,见 ADR-023)。
机器码由客户端生成、**不可信**——仅作统计与**辅助**限流维度,**不作信任/授权依据**(限流以 IP 为主,FR-096)。 每频道每机器码一行,记首/末见与命中计数;按机器码维度的统计看板归 FR-095、全链路追踪/留存归 FR-093。
type ClientProtectionAction ¶
type ClientProtectionAction struct {
ID uint `gorm:"primaryKey" json:"id"`
TargetType string `gorm:"type:varchar(32);not null;index" json:"targetType"`
TargetValue string `gorm:"column:target_value;type:varchar(128);default:'';not null;index" json:"targetValue"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);index" json:"channelId"`
Action string `gorm:"type:varchar(64);not null;index" json:"action"`
Status string `gorm:"type:varchar(16);default:active;not null;index" json:"status"`
PolicyJSON string `gorm:"column:policy_json;type:text" json:"-"`
Reason string `gorm:"type:varchar(512)" json:"reason"`
Auto bool `gorm:"default:false;not null" json:"auto"`
ExpiresAt *time.Time `gorm:"index" json:"expiresAt"`
CreatedBy uint `gorm:"default:0;not null" json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
CanceledAt *time.Time `json:"canceledAt"`
}
type ClientPullKey ¶
type ClientPullKey struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 所属频道 slug(随频道删除级联清理)。
ChannelID string `gorm:"column:channel_id;type:varchar(64);index;not null" json:"channelId"`
// Name 密钥名(识别用途,如「正式包」「灰度」)。
Name string `gorm:"type:varchar(128);not null" json:"name"`
// KeyHash 拉取密钥明文的 SHA-256 十六进制小写。**鉴权依据**,库内不存明文。
KeyHash string `gorm:"column:key_hash;type:char(64);uniqueIndex;not null" json:"-"`
// KeyEnc 拉取密钥明文的 AES-256-GCM 可逆加密副本(base64(nonce‖密文);FR-192,见 ADR-044)。
// 仅供平台管理员经 reveal 端点查看明文,不参与鉴权、绝不序列化给客户端。空=不可查看
// (存量老密钥 / 创建时未配 JIANMANAGER_CLIENT_KEY_ENC_SECRET 的密钥)。加性列、默认空。
// 密钥发出后永久使用;管理员可经编辑端点改值(重算 KeyHash + 重写 KeyEnc),不再提供轮换。
KeyEnc string `gorm:"column:key_enc;type:text" json:"-"`
// KeyPrefix 明文前缀(如 jmck_ab12),仅供列表识别,不足以重建密钥。
KeyPrefix string `gorm:"column:key_prefix;type:varchar(16);not null" json:"keyPrefix"`
// Revealable 是否可查看明文(派生字段,不落库;= KeyEnc 非空,FR-192)。
// 供前端对存量「只有哈希」的老密钥禁用「查看」并提示;不泄露密文本身。
Revealable bool `gorm:"-" json:"revealable"`
// Revoked 吊销标记;true 即鉴权失败。
Revoked bool `gorm:"default:false;index;not null" json:"revoked"`
// ExpiresAt 可选过期时间;到期即鉴权失败。
ExpiresAt *time.Time `json:"expiresAt"`
// LastUsedAt 最近一次鉴权命中时间(统计用,弱一致)。
LastUsedAt *time.Time `json:"lastUsedAt"`
SecurityState string `gorm:"column:security_state;type:varchar(32);default:normal;not null" json:"securityState"`
ThrottlePolicyJSON string `gorm:"column:throttle_policy_json;type:text" json:"-"`
SecurityNote string `gorm:"column:security_note;type:varchar(512)" json:"securityNote"`
SecurityUpdatedAt *time.Time `gorm:"column:security_updated_at" json:"securityUpdatedAt"`
CreatedAt time.Time `json:"createdAt"`
// RevokedAt 吊销时间。
RevokedAt *time.Time `json:"revokedAt"`
}
ClientPullKey 频道拉取密钥:玩家侧 updater 拉 manifest/制品时经请求头携带。 半公开凭据(随整包分发会泄露)——仅作鉴权路由 + 吊销,不作内容可信依据(内容可信靠 manifest 签名)。 鉴权只用 KeyHash(SHA-256)比对;另存 AES-256-GCM 可逆加密副本 KeyEnc(FR-192)供管理员查看明文。 参见 ADR-022 §1、ADR-044(拉取密钥可逆加密 + 管理员可查看,修订 ADR-022 决策①的「只存哈希」)。
type ClientRuntimeState ¶
type ClientRuntimeState struct {
ID uint `gorm:"primaryKey" json:"id"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;uniqueIndex:idx_client_runtime_identity;index" json:"channelId"`
MachineID string `gorm:"column:machine_id;type:varchar(128);not null;uniqueIndex:idx_client_runtime_identity;index" json:"machineId"`
PlayerName string `gorm:"column:player_name;type:varchar(32);index" json:"playerName"`
IP string `gorm:"type:varchar(64);index" json:"ip"`
Platform string `gorm:"type:varchar(32);index" json:"platform"`
JavaVersion string `gorm:"column:java_version;type:varchar(32)" json:"javaVersion"`
Launcher string `gorm:"type:varchar(32);index" json:"launcher"`
CoreVersion string `gorm:"column:core_version;type:varchar(64);index" json:"coreVersion"`
LocalVersion int `gorm:"column:local_version;default:0;not null;index" json:"localVersion"`
FirstSeenAt time.Time `gorm:"column:first_seen_at;index" json:"firstSeenAt"`
LastHeartbeatAt time.Time `gorm:"column:last_heartbeat_at;index" json:"lastHeartbeatAt"`
LastUpdateResult string `gorm:"column:last_update_result;type:varchar(16);index" json:"lastUpdateResult"`
LastUpdateAt *time.Time `gorm:"column:last_update_at;index" json:"lastUpdateAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ClientRuntimeState 客户端运行态最新快照(FR-265)。 按 channel_id + machine_id upsert,仅保存最新启动心跳;不作为可信身份,仅用于观测统计。
type ClientSecurityCounter ¶
type ClientSecurityCounter struct {
ID uint `gorm:"primaryKey" json:"id"`
Scope string `gorm:"type:varchar(32);not null;uniqueIndex:idx_client_security_counter_bucket" json:"scope"`
Key string `gorm:"type:varchar(128);not null;uniqueIndex:idx_client_security_counter_bucket" json:"key"`
Bucket string `gorm:"type:varchar(32);not null;uniqueIndex:idx_client_security_counter_bucket" json:"bucket"`
Value int64 `gorm:"default:0;not null" json:"value"`
UpdatedAt time.Time `json:"updatedAt"`
}
type ClientSecurityGroup ¶
type ClientSecurityGroup struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"type:varchar(128);not null;uniqueIndex" json:"name"`
Kind string `gorm:"type:varchar(16);default:manual;not null" json:"kind"`
TargetType string `gorm:"column:target_type;type:varchar(32);default:'';not null" json:"targetType"`
RuleJSON string `gorm:"column:rule_json;type:text" json:"-"`
ActionPolicyJSON string `gorm:"column:action_policy_json;type:text" json:"-"`
Enabled bool `gorm:"default:true;not null" json:"enabled"`
CreatedBy uint `gorm:"default:0;not null" json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type ClientSecurityHello ¶
type ClientSecurityHello struct {
ID uint `gorm:"primaryKey" json:"id"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);index" json:"channelId"`
MachineID string `gorm:"column:machine_id;type:varchar(128);index" json:"machineId"`
InstallID string `gorm:"column:install_id;type:varchar(128);index" json:"installId"`
PlayerName string `gorm:"type:varchar(64);index" json:"playerName"`
Accepted bool `gorm:"default:false;not null" json:"accepted"`
ErrCode string `gorm:"column:err_code;type:varchar(64);index" json:"errCode"`
IP string `gorm:"type:varchar(64);index" json:"ip"`
KeyID uint `gorm:"column:key_id;index" json:"keyId"`
KeyPrefix string `gorm:"column:key_prefix;type:varchar(16)" json:"keyPrefix"`
UserAgent string `gorm:"type:varchar(255)" json:"userAgent"`
PayloadJSON string `gorm:"column:payload_json;type:text" json:"-"`
CreatedAt time.Time `gorm:"index" json:"createdAt"`
}
type ClientSecurityProfile ¶
type ClientSecurityProfile struct {
ID uint `gorm:"primaryKey" json:"id"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;uniqueIndex:idx_client_security_profile_identity" json:"channelId"`
MachineID string `gorm:"column:machine_id;type:varchar(128);not null;uniqueIndex:idx_client_security_profile_identity" json:"machineId"`
InstallID string `gorm:"column:install_id;type:varchar(128);not null;uniqueIndex:idx_client_security_profile_identity" json:"installId"`
PlayerName string `gorm:"type:varchar(64)" json:"playerName"`
PlayerNameNorm string `gorm:"type:varchar(64);index" json:"playerNameNorm"`
KeyID uint `gorm:"column:key_id;index" json:"keyId"`
KeyPrefix string `gorm:"column:key_prefix;type:varchar(16)" json:"keyPrefix"`
FirstSeen time.Time `gorm:"column:first_seen;index" json:"firstSeen"`
LastSeen time.Time `gorm:"column:last_seen;index" json:"lastSeen"`
LastIP string `gorm:"column:last_ip;type:varchar(64);index" json:"lastIp"`
UserAgent string `gorm:"type:varchar(255)" json:"userAgent"`
CoreVersion string `gorm:"type:varchar(64)" json:"coreVersion"`
WedgeVersion string `gorm:"type:varchar(64)" json:"wedgeVersion"`
ManifestVersion string `gorm:"type:varchar(64)" json:"manifestVersion"`
OS string `gorm:"type:varchar(64)" json:"os"`
OSVersion string `gorm:"type:varchar(64)" json:"osVersion"`
Arch string `gorm:"type:varchar(32)" json:"arch"`
JavaVendor string `gorm:"type:varchar(128)" json:"javaVendor"`
JavaVersion string `gorm:"type:varchar(64)" json:"javaVersion"`
JavaArch string `gorm:"type:varchar(32)" json:"javaArch"`
Launcher string `gorm:"type:varchar(128)" json:"launcher"`
Locale string `gorm:"type:varchar(32)" json:"locale"`
Timezone string `gorm:"type:varchar(64)" json:"timezone"`
MemoryTier string `gorm:"type:varchar(32)" json:"memoryTier"`
RiskScore int `gorm:"default:0;not null" json:"riskScore"`
RiskLevel string `gorm:"type:varchar(32);default:normal;not null" json:"riskLevel"`
ProtectionState string `gorm:"type:varchar(32);default:normal;not null" json:"protectionState"`
LabelsJSON string `gorm:"column:labels_json;type:text" json:"-"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type ClientSecurityRiskEvent ¶
type ClientSecurityRiskEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
SubjectType string `gorm:"column:subject_type;type:varchar(32);index" json:"subjectType"`
SubjectValue string `gorm:"column:subject_value;type:varchar(128);index" json:"subjectValue"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);index" json:"channelId"`
MachineID string `gorm:"column:machine_id;type:varchar(128);index" json:"machineId"`
InstallID string `gorm:"column:install_id;type:varchar(128);index" json:"installId"`
PlayerName string `gorm:"type:varchar(64);index" json:"playerName"`
IP string `gorm:"type:varchar(64);index" json:"ip"`
KeyID uint `gorm:"column:key_id;index" json:"keyId"`
KeyPrefix string `gorm:"column:key_prefix;type:varchar(16)" json:"keyPrefix"`
RuleCode string `gorm:"column:rule_code;type:varchar(64);default:'';not null;index" json:"ruleCode"`
Severity string `gorm:"type:varchar(32);default:info;not null" json:"severity"`
ScoreDelta int `gorm:"column:score_delta;default:0;not null" json:"scoreDelta"`
Action string `gorm:"type:varchar(32)" json:"action"`
Reason string `gorm:"type:varchar(512)" json:"reason"`
DetailJSON string `gorm:"column:detail_json;type:text" json:"-"`
CreatedAt time.Time `gorm:"index" json:"createdAt"`
}
type ClientTelemetry ¶
type ClientTelemetry struct {
ID uint `gorm:"primaryKey" json:"id"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);index:idx_ct_channel_time" json:"channelId"`
MachineID string `gorm:"column:machine_id;type:varchar(128);index" json:"machineId"`
PlayerName string `gorm:"column:player_name;type:varchar(32);index" json:"playerName"`
IP string `gorm:"type:varchar(64)" json:"ip"`
Result string `gorm:"type:varchar(16);not null" json:"result"` // success|fail-static|rolled-back|error
FromVersion int `gorm:"default:0;not null" json:"fromVersion"`
ToVersion int `gorm:"default:0;not null" json:"toVersion"`
CoreVersion string `gorm:"column:core_version;type:varchar(64)" json:"coreVersion"`
OS string `gorm:"column:os;type:varchar(32)" json:"os"`
Arch string `gorm:"column:arch;type:varchar(16)" json:"arch"`
JavaVersion string `gorm:"column:java_version;type:varchar(32)" json:"javaVersion"`
JavaVendor string `gorm:"column:java_vendor;type:varchar(64)" json:"javaVendor"`
Launcher string `gorm:"type:varchar(32)" json:"launcher"`
Locale string `gorm:"column:locale;type:varchar(32)" json:"locale"`
Timezone string `gorm:"column:timezone;type:varchar(64)" json:"timezone"`
MemoryTier string `gorm:"column:memory_tier;type:varchar(16)" json:"memoryTier"`
DurationMs int64 `gorm:"column:duration_ms;default:0;not null" json:"durationMs"`
BootSuccess bool `gorm:"column:boot_success;default:false;not null" json:"bootSuccess"`
Error string `gorm:"type:varchar(512)" json:"error"`
CreatedAt time.Time `gorm:"index:idx_ct_channel_time" json:"createdAt"`
}
ClientTelemetry 客户端遥测明细(FR-094 / FR-360,见 ADR-023、contract §4.3)。 **短保留 + 滚动清理**(数据量治理)。仅环境粗粒度 + 不可逆机器码;隐私可关(客户端 opt-out)。 FR-360 增列:core_version/arch(required)与 java_vendor/locale/timezone/memory_tier(diagnostic)。
type ClientTelemetryDaily ¶
type ClientTelemetryDaily struct {
ID uint `gorm:"primaryKey" json:"id"`
Day string `gorm:"type:char(10);not null;uniqueIndex:idx_ctd_day_chan_result" json:"day"`
ChannelID string `gorm:"column:channel_id;type:varchar(64);not null;uniqueIndex:idx_ctd_day_chan_result" json:"channelId"`
Result string `gorm:"type:varchar(16);not null;uniqueIndex:idx_ctd_day_chan_result" json:"result"`
Count int64 `gorm:"default:0;not null" json:"count"`
}
ClientTelemetryDaily 遥测按日聚合(FR-094)。长保留,写时增量;供 FR-095 更新成功率/回退率趋势。 不按 FR-360 新维度打爆基数,仍仅 day×channel×result。
type ClientVersion ¶
type ClientVersion struct {
ID uint `gorm:"primaryKey" json:"id"`
// ChannelID 所属频道 slug(随频道删除级联清理)。
ChannelID string `gorm:"column:channel_id;type:varchar(64);index:idx_client_versions_channel_version,unique;not null" json:"channelId"`
// Version 单调递增整数(同频道内唯一);防降级基准(contract §3)。
Version int `gorm:"index:idx_client_versions_channel_version,unique;not null" json:"version"`
// FilesJSON 文件清单快照([]ManifestFile 的 JSON):path/sha256/md5/size/sync/platform/artifact。
FilesJSON string `gorm:"column:files_json;type:text;not null" json:"-"`
// ManagedDirsJSON 托管目录快照([]string 的 JSON):仅这些目录可增删(减量)。
// FR-255:可含 "*" 哨兵表「整个 gameDir」(clean-all)。
ManagedDirsJSON string `gorm:"column:managed_dirs_json;type:text;not null" json:"-"`
// CleanExcludeJSON 运营自定义排除快照([]string 的 JSON,FR-255):命中前缀永不删。
// 空串=未声明(向后兼容,老版本无此列)。
CleanExcludeJSON string `gorm:"column:clean_exclude_json;type:text" json:"-"`
// AgentJSON 楔子 + updater-core 自更新段快照(ManifestAgent 的 JSON),可空(未声明自更新段)。
AgentJSON string `gorm:"column:agent_json;type:text" json:"-"`
// Note 发布备注(运营可读,信息性)。
Note string `gorm:"type:varchar(512)" json:"note"`
// CreatedBy 发布者用户 ID(审计辅助,0=未知)。
CreatedBy uint `gorm:"default:0;not null" json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
}
ClientVersion 客户端分发版本快照(FR-087,见 ADR-022、contract §2)。 一条记录 = 频道某次发布的完整文件清单 + 同步策略 + 自更新段。Version 单调递增、与 ClientChannel.CurrentVersion 配合定位 latest。manifest 由该快照即时组装 + Ed25519 签名(不缓存签名,密钥轮换/防降级见 ADR-022)。
本 FR(latest-only)只需「能发布一版并以 latest 返回」;完整版本历史/运营回滚/管理台见 FR-088。
type EconomyBalanceMirror ¶
type EconomyBalanceMirror struct {
ID uint `gorm:"primaryKey" json:"id"`
// NodeUUID 余额所在节点(聚合 node→zone 维度起点)。
NodeUUID string `gorm:"column:node_uuid;type:varchar(64);not null;uniqueIndex:idx_ebm_scope,priority:1" json:"nodeUuid"`
// InstanceUUID 余额来源实例,用于业务汇聚读视图按用户组做资源级隔离。
InstanceUUID string `gorm:"column:instance_uuid;type:varchar(64);index" json:"instanceUuid"`
// ZoneID mce 区 ID(CoreLib zoneId);跨区同名玩家独立隔离的关键维度。
ZoneID string `gorm:"column:zone_id;type:varchar(64);not null;uniqueIndex:idx_ebm_scope,priority:2" json:"zoneId"`
// PlayerName 玩家名(区分大小写,mce 口径)。
PlayerName string `` /* 127-byte string literal not displayed */
// Currency 货币 identifier(全局稳定业务键;探针侧已由 currencyId Int 折算,跨服可聚合)。
Currency string `gorm:"type:varchar(64);not null;uniqueIndex:idx_ebm_scope,priority:4" json:"currency"`
// CurrencyID 货币 mce Int 原值(审计回溯用;跨服不保证一致,故不作聚合键)。
CurrencyID int `gorm:"column:currency_id;default:0;not null" json:"currencyId"`
// Balance 最新余额(字符串承载 BigDecimal,禁浮点,防多币种精度失真)。
Balance string `gorm:"type:varchar(64);not null" json:"balance"`
// LastSeq 已应用的最大 mce 区内单调 seq(镜像推进游标,防乱序/重发回退余额)。
LastSeq int64 `gorm:"column:last_seq;default:0;not null" json:"lastSeq"`
// LastLedgerID 最近一次应用的总账流水 ID(可追溯到 [EconomyLedgerEntry])。
LastLedgerID int64 `gorm:"column:last_ledger_id;default:0;not null" json:"lastLedgerId"`
// LastEntryType 最近一次变更的入账类型(DEPOSIT/WITHDRAW/…)。
LastEntryType string `gorm:"column:last_entry_type;type:varchar(32)" json:"lastEntryType"`
// OccurredAt 最近一次变更的业务发生时间(epoch 毫秒)。
OccurredAt int64 `gorm:"column:occurred_at;default:0;not null" json:"occurredAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
EconomyBalanceMirror 是经济结构化镜像表:每 (节点, 区, 玩家, 货币) 的**最新余额**快照(FR-122,见 ADR-028)。
由经济变更事件流(BusinessEvent domain=economy)按 ledgerId 去重后**按 seq 单调推进**维护:仅当来量 seq ≥ 已存 seq 时覆盖余额,乱序/重发的旧事件不回退镜像。聚合维度 (NodeUUID, ZoneID, PlayerName, Currency) 唯一——**node→zone 维度**确保跨区同名玩家不串味/不重复计数(mce 账户按 zoneId 隔离,同名玩家跨区独立)。
非业务真源:余额真源仍在各服 mce 库,本表是供平台高效查询/对账的汇聚镜像(守数据所有权不变量)。
type EconomyLedgerEntry ¶
type EconomyLedgerEntry struct {
ID uint `gorm:"primaryKey" json:"id"`
// LedgerID mce 总账流水 ID(去重锚点,仅 node→zone 内唯一)。
LedgerID int64 `gorm:"column:ledger_id;not null;uniqueIndex:idx_ele_scope_ledger,priority:3" json:"ledgerId"`
// NodeUUID / InstanceUUID 事件来源(node→zone 聚合维度)。
NodeUUID string `` /* 128-byte string literal not displayed */
InstanceUUID string `gorm:"column:instance_uuid;type:varchar(64)" json:"instanceUuid"`
// ZoneID mce 区 ID。
ZoneID string `` /* 137-byte string literal not displayed */
// PlayerName 玩家名。
PlayerName string `gorm:"column:player_name;type:varchar(64);index:idx_ele_player,priority:2" json:"playerName"`
// Currency 货币 identifier;CurrencyID 为 mce Int 原值。
Currency string `gorm:"type:varchar(64)" json:"currency"`
CurrencyID int `gorm:"column:currency_id;default:0;not null" json:"currencyId"`
// EntryType 入账类型(DEPOSIT/WITHDRAW/CONSUME/REFUND/TRANSFER_IN/TRANSFER_OUT/ADJUST)。
EntryType string `gorm:"column:entry_type;type:varchar(32)" json:"entryType"`
// SignedAmount 带符号变更额(字符串承载 BigDecimal,正入负出)。
SignedAmount string `gorm:"column:signed_amount;type:varchar(64)" json:"signedAmount"`
// BalanceAfter 变更后余额(字符串承载 BigDecimal)。
BalanceAfter string `gorm:"column:balance_after;type:varchar(64)" json:"balanceAfter"`
// Seq mce 区内单调投递序号(排序/回放游标,非幂等键)。
Seq int64 `gorm:"default:0;not null" json:"seq"`
// OccurredAt 账务发生时间(epoch 毫秒)。
OccurredAt int64 `gorm:"column:occurred_at;default:0;not null;index:idx_ele_time" json:"occurredAt"`
// CreatedAt CP 落库时间。
CreatedAt time.Time `json:"createdAt"`
}
EconomyLedgerEntry 是经济变更/操作审计表:逐条经济变更的结构化留痕(FR-122,见 ADR-028)。
与通用 BusinessEvent 并存——envelope 是插件无关底座,本表是经济域**结构化专表**,把信封 payload 拆列 供高效查询/对账(按玩家/货币/区/时间维度)。按 (NodeUUID, ZoneID, LedgerID) 唯一去重(与 envelope 同源 dedupKey), 业务数据**不降采样、不丢**(区别于监控时序,ADR-028)。append-only,不随镜像覆盖。
type FileVersion ¶
type FileVersion struct {
ID uint `gorm:"primaryKey" json:"id"`
InstanceID uint `gorm:"not null;index:idx_file_version_instance_path" json:"instanceId"`
FilePath string `gorm:"type:varchar(512);not null;index:idx_file_version_instance_path" json:"filePath"`
ContentHash string `gorm:"type:char(64);not null;index" json:"contentHash"`
Content string `gorm:"type:longtext;not null" json:"-"`
Size int64 `gorm:"not null" json:"size"`
AuthorID uint `gorm:"index" json:"authorId"`
RollbackOfVersionID *uint `gorm:"index" json:"rollbackOfVersionId,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
FileVersion 通用文件版本快照记录(FR-051)。
与 InstanceConfigVersion(FR-031,仅限配置文件)共用「改前快照 + 列表 + diff + 回滚」 的版本机制,但适用于实例工作目录下的任意文件(含上传覆盖的二进制文件)。 二者刻意分表:配置版本带 schema/校验语义,通用文件版本只关心字节内容, 避免把二进制内容混入按文本语义设计的 instance_config_versions 表。
版本事实源在 Control Plane 数据库(架构不变量:Worker 不碰 DB), 文件本体仍归 Worker;快照内容随写入时机由 CP 先读旧内容后落库。
Content 以 base64 编码存储,保证二进制文件(jar/zip/图片等)也能无损快照与回滚; 不直接存原始字节是为了兼容 SQLite/MySQL 的文本列与现有 GORM string 字段约定。 RollbackOfVersionID 记录本次写入是否由回滚触发,指向被回滚的源版本,便于审计回滚链。
type Group ¶
type Group struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
Description string `gorm:"type:varchar(512)" json:"description"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Members []GroupMember `gorm:"foreignKey:GroupID" json:"members,omitempty"`
Quota *GroupQuota `gorm:"foreignKey:GroupID" json:"quota,omitempty"`
}
Group 用户组。
type GroupInstance ¶
type GroupInstance struct {
ID uint `gorm:"primaryKey" json:"id"`
GroupID uint `gorm:"not null;index" json:"groupId"`
InstanceID uint `gorm:"uniqueIndex;not null" json:"instanceId"`
CreatedAt time.Time `json:"createdAt"`
}
GroupInstance 实例与用户组的关联。
type GroupMember ¶
type GroupMember struct {
ID uint `gorm:"primaryKey" json:"id"`
GroupID uint `gorm:"not null;uniqueIndex:idx_group_user" json:"groupId"`
UserID uint `gorm:"not null;uniqueIndex:idx_group_user" json:"userId"`
Role GroupMemberRole `gorm:"default:0" json:"role"`
CreatedAt time.Time `json:"createdAt"`
Group Group `gorm:"foreignKey:GroupID" json:"-"`
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
}
GroupMember 组成员关联。
type GroupMemberRole ¶
type GroupMemberRole int
GroupMemberRole 组内角色。
const ( GroupMemberRoleMember GroupMemberRole = 0 // 普通成员 GroupMemberRoleAdmin GroupMemberRole = 1 // 组管理员 )
type GroupQuota ¶
type GroupQuota struct {
ID uint `gorm:"primaryKey" json:"id"`
GroupID uint `gorm:"uniqueIndex;not null" json:"groupId"`
MaxInstances int `gorm:"default:10" json:"maxInstances"`
MaxBots int `gorm:"default:50" json:"maxBots"`
MaxStorageMB int `gorm:"default:10240" json:"maxStorageMb"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
GroupQuota 组配额。
type Instance ¶
type Instance struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
NodeID uint `gorm:"not null;index" json:"nodeId"`
Name string `gorm:"type:varchar(128);not null;index" json:"name"`
Type InstanceType `gorm:"type:varchar(64);not null" json:"type"`
Role InstanceRole `gorm:"type:varchar(16);default:universal;index" json:"role"`
ProcessType ProcessType `gorm:"type:varchar(32);not null" json:"processType"`
Status InstanceStatus `gorm:"type:varchar(32);default:STOPPED;index" json:"status"`
// StatusReason 记录当前状态的原因,主要用于 CRASHED:异步委托(启动/停止)失败时写入具体错误
// (如「实例未绑定 JDK…」),供前端显示,不再让用户只见「崩溃」无因。正常状态推进时清空。
StatusReason string `gorm:"type:varchar(512)" json:"statusReason"`
StartCommand string `gorm:"type:varchar(1024);not null" json:"startCommand"`
JDKID uint `gorm:"index" json:"jdkId"`
JavaMajorVersion int `gorm:"index" json:"javaMajorVersion"`
LaunchSpec string `gorm:"type:text" json:"launchSpec"`
// ProvisionSpec 存一键搭建/代理搭建的原始请求(JSON),供损毁后「重建」复用参数重跑搭建(FR-342)。
// 仅经搭建入口创建的实例有值;手动/导入实例为空、不适用重建。
ProvisionSpec string `gorm:"type:text" json:"provisionSpec,omitempty"`
WorkDir string `gorm:"type:varchar(512)" json:"workDir"`
// WorkDirInPlace 就地导入标记(FR-302,见 ADR-069):工作目录为托管区外的原始绝对路径
// (ADR-007 系统分配原则的唯一合法例外)。删除实例时 CP 据此指示 Worker 跳过目录删除,
// 原目录永不清理(双保险之一,另一道是 Worker 托管区守卫)。
WorkDirInPlace bool `gorm:"default:false" json:"workDirInPlace"`
EnvVars string `gorm:"type:text" json:"envVars"` // JSON
// Image 是 docker 模式的容器镜像引用(如 itzg/minecraft-server:latest),仅 process_type=docker 使用(FR-078,ADR-019)。
Image string `gorm:"type:varchar(256)" json:"image"`
// ContainerID 记录 docker 模式实例最近一次运行的容器 ID(排障/展示用,运行态由 Worker 持有)。
ContainerID string `gorm:"type:varchar(64)" json:"containerId"`
// CPULimit 是 docker 模式的 CPU 核数上限(如 1.5),启动时注入容器 cgroup;0=不限制(FR-079,ADR-019)。
CPULimit float64 `gorm:"default:0" json:"cpuLimit"`
// MemLimitMB 是 docker 模式的内存上限(MiB),启动时注入容器 cgroup;0=不限制(FR-079,ADR-019)。
MemLimitMB int64 `gorm:"default:0" json:"memLimitMb"`
// DiskLimitMB 是 docker 模式的磁盘上限(MiB),仅持久化与展示,v1 不注入(依赖存储驱动)(FR-079)。
DiskLimitMB int64 `gorm:"default:0" json:"diskLimitMb"`
AutoStart bool `gorm:"default:false" json:"autoStart"`
AutoRestart bool `gorm:"default:true" json:"autoRestart"`
// Deprecated: RCON 已退役(FR-067,见 ADR-016)——治理改走 ServerProbe 探针。
// 列保留仅为迁移安全(不破坏既有库与历史实例数据),新实例不再写入、读取方不再使用。
RCONPort int `gorm:"default:0" json:"rconPort"`
RCONPassword string `gorm:"type:varchar(128)" json:"-"`
// ForwardingSecret 是 Velocity modern 转发的 forwarding secret(代理实例 provision 时生成)。
// 下发到所注册后端 paper 配置 + 跨代理一致校验复用;BungeeCord/Waterfall 不使用。参见 FR-035。
ForwardingSecret string `gorm:"type:varchar(128)" json:"-"`
// ProxyOnlineMode 代理是否向 Mojang 校验正版(true=正版网络,false=离线模式群组服)。
// 仅代理实例使用;持久化以便 SyncProxy 重新生成配置时保留选择(默认 true)。参见 FR-035。
ProxyOnlineMode bool `gorm:"default:true" json:"proxyOnlineMode"`
ServerPort int `gorm:"default:0" json:"serverPort"`
QueryPort int `gorm:"default:0" json:"queryPort"`
// ProbePort 是 ServerProbe 监控探针 /metrics 端口(系统分配,FR-010)。0 表示未部署探针。
ProbePort int `gorm:"default:0" json:"probePort"`
// ProbeVersionID 是实例显式选择的 ServerProbe 版本;0 表示继承所属 Worker 或全局默认(FR-409)。
ProbeVersionID uint `gorm:"default:0;index" json:"probeVersionId"`
PID int `gorm:"default:0" json:"pid"`
StartedAt *time.Time `json:"startedAt"`
CrashCount int `gorm:"default:0" json:"crashCount"`
Tags string `gorm:"type:text" json:"tags"` // JSON
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
Node Node `gorm:"foreignKey:NodeID" json:"node,omitempty"`
}
Instance 实例。
type InstanceConfigVersion ¶
type InstanceConfigVersion struct {
ID uint `gorm:"primaryKey" json:"id"`
InstanceID uint `gorm:"not null;index:idx_cfg_version_instance_file" json:"instanceId"`
FilePath string `gorm:"type:varchar(512);not null;index:idx_cfg_version_instance_file" json:"filePath"`
ContentHash string `gorm:"type:char(64);not null;index" json:"contentHash"`
Content string `gorm:"type:longtext;not null" json:"content"`
Message string `gorm:"type:varchar(255)" json:"message"`
AuthorID uint `gorm:"index" json:"authorId"`
RollbackOfVersionID *uint `gorm:"index" json:"rollbackOfVersionId,omitempty"`
RollbackedByVersionID *uint `gorm:"index" json:"rollbackedByVersionId,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
InstanceConfigVersion 配置版本记录。 同一实例的同一文件可保存多条历史版本(无联合唯一约束)。 RollbackOfVersionID 记录本次写入是否由回滚触发,指向被回滚的源版本。 RollbackedByVersionID 指向"回滚此版本"产生的新版本(若存在),便于反向追溯回滚链。
type InstanceCrashSnapshot ¶
type InstanceCrashSnapshot struct {
ID uint `gorm:"primaryKey" json:"id"`
InstanceID uint `gorm:"not null;index" json:"instanceId"`
// OccurredAt 崩溃发生时刻(Worker 侧时钟)。
OccurredAt time.Time `json:"occurredAt"`
// ExitCode 进程退出码;无法获知(Wait 出错/容器 Wait 错误)时为 -1。
ExitCode int `json:"exitCode"`
// Signal 终止信号名(Unix,如 killed/terminated);Windows / 非信号退出为空。
Signal string `gorm:"type:varchar(32)" json:"signal"`
// DurationMs 本次运行时长(毫秒)。
DurationMs int64 `json:"durationMs"`
// TailOutput 崩溃前终端尾部输出(Worker 侧截取,≤200 行 / 64KB)。
TailOutput string `gorm:"type:text" json:"tailOutput"`
CreatedAt time.Time `json:"createdAt"`
}
InstanceCrashSnapshot 实例崩溃快照(FR-313):进程非正常退出的现场留存。 Worker 在进程崩溃时经 gRPC ReportCrashSnapshot 上报,CP 持久化并按实例滚动保留 最近 5 条(写死不做配置,见 spec §6);实例删除时级联清理。
type InstanceGroupMember ¶
type InstanceGroupMember struct {
ID uint `gorm:"primaryKey" json:"id"`
GroupID uint `gorm:"not null;index;uniqueIndex:idx_igmember_group_inst" json:"groupId"`
InstanceID uint `gorm:"not null;index;uniqueIndex:idx_igmember_group_inst" json:"instanceId"`
CreatedAt time.Time `json:"createdAt"`
}
InstanceGroupMember 是分组节点与实例的 M:N 关联(一个实例可属多个组织分组)。 UNIQUE(group_id, instance_id) 保证同组内不重复;删组只硬删成员关系、不触及实例。
type InstanceGroupNode ¶
type InstanceGroupNode struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
// ParentID 父节点 ID,NULL 表示根分组;自引用邻接表表达树。建索引便于按父查子。
ParentID *uint `gorm:"index" json:"parentId,omitempty"`
// Sort 同级排序权重(升序),由 service 维护;前端可拖拽改序。
Sort int `gorm:"default:0" json:"sort"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
InstanceGroupNode 是「实例组织分组树」的一个节点(ADR-033 实例组织分组树)。 多级嵌套用自引用 ParentID 邻接表表达(NULL=根);与用户组(ADR-004 RBAC/配额)、 网络群组(ADR-007 proxy↔backend 部署)三者正交——仅供人为组织归类、折叠、批量运维, 不承载权限/配额,也不表达运行时拓扑。删非空节点默认拒删(service 校验),不级联删实例。
func (*InstanceGroupNode) BeforeCreate ¶
func (n *InstanceGroupNode) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成 UUID。
type InstanceRole ¶
type InstanceRole string
InstanceRole 实例在 MC 群组服拓扑中的角色(ADR-007)。
const ( // InstanceRoleBackend 后端子服(Paper/Spigot/Purpur),可注册进多个代理。 InstanceRoleBackend InstanceRole = "backend" // InstanceRoleProxy 代理(BungeeCord/Waterfall/Velocity),聚合多个后端。 InstanceRoleProxy InstanceRole = "proxy" // InstanceRoleUniversal 通用实例(默认;非群组服角色,保留自由命令)。 InstanceRoleUniversal InstanceRole = "universal" )
type InstanceStatus ¶
type InstanceStatus string
InstanceStatus 实例状态。
const ( InstanceStatusStopped InstanceStatus = "STOPPED" InstanceStatusStarting InstanceStatus = "STARTING" InstanceStatusRunning InstanceStatus = "RUNNING" InstanceStatusStopping InstanceStatus = "STOPPING" InstanceStatusCrashed InstanceStatus = "CRASHED" // InstanceStatusDamaged 损毁(FR-342):一键搭建/代理搭建过程中任一阶段失败进入此态, // 原始搭建参数(ProvisionSpec)保留,可「重建」复用参数重跑搭建;损毁实例不可直接启动。 InstanceStatusDamaged InstanceStatus = "DAMAGED" )
type InstanceType ¶
type InstanceType string
InstanceType 实例类型。
const ( InstanceTypeMinecraftJava InstanceType = "minecraft_java" InstanceTypeGeneric InstanceType = "generic" )
type LogEntry ¶
type LogEntry struct {
ID uint `gorm:"primaryKey" json:"id"`
// Source 区分实例日志与平台日志,过滤维度之一。
Source LogSource `gorm:"type:varchar(16);not null;index:idx_logs_source_time,priority:1" json:"source"`
// Level 日志级别,过滤维度之一。
Level LogLevel `gorm:"type:varchar(8);not null;index:idx_logs_level_time,priority:1" json:"level"`
// InstanceID 实例主键(实例日志非零);与 Time 组成复合索引承接按实例时间检索。
InstanceID uint `gorm:"index:idx_logs_instance_time,priority:1" json:"instanceId"`
// InstanceUUID 实例 UUID 冗余列,采集侧仅持有 UUID 时直接落库。
InstanceUUID string `gorm:"type:char(36);index" json:"instanceUuid"`
// NodeID 节点主键(实例/Worker 日志非零);与 Time 组成复合索引承接按节点时间检索。
NodeID uint `gorm:"index:idx_logs_node_time,priority:1" json:"nodeId"`
// Stream 原始流名(stdout/stderr/""),仅实例日志使用,辅助前端区分。
Stream string `gorm:"type:varchar(8)" json:"stream,omitempty"`
// Message 日志正文(已去除行尾换行)。关键字检索在此列上做 DB 侧 LIKE。
Message string `gorm:"type:text;not null" json:"message"`
// Time 日志产生时间(采集/写入时刻)。所有复合索引的次序列,统一按时间倒序检索。
Time time.Time `` /* 178-byte string literal not displayed */
}
LogEntry 是单条持久化日志(实例运行日志或平台运行日志)。
这是高写入、按条件检索的表,因此刻意不内嵌外键关联对象(不像 AuditLog 预加载 User):
- 以 InstanceID/NodeID 的整型外键 + 复合索引承接「按实例/节点 + 时间」的高频过滤;
- 关键字检索走 Message 上的 DB 谓词(LIKE),不在应用层全量序列化(FR-049/FR-050);
- InstanceUUID 冗余保存,便于采集侧(仅持有 UUID 的 Worker 事件流)直接落库而不必反查。
归档与保留由 LogService 负责:超阈值的旧条目滚动落盘到数据根 var/log 后从表中清理 (参见 ADR-005 单二进制不引 ELK、ADR-010 数据根布局)。
type LogLevel ¶
type LogLevel string
LogLevel 日志级别。实例 stdout 默认归为 info、stderr 归为 error;平台日志沿用 slog 级别。
type LogSource ¶
type LogSource string
LogSource 日志来源类别。
const ( // LogSourceInstance 实例运行日志(采集自 Worker 转发的进程 stdout/stderr)。 LogSourceInstance LogSource = "instance" // LogSourceControlPlane 平台 Control Plane 自身结构化日志。 LogSourceControlPlane LogSource = "control_plane" // LogSourceWorker 平台 Worker Node 自身结构化日志(经 gRPC 上报或本地直采,预留)。 LogSourceWorker LogSource = "worker" )
type MetricRollup1h ¶
type MetricRollup1h struct {
ID uint `gorm:"primaryKey" json:"id"`
SeriesID uint `gorm:"not null;index:idx_metric_1h_series_bucket,priority:1" json:"seriesId"`
BucketTS time.Time `gorm:"not null;index:idx_metric_1h_series_bucket,priority:2" json:"bucketTs"`
Avg float64 `json:"avg"`
Min float64 `json:"min"`
Max float64 `json:"max"`
Last float64 `json:"last"`
Count int `json:"count"`
}
MetricRollup1h 1 小时降采样档(留 ≥1 年)。结构同 5m 档,独立表便于按 TTL 清理。
type MetricRollup5m ¶
type MetricRollup5m struct {
ID uint `gorm:"primaryKey" json:"id"`
SeriesID uint `gorm:"not null;index:idx_metric_5m_series_bucket,priority:1" json:"seriesId"`
BucketTS time.Time `gorm:"not null;index:idx_metric_5m_series_bucket,priority:2" json:"bucketTs"`
Avg float64 `json:"avg"`
Min float64 `json:"min"`
Max float64 `json:"max"`
Last float64 `json:"last"`
Count int `json:"count"`
}
MetricRollup5m 5 分钟降采样档(留 ~30d)。仅在桶内有非空样本时生成,缺测为缺桶。
type MetricSampleRaw ¶
type MetricSampleRaw struct {
ID uint `gorm:"primaryKey" json:"id"`
SeriesID uint `gorm:"not null;index:idx_metric_raw_series_ts,priority:1" json:"seriesId"`
TS time.Time `gorm:"not null;index:idx_metric_raw_series_ts,priority:2" json:"ts"`
Value *float64 `json:"value"`
}
MetricSampleRaw 原始样本(30s 粒度,留 ~48h)。 Value 为指针:nil 表示缺测(采集源不可达),查询时渲染为断点,不补假值。
type MetricScope ¶
type MetricScope string
MetricScope 时序指标的作用域维度(ADR-013)。
const ( // MetricScopeNode 节点级指标(CPU/内存/磁盘/网络),来自心跳。 MetricScopeNode MetricScope = "node" // MetricScopeInstance 实例级指标,来自 ServerProbe(TPS/MSPT/堆/线程/CPU/uptime)。 MetricScopeInstance MetricScope = "instance" // MetricScopeWorld 实例下单个世界的负载,来自 ServerProbe serverprobe_world_*。 MetricScopeWorld MetricScope = "world" )
type MetricSeries ¶
type MetricSeries struct {
ID uint `gorm:"primaryKey" json:"id"`
// NodeUUID 所属节点。
NodeUUID string `gorm:"type:varchar(64);not null;uniqueIndex:idx_metric_series_identity,priority:1" json:"nodeUuid"`
// InstanceID 实例级/世界级序列才有;节点级为空字符串。
InstanceID string `gorm:"type:varchar(64);not null;default:'';uniqueIndex:idx_metric_series_identity,priority:2" json:"instanceId"`
// Scope 作用域:node / instance / world。
Scope MetricScope `gorm:"type:varchar(16);not null;uniqueIndex:idx_metric_series_identity,priority:3" json:"scope"`
// MetricKey 指标键,见上方常量。
MetricKey string `gorm:"type:varchar(48);not null;uniqueIndex:idx_metric_series_identity,priority:4" json:"metricKey"`
// World scope=world 时的世界名,其余为空字符串。
World string `gorm:"type:varchar(64);not null;default:'';uniqueIndex:idx_metric_series_identity,priority:5" json:"world"`
// Unit 单位:pct/bytes/bytes_per_sec/count/ms/tps/seconds。
Unit string `gorm:"type:varchar(16)" json:"unit"`
CreatedAt time.Time `json:"createdAt"`
LastSeenAt time.Time `json:"lastSeenAt"`
}
MetricSeries 时序序列的身份维度表(ADR-013)。 一条序列 = (node_uuid, instance_id?, scope, metric_key, world?); 样本/卷积表只引用 series_id,对新增指标键与动态世界天然可扩展。
type Network ¶
type Network struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
// Name 群组名,唯一性由 service 在未软删记录间校验(不加 DB 唯一索引,便于删除后重用同名)。
Name string `gorm:"type:varchar(128);not null;index" json:"name"`
Description string `gorm:"type:varchar(512)" json:"description"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
Network 是 MC 群组服的非独占软标签(ADR-007):仅供 UI 分组/筛选/批量运维, 一个实例可属于多个 network;真实路由只由 server_registrations 驱动,network 不做归属容器。 删除 network 不影响成员实例与其 server_registrations。
type NetworkMember ¶
type NetworkMember struct {
ID uint `gorm:"primaryKey" json:"id"`
NetworkID uint `gorm:"not null;index;uniqueIndex:idx_netmember_net_inst" json:"networkId"`
InstanceID uint `gorm:"not null;index;uniqueIndex:idx_netmember_net_inst" json:"instanceId"`
CreatedAt time.Time `json:"createdAt"`
}
NetworkMember 群组成员关联(Network M:N Instance)。 删除 network 时一并硬删除其成员关系,但不触及实例与 server_registrations。
type Node ¶
type Node struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
// Name 节点名(人类可读标签)。身份由 UUID 锚定(见 ADR-039),name 仅为可变标签,
// 但活跃节点间名字唯一:唯一性由 database.AutoMigrate 建的「部分唯一索引」
// (仅约束 deleted_at IS NULL 的活跃行)强制,软删除节点可释放其名供新节点复用。
Name string `gorm:"type:varchar(128);not null" json:"name"`
Host string `gorm:"type:varchar(256);not null" json:"host"`
GRPCPort int `gorm:"column:grpc_port;not null" json:"grpcPort"`
WSPort int `gorm:"not null" json:"wsPort"`
Secret string `gorm:"type:varchar(128);not null" json:"-"`
Status NodeStatus `gorm:"default:0" json:"status"`
OS string `gorm:"type:varchar(64)" json:"os"`
Arch string `gorm:"type:varchar(32)" json:"arch"`
CPUCores int `json:"cpuCores"`
MemoryMB int64 `json:"memoryMb"`
DiskTotalMB int64 `json:"diskTotalMb"`
CPUUsage float32 `gorm:"default:0" json:"cpuUsage"`
MemoryUsage float32 `gorm:"default:0" json:"memoryUsage"`
DiskUsage float32 `gorm:"default:0" json:"diskUsage"`
// Maintenance 维护模式(cordon)标记。为 true 时禁止新实例调度/分配到本节点,
// 与 Status(在线/离线,由心跳驱动)正交:节点可同时「在线 + 维护中」。
// 参见 FR-048。
Maintenance bool `gorm:"default:false" json:"maintenance"`
MemoryUsedMB int64 `gorm:"default:0" json:"memoryUsedMb"`
DiskUsedMB int64 `gorm:"default:0" json:"diskUsedMb"`
NetworkBytesSent int64 `gorm:"default:0" json:"networkBytesSent"`
NetworkBytesRecv int64 `gorm:"default:0" json:"networkBytesRecv"`
// LoadAvg1 节点 1 分钟 load average(FR-062,心跳驱动)。
LoadAvg1 float64 `gorm:"default:0" json:"loadAvg1"`
// ManagedRuntimeObservedAt 是 Worker 随已认证 Heartbeat 上报受管运行时快照的实际观测时间。
// 运行时不可用或旧 Worker 未上报时,相关字段必须清空,避免陈旧值被当成当前资源。
ManagedRuntimeObservedAt *time.Time `json:"managedRuntimeObservedAt"`
WorkerProcessRSSBytes *int64 `json:"workerProcessRssBytes"`
WorkerProcessCPUPct *float64 `json:"workerProcessCpuPct"`
BotWorkerRSSBytes *int64 `json:"botWorkerRssBytes"`
BotWorkerCPUPct *float64 `json:"botWorkerCpuPct"`
BotActiveCount *int32 `json:"botActiveCount"`
BotConnectingCount *int32 `json:"botConnectingCount"`
BotEventLoopP95MS *float64 `json:"botEventLoopP95Ms"`
BotCapacityMax *int32 `json:"botCapacityMax"`
BotAvailable bool `gorm:"default:false" json:"botAvailable"`
// ProxyMode 节点出站代理模式(FR-185,见 ADR-043):
// inherit(默认)= 用平台全局默认代理(settings DB > control-plane.yml > env);
// custom = 用本节点自定义 ProxyURL/ProxyNoProxy。
// CP 据此算每节点期望代理经心跳响应下发,Worker 运行时重建出站 client(免登机器改 worker.yml)。
ProxyMode string `gorm:"type:varchar(16);default:inherit" json:"proxyMode"`
// ProxyURL 节点自定义代理地址(仅 ProxyMode=custom 有效;含凭据,API 响应/日志脱敏)。
ProxyURL string `gorm:"type:varchar(512)" json:"-"`
// ProxyNoProxy 节点自定义免代理列表(逗号分隔,仅 ProxyMode=custom 有效)。
ProxyNoProxy string `gorm:"type:varchar(1024)" json:"proxyNoProxy"`
LastHeartbeat *time.Time `json:"lastHeartbeat"`
// RuntimeSyncedAt 上次运行时库存从 Worker 同步成功的时间(FR-301)。
// JDKService.syncFromWorker 成功即刷新(含 JDK 面板隐式同步与运行时资产页手动刷新);
// nil = 从未同步。运行时资产页据此显示「上次同步 <相对时间>」并识别陈旧节点。
RuntimeSyncedAt *time.Time `json:"runtimeSyncedAt"`
// ProbeVersionID 是该 Worker 后续新实例的 ServerProbe 默认版本;0 表示继承全局默认(FR-409)。
ProbeVersionID uint `gorm:"default:0;index" json:"probeVersionId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
// TunnelConnected 该节点当前是否有活跃反向隧道(FR-281,见 ADR-066)。
// 运行态字段不落库(gorm:"-"),由 NodeService 在响应时据 TunnelRegistry 填充:
// true=指令经隧道下发(NAT/内网节点可用),false=直拨回退(老 worker/隧道重建窗口)。
TunnelConnected bool `gorm:"-" json:"tunnelConnected"`
}
Node Worker Node 节点。
type NodeEnrollToken ¶
type NodeEnrollToken struct {
ID uint `gorm:"primaryKey" json:"id"`
// TokenHash enrollment token 明文的 SHA-256 十六进制小写。库内不存明文。
TokenHash string `gorm:"column:token_hash;type:char(64);uniqueIndex;not null" json:"-"`
// TokenPrefix 明文前缀(如 jmet_ab12),仅供列表识别,不足以重建 token。
TokenPrefix string `gorm:"column:token_prefix;type:varchar(16);not null" json:"tokenPrefix"`
// NodeName 预设节点名;留空则注册时以 Worker 上报名生效。
NodeName string `gorm:"type:varchar(128)" json:"nodeName"`
// ExpiresAt 过期时间;到期即校验失败。
ExpiresAt time.Time `gorm:"not null" json:"expiresAt"`
// Used 是否已消费(一次性);true 即不可再用于注册。
Used bool `gorm:"default:false;index;not null" json:"used"`
// UsedAt 消费时间。
UsedAt *time.Time `json:"usedAt"`
// UsedByNode 消费该 token 注册成功的节点 UUID(审计/追溯用)。
UsedByNode string `gorm:"type:char(36)" json:"usedByNode"`
// Revoked 吊销标记(运营主动作废未消费 token);true 即校验失败。
Revoked bool `gorm:"default:false;not null" json:"revoked"`
CreatedAt time.Time `json:"createdAt"`
// CreatedBy 签发该 token 的平台管理员用户 ID(审计用)。
CreatedBy uint `json:"createdBy"`
}
NodeEnrollToken 节点 enrollment token:新增 Worker Node 时的一次性、限时准入凭据(FR-080,见 ADR-020)。
信任模型同构 FR-086 拉取密钥与 JM 既有运行时密钥惯例:落库只存明文的 SHA-256 哈希, 明文仅签发时一次性返回、不可二次读取。Worker 注册时经 gRPC metadata 携带明文, CP 在 Register 内校验(存在 + 未过期 + 未消费 + 未吊销)并原子标记 Used(一次性)。 enrollment token 只对「新节点首次落库」设门槛,已存在节点重注册不强制 token(ADR-020 §1)。
type NodeJDK ¶
type NodeJDK struct {
ID uint `gorm:"primaryKey" json:"id"`
NodeID uint `gorm:"not null;index" json:"nodeId"`
Vendor string `gorm:"type:varchar(64);not null" json:"vendor"`
MajorVersion int `gorm:"not null;index" json:"majorVersion"`
Version string `gorm:"type:varchar(64);not null" json:"version"`
Arch string `gorm:"type:varchar(32);not null" json:"arch"`
Path string `gorm:"type:varchar(512);not null" json:"path"`
Managed bool `gorm:"default:false" json:"managed"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
NodeJDK 节点托管或登记的 JDK。
type NodePMConfig ¶
type NodePMConfig struct {
ID uint `gorm:"primaryKey" json:"id"`
NodeID uint `gorm:"not null;uniqueIndex" json:"nodeId"`
// PM 包管理器偏好:npm(默认)/ pnpm / yarn。pnpm/yarn 经 corepack enable 激活。
PM string `gorm:"type:varchar(16);not null;default:npm" json:"pm"`
// Registries JSON 数组([]PMRegistry):默认源用 scope="" 那条,其余为 @scope 域源。
Registries string `gorm:"type:text" json:"-"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
NodePMConfig 节点级包管理器与 registry 配置(FR-306,节点单例)。 承载 corepack 激活的 PM 偏好与多 registry(默认源 + @scope 域源 + 可选凭据); registries 以 JSON 数组存 []PMRegistry;token 入库明文(节点级配置密级同 proxy.url), 出参与日志脱敏。被 FR-307 全局包管理 / FR-308 bot-worker 依赖装全局消费。
type NodeRuntime ¶
type NodeRuntime struct {
ID uint `gorm:"primaryKey" json:"id"`
NodeID uint `gorm:"not null;index;uniqueIndex:uniq_node_runtime_type_path" json:"nodeId"`
// Type 运行时类型(nodejs / python 预留;jdk 不落本表)。
Type string `gorm:"type:varchar(16);not null;uniqueIndex:uniq_node_runtime_type_path" json:"type"`
// Name 展示名(如 "Node.js 22")。
Name string `gorm:"type:varchar(64);not null" json:"name"`
// Version 完整版本(如 "22.17.0")。
Version string `gorm:"type:varchar(64);not null" json:"version"`
// Major 主版本(如 22),排序/选择用。
Major int `gorm:"not null;index" json:"major"`
Arch string `gorm:"type:varchar(32)" json:"arch"`
Path string `gorm:"type:varchar(512);not null;uniqueIndex:uniq_node_runtime_type_path" json:"path"`
// Managed 是否平台托管(波1 登记均为外部发现 false;FR-299 安装器落 true)。
Managed bool `gorm:"default:false" json:"managed"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
NodeRuntime 节点登记/托管的非 JDK 运行时(FR-298 节点运行时库)。 JDK 沿用 node_jdks 表不迁移(实例外键 instances.jdk_id 零变更);本表承载 nodejs / python(预留)等其它类型,读侧与 node_jdks 拼成统一 Runtime 视图。
type NodeStatus ¶
type NodeStatus int
NodeStatus 节点状态。
const ( NodeStatusOffline NodeStatus = 0 // 离线 NodeStatusOnline NodeStatus = 1 // 在线 NodeStatusStarting NodeStatus = 2 // 启动中 )
type Notification ¶
type Notification struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"index;not null" json:"userId"` // 收件人
Level NotificationLevel `gorm:"type:varchar(16);not null;default:info" json:"level"`
Title string `gorm:"type:varchar(256);not null" json:"title"`
Body string `gorm:"type:text" json:"body"`
// TaskID 关联任务的业务 ID(可空,非任务类通知留空)。
TaskID string `gorm:"type:varchar(64);index" json:"taskId,omitempty"`
// ReadAt 已读时间,nil 表示未读。
ReadAt *time.Time `json:"readAt,omitempty"`
CreatedAt time.Time `json:"createdAt"`
}
Notification 站内信。一条投递给某用户的消息,可关联到产生它的任务(见 ADR-040)。
type NotificationLevel ¶
type NotificationLevel string
NotificationLevel 站内信级别。
const ( // NotificationLevelInfo 一般信息。 NotificationLevelInfo NotificationLevel = "info" // NotificationLevelSuccess 成功通知(如任务完成)。 NotificationLevelSuccess NotificationLevel = "success" // NotificationLevelWarning 警告。 NotificationLevelWarning NotificationLevel = "warning" // NotificationLevelError 失败 / 错误通知(如任务失败)。 NotificationLevelError NotificationLevel = "error" )
type OrphanRuntime ¶ added in v0.20.0
type OrphanRuntime struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
NodeUUID string `gorm:"type:char(36);not null;index:idx_orphan_node_inst,priority:1" json:"nodeUuid"`
InstanceUUID string `gorm:"type:char(36);not null;index:idx_orphan_node_inst,priority:2" json:"instanceUuid"`
// WorkerState 最近一次心跳上报的状态摘要(RUNNING/STOPPED/…)。
WorkerState string `gorm:"type:varchar(32)" json:"workerState"`
// WorkerPID 最近一次心跳上报的进程 PID(0=未知)。
// 列名显式 worker_pid:避免 GORM 把 PID 缩写蛇形化为 worker_p_id(同 grpc_port 先例)。
WorkerPID int `gorm:"column:worker_pid;default:0" json:"workerPid"`
Status OrphanRuntimeStatus `gorm:"type:varchar(32);not null;index;default:pending" json:"status"`
FirstSeenAt time.Time `gorm:"not null;index" json:"firstSeenAt"`
LastSeenAt time.Time `gorm:"not null" json:"lastSeenAt"`
// DisposedAt 处置完成时刻(自动或手动)。
DisposedAt *time.Time `json:"disposedAt,omitempty"`
// DisposeMode auto | manual;未处置为空。
DisposeMode string `gorm:"type:varchar(16)" json:"disposeMode,omitempty"`
// LastError 最近一次自动/手动处置失败原因(成功后清空)。
LastError string `gorm:"type:varchar(512)" json:"lastError,omitempty"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
OrphanRuntime 记录 Worker 有、CP 无实例记录的无主运行时(FR-326 反向对账)。 不重建业务实例,仅跟踪发现/宽限/处置;处置后终态保留供列表与审计对照。
func (*OrphanRuntime) BeforeCreate ¶ added in v0.20.0
func (o *OrphanRuntime) BeforeCreate(tx *gorm.DB) error
BeforeCreate 创建前自动生成 UUID。
type OrphanRuntimeStatus ¶ added in v0.20.0
type OrphanRuntimeStatus string
OrphanRuntimeStatus 无主运行时处置状态(FR-326)。
const ( // OrphanRuntimePending 首次发现,宽限观察中。 OrphanRuntimePending OrphanRuntimeStatus = "pending" // OrphanRuntimeConfirmed 宽限期已过,待自动/手动处置(auto_dispose 关时停在此态)。 OrphanRuntimeConfirmed OrphanRuntimeStatus = "confirmed" // OrphanRuntimeDisposed 已下发并完成处置(进程停、Worker 本地运行态已清)。 OrphanRuntimeDisposed OrphanRuntimeStatus = "disposed" // OrphanRuntimeCancelled 宽限期内 CP 又出现对应实例记录,取消处置。 OrphanRuntimeCancelled OrphanRuntimeStatus = "cancelled" )
type PMRegistry ¶
type PMRegistry struct {
Name string `json:"name"` // 展示名(可选)
URL string `json:"url"` // http(s) registry 地址
Scope string `json:"scope"` // 空=默认源;非空=@<scope> 域源
Token string `json:"token"` // 可选凭据(出参脱敏)
}
PMRegistry 单条 registry 配置。scope 为空表示默认 registry;非空为 @scope 域源(不含 @ 前缀由前端约定)。 Token 为可选凭据(写入 .npmrc 的 _authToken),API 出参脱敏。
type PlatformSetting ¶
type PlatformSetting struct {
// Key 配置键,与 SettingsService 白名单一致(如 log.level、graceful_stop.timeout)。
Key string `gorm:"type:varchar(128);primaryKey" json:"key"`
// Value 覆盖值的文本表示(按键各自的语义解析,如 duration 文本、整数文本)。
Value string `gorm:"type:text" json:"value"`
UpdatedAt time.Time `json:"updatedAt"`
}
PlatformSetting 平台配置的 DB 覆盖项(FR-063 / ADR-015)。
只存「被显式覆盖过的白名单键」:未覆盖的键不落库,沿用 env/YAML 基线。 生效优先级 DB 覆盖 > 环境变量 > YAML 默认,由 SettingsService 解析有效配置时叠加。
type ProcessMetricSnapshot ¶
type ProcessMetricSnapshot struct {
ID uint `gorm:"primaryKey" json:"id"`
// NodeUUID 所属节点。
NodeUUID string `gorm:"type:varchar(64);not null;index:idx_process_metric_node_sampled,priority:1" json:"nodeUuid"`
// InstanceUUID 受管实例 UUID。
InstanceUUID string `gorm:"type:varchar(64);not null;index:idx_process_metric_instance_sampled,priority:1" json:"instanceUuid"`
// PID 显式列名 pid:避免 GORM 把 PID 缩写蛇形化为 p_id,与 managedProcessHistory 的
// WHERE pid = ? 查询对齐(真机验收 FR-407 抓到:SQL logic error: no such column: pid)。
PID int32 `gorm:"column:pid;not null" json:"pid"`
Name string `gorm:"type:varchar(128)" json:"name"`
CPUPercent float64 `json:"cpuPercent"`
RSSBytes uint64 `json:"rssBytes"`
ReadBytesPerSec uint64 `json:"readBytesPerSec"`
WriteBytesPerSec uint64 `json:"writeBytesPerSec"`
User string `gorm:"type:varchar(128)" json:"user"`
CommandSummary string `gorm:"type:varchar(160)" json:"commandSummary"`
SampledAt time.Time `` /* 134-byte string literal not displayed */
CreatedAt time.Time `json:"createdAt"`
}
ProcessMetricSnapshot 受管实例进程 TOPN 短期快照(FR-170)。
type ProcessType ¶
type ProcessType string
ProcessType 启动方式。
const ( ProcessTypeDirect ProcessType = "direct" ProcessTypeDaemon ProcessType = "daemon" ProcessTypeDocker ProcessType = "docker" ProcessTypeRCON ProcessType = "rcon" )
type Schedule ¶
type Schedule struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
InstanceID uint `gorm:"not null;index" json:"instanceId"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
CronExpr string `gorm:"type:varchar(64);not null" json:"cronExpr"`
Action string `gorm:"type:varchar(32);not null" json:"action"` // start, stop, restart, command, backup
Payload string `gorm:"type:text" json:"payload"` // JSON: command text, etc.
Enabled bool `gorm:"default:true" json:"enabled"`
LastRun *time.Time `json:"lastRun"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
Schedule 定时任务。
type ScheduleExecutionLog ¶
type ScheduleExecutionLog struct {
ID uint `gorm:"primaryKey" json:"id"`
ScheduleID uint `gorm:"not null;index" json:"scheduleId"`
Action string `gorm:"type:varchar(32);not null" json:"action"`
Status ScheduleLogStatus `gorm:"type:varchar(16);not null" json:"status"`
Error string `gorm:"type:text" json:"error"`
StartedAt time.Time `json:"startedAt"`
FinishedAt time.Time `json:"finishedAt"`
Schedule Schedule `gorm:"foreignKey:ScheduleID" json:"schedule,omitempty"`
}
ScheduleExecutionLog 定时任务执行日志。
func (*ScheduleExecutionLog) BeforeCreate ¶
func (l *ScheduleExecutionLog) BeforeCreate(tx *gorm.DB) error
BeforeCreate 预留钩子。
type ScheduleLogStatus ¶
type ScheduleLogStatus string
ScheduleLogStatus 定时任务执行状态。
const ( ScheduleLogStatusSuccess ScheduleLogStatus = "success" ScheduleLogStatusFailed ScheduleLogStatus = "failed" )
type SelfUpdateCheckCache ¶
type SelfUpdateCheckCache struct {
// ID 固定为 1:本表为单行覆盖式缓存,不按时间累积多行。
ID uint `gorm:"primaryKey" json:"id"`
// ResultJSON 是上次成功 CheckResult 的 JSON 序列化(含 latestVersion/source/notes/各组件状态)。
ResultJSON string `gorm:"type:text" json:"-"`
// Source 冗余存更新源标识(github:owner/repo@channel | feed),便于诊断不必解 blob。
Source string `gorm:"type:varchar(255)" json:"source"`
// CheckedAt 该次成功检查的时刻(UTC),供前端展示「上次检查:<相对时间>」。
CheckedAt time.Time `json:"checkedAt"`
}
SelfUpdateCheckCache 持久化最近一次「成功」检查更新的结果(FR-186,增强 FR-182/FR-081)。
仅一行(ID 固定 1 单行表):每次 live 检查成功后 upsert 覆盖。整段 CheckResult 序列化为 JSON blob 存 ResultJSON,而非拆字段——CheckResult 随版本演进加字段时无需迁移,反序列化 缺字段自然降级(见 spec §6 风险)。进系统更新页直接读此缓存即时回显,后台再静默触发 live 刷新; 刷新失败保留旧缓存(不清行),页面据 CheckedAt 标注「上次检查时间」。
type ServerRegistration ¶
type ServerRegistration struct {
ID uint `gorm:"primaryKey" json:"id"`
// ProxyID 代理实例 ID(role=proxy)。
ProxyID uint `gorm:"not null;index;uniqueIndex:idx_reg_proxy_alias" json:"proxyId"`
// BackendID 后端实例 ID(role=backend)。
BackendID uint `gorm:"not null;index" json:"backendId"`
// Alias 在该代理 servers{} 中的本地名([a-z0-9_-]{1,64}),同一代理内唯一。
Alias string `gorm:"type:varchar(64);not null;uniqueIndex:idx_reg_proxy_alias" json:"alias"`
// Priority try/优先级顺序,小值优先。
Priority int `gorm:"default:0" json:"priority"`
// ForcedHost 可选 forced-host 域名 → 该后端。
ForcedHost string `gorm:"type:varchar(255)" json:"forcedHost"`
// Restricted Velocity restricted:仅可经 forced-host/命令访问。
Restricted bool `gorm:"default:false" json:"restricted"`
// Enabled 是否启用(写入代理配置时跳过 disabled)。
Enabled bool `gorm:"default:true" json:"enabled"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
ServerRegistration 表示一个后端子服注册进一个代理(proxy↔backend 的 M:N,ADR-007)。 每条注册携带「代理内本地属性」:在该代理 servers{} 中的 alias、try/优先级、forced-host、restricted。 同一 backend 可注册进多个 proxy;同一代理内 alias 唯一。
本模型只承载关系数据;将注册「写入代理配置 + Velocity secret 下发」属 FR-035。
type Task ¶
type Task struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"type:varchar(64);uniqueIndex;not null" json:"taskId"`
NodeID uint `gorm:"index" json:"nodeId"`
Kind string `gorm:"type:varchar(64);not null;index" json:"kind"`
// InstanceID 关联实例(provision/import/clone 等实例级长操作任务用,FR-319/FR-323);0=无关联。
// 启动闸据此拦截「工作目录尚未就绪就点启动」的实例(在途任务未终态即拒启)。
InstanceID uint `gorm:"index" json:"instanceId"`
// State 见 TaskState;以字符串存储便于跨进程一致。
State TaskState `gorm:"type:varchar(16);not null;default:pending;index" json:"state"`
Progress int `gorm:"not null;default:0" json:"progress"` // 0~100
Title string `gorm:"type:varchar(256)" json:"title"`
Detail string `gorm:"type:varchar(1024)" json:"detail"` // 发起参数摘要
Error string `gorm:"type:text" json:"error"` // 失败原因(仅 failed)
Result string `gorm:"type:text" json:"result"` // 成功结果 JSON(如安装出的 JDK 信息)
// CancelRequested 标记用户已请求强制停止(FR-227):CP 据此每拍经心跳向节点下发 cancel_task_ids,
// 直到 Worker 确认中断并上报 canceled 终态。pending 未起 / 节点离线时直接置 canceled、不设此标记。
CancelRequested bool `gorm:"not null;default:false" json:"cancelRequested"`
// CreatedBy 发起用户 ID,用于归属隔离与完成站内信收件人(0=系统)。
CreatedBy uint `gorm:"index" json:"createdBy"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
Task 一条长耗时跨进程任务(如 JDK 安装)。 task_id 为业务唯一键(UUID),Worker 经心跳上报进度时据此 upsert(见 ADR-040)。
type TaskLog ¶
type TaskLog struct {
ID uint `gorm:"primaryKey" json:"id"`
TaskID string `gorm:"type:varchar(64);not null;index:idx_tasklog_task_seq,unique,priority:1" json:"taskId"`
Seq int `gorm:"not null;index:idx_tasklog_task_seq,unique,priority:2" json:"seq"`
Line string `gorm:"type:text" json:"line"`
TS time.Time `json:"ts"`
}
TaskLog 任务的一行滚动日志。按 task_id + seq 幂等去重(心跳可能重复携带同一行)。
type TaskState ¶
type TaskState string
TaskState 任务状态。pending/running 为非终态,succeeded/failed 为终态。
const ( // TaskStatePending 任务已创建,尚未在 Worker 上开始执行。 TaskStatePending TaskState = "pending" // TaskStateRunning 任务执行中。 TaskStateRunning TaskState = "running" // TaskStateSucceeded 任务成功完成(终态)。 TaskStateSucceeded TaskState = "succeeded" // TaskStateFailed 任务失败(终态)。 TaskStateFailed TaskState = "failed" // TaskStateCanceled 任务被强制停止(终态,FR-227)。Worker 操作真被中断后由心跳上报。 TaskStateCanceled TaskState = "canceled" )
type Template ¶
type Template struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Name string `gorm:"type:varchar(128);not null" json:"name"`
Type string `gorm:"type:varchar(64);not null" json:"type"` // minecraft_java, etc.
Description string `gorm:"type:varchar(512)" json:"description"`
StartCommand string `gorm:"type:varchar(1024)" json:"startCommand"`
DefaultWorkDir string `gorm:"type:varchar(512)" json:"defaultWorkDir"`
DownloadURL string `gorm:"type:varchar(512)" json:"downloadUrl"`
ConfigFiles string `gorm:"type:text" json:"configFiles"` // JSON
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
Template 服务端模板。
type User ¶
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
UUID string `gorm:"type:char(36);uniqueIndex;not null" json:"uuid"`
Username string `gorm:"type:varchar(64);uniqueIndex;not null" json:"username"`
Password string `gorm:"type:varchar(128);not null" json:"-"`
Role UserRole `gorm:"default:0" json:"role"`
Status UserStatus `gorm:"default:0" json:"status"`
// AuthVersion 在密码、状态或角色发生安全相关变更时递增,用于立即吊销旧会话。
AuthVersion uint `gorm:"not null;default:0" json:"-"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
User 用户模型。
type UserInvitation ¶ added in v0.21.0
type UserInvitation struct {
ID uint `gorm:"primaryKey" json:"id"`
Email string `gorm:"type:varchar(254);not null;index" json:"email"`
TokenHash []byte `gorm:"type:binary(32);uniqueIndex;not null" json:"-"`
TokenPrefix string `gorm:"type:varchar(16);not null" json:"-"`
Role UserRole `gorm:"not null;default:0" json:"role"`
ExpiresAt time.Time `gorm:"not null;index" json:"expiresAt"`
CreatedByID uint `gorm:"not null;index" json:"createdBy"`
UsedAt *time.Time `json:"usedAt"`
RevokedAt *time.Time `json:"revokedAt"`
EmailSentAt *time.Time `json:"emailSentAt"`
EmailDelivery string `gorm:"type:varchar(32);not null;default:not_configured" json:"emailDelivery"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}
UserInvitation 记录由平台管理员签发的一次性成员邀请。 明文令牌只在签发响应与邮件正文中短暂存在,数据库仅保存哈希。
type UserStatus ¶
type UserStatus int
UserStatus 用户状态。
const ( UserStatusActive UserStatus = 0 // 启用 UserStatusDisabled UserStatus = 1 // 禁用 )
Source Files
¶
- agent_call_log.go
- agent_token.go
- agent_transfer_ticket.go
- alert.go
- artifact_migration.go
- artifact_reconcile.go
- artifact_storage_channel.go
- artifact_version.go
- asset.go
- audit.go
- auth_setup_lock.go
- backup.go
- backup_storage.go
- ban.go
- bot.go
- bot_load_command_checkpoint.go
- bot_load_metric.go
- bot_load_run_event.go
- bot_load_template.go
- business_event.go
- client_channel.go
- client_dist_event.go
- client_dist_snapshot.go
- client_ip_rule.go
- client_machine.go
- client_runtime_state.go
- client_security.go
- client_telemetry.go
- client_version.go
- config_version.go
- enroll_token.go
- file_version.go
- group.go
- instance.go
- instance_crash_snapshot.go
- instance_group.go
- instance_tags.go
- log.go
- metric.go
- network.go
- node.go
- node_jdk.go
- node_pm_config.go
- node_runtime.go
- notification.go
- orphan_runtime.go
- platform_setting.go
- registration.go
- schedule.go
- schedule_log.go
- selfupdate_check_cache.go
- task.go
- template.go
- user.go
- user_invitation.go