Files
FlowStack/backend/internal/model/models.go
T
Logan.Li 97193eb090 feat: v0.4.0 主题切换 + LLM 全面优化 + 登录会话 + 用户管理/LDAP
主题:
- 深色/浅色/跟随系统(useTheme:本地缓存先行+远端同步+matchMedia),
  侧边栏快捷切换,设置页三档即选即生效

LLM(参考 opsxdb/aiops):
- llm.Client.ChatStream 流式(SSE 增量解析,透传 reasoning_content,
  ctx 控制超时);POST /api/ai/chat/stream(平台实时数据注入降幻觉,
  未配 LLM 降级规则 JSON,指令解析 action 不变)
- test-llm 支持草稿直测(保存前验证,apiKey 空/掩码回退已存)
- 发布失败自动 AI 分析日志尾部(结论/根因/建议),发布记录与发布
  Tab 展示分析卡片
- 设置页 Provider 预设(DeepSeek/GLM/GLM编码/Qwen/Kimi/Ollama/自定义)
  自动填 endpoint+模型+获取 Key 直达链接

登录与会话:
- HMAC 签名 token(7 天,密钥派生自 encryption.key);
  authMiddleware 保护 /api/*(豁免登录/健康/SSE日志流/入站webhook)
- 登录页 /login + 未登录跳转 + 登出;401 自动清理跳登录

用户管理与 LDAP(借鉴 LokiStack):
- /users 页面:本地用户 CRUD、一次性密码、角色切换、来源徽章
  (本地·蓝 | LDAP导入·紫);LDAP 导入按钮仅在启用且配置齐备时显示
- LDAP 配置卡(未启用仅提示语)、测试连接草稿直测+可选测试账号
- go-ldap:管理 Bind/用户搜索(防注入)/用户 DN 直连验证;
  批量导入冲突策略(已LDAP跳过/本地同名转LDAP/新建);
  登录分流本地 argon2id 或 LDAP 目录验证 + 首登 JIT 建号
2026-10-27 12:58:21 +08:00

305 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import "time"
// User 系统用户
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
Username string `gorm:"uniqueIndex" json:"username"`
Password string `json:"-"` // argon2id 哈希,绝不返回给前端
Nickname string `json:"nickname"`
Email string `json:"email"`
AuthSource string `gorm:"default:local" json:"authSource"` // local | ldap
Role string `gorm:"default:user" json:"role"` // admin | user
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// Pipeline 流水线定义
type Pipeline struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"index" json:"name"`
Description string `json:"description"`
Type string `gorm:"default:native" json:"type"` // native | jenkins | tekton
SourceRepo string `json:"sourceRepo"`
SourceBranch string `gorm:"default:main" json:"sourceBranch"`
GitopsRepo string `json:"gitopsRepo"`
GitopsPath string `json:"gitopsPath"`
DeployType string `gorm:"default:host" json:"deployType"` // host | k8s | gitops
Env string `gorm:"default:staging" json:"env"`
TriggerMode string `gorm:"default:manual" json:"triggerMode"` // manual | git_push | cron | webhook
CronExpr string `json:"cronExpr"`
WebhookToken string `json:"webhookToken"`
WatchBranches string `json:"watchBranches"`
Variables string `gorm:"type:text" json:"variables"` // JSON [{key,value,remark}]
CachePaths string `gorm:"type:text" json:"cachePaths"` // JSON [{path,key}]
NotifyWebhook string `json:"notifyWebhookURL"`
JenkinsJobName string `json:"jenkinsJobName"`
JenkinsServerID uint `json:"jenkinsServerId"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// PipelineNode 画布节点(JSON 字段名与前端 React Flow 对齐)
type PipelineNode struct {
ID uint `gorm:"primaryKey" json:"dbId"`
PipelineID uint `gorm:"index" json:"pipelineId"`
NodeID string `gorm:"index" json:"nodeId"`
Type string `json:"type"`
Name string `json:"name"`
PositionX float64 `json:"positionX"`
PositionY float64 `json:"positionY"`
Width float64 `json:"width"`
Height float64 `json:"height"`
Category string `json:"category"` // source|build|test|security|deploy|gitops|custom
Config map[string]interface{} `gorm:"serializer:json" json:"config"`
}
// PipelineEdge 画布连线
type PipelineEdge struct {
ID uint `gorm:"primaryKey" json:"dbId"`
PipelineID uint `gorm:"index" json:"pipelineId"`
EdgeID string `gorm:"index" json:"edgeId"`
Source string `json:"source"`
Target string `json:"target"`
Label string `json:"label"`
Animated bool `json:"animated"`
}
// PipelineRun 一次流水线运行
type PipelineRun struct {
ID uint `gorm:"primaryKey" json:"id"`
RunID string `gorm:"uniqueIndex" json:"runId"` // pr-<timestamp>
PipelineID uint `gorm:"index" json:"pipelineId"`
PipelineName string `json:"pipelineName"`
Branch string `gorm:"default:main" json:"branch"`
Env string `gorm:"default:staging" json:"env"`
DeployType string `gorm:"default:host" json:"deployType"`
Type string `gorm:"default:native" json:"type"`
TriggerBy string `gorm:"default:system" json:"triggerBy"`
TriggerType string `gorm:"default:manual" json:"triggerType"` // manual|webhook|cron|batch
Status string `gorm:"default:pending" json:"status"` // pending|queued|running|success|failed|cancelled
DurationMs int64 `json:"durationMs"`
BuildNumber int `json:"buildNumber"`
Analysis string `gorm:"type:text" json:"analysis"` // 发布失败时的 AI 分析
ExternalRunID string `json:"externalRunId"`
ExternalURL string `json:"externalUrl"`
NodesSnapshot string `json:"nodesSnapshot"`
EdgesSnapshot string `json:"edgesSnapshot"`
StartedAt time.Time `json:"startedAt"`
CompletedAt *time.Time `json:"completedAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// RunStage 运行中的阶段(对应一个节点)
type RunStage struct {
ID uint `gorm:"primaryKey" json:"id"`
RunID uint `gorm:"index" json:"runId"`
NodeID string `json:"nodeId"`
Name string `json:"name"`
PodName string `json:"podName"`
Status string `gorm:"default:pending" json:"status"` // pending|running|success|failed|skipped
ExitCode *int `json:"exitCode"`
StartedAt *time.Time `json:"startedAt"`
CompletedAt *time.Time `json:"completedAt"`
}
// LogEntry 运行日志
type LogEntry struct {
ID uint `gorm:"primaryKey" json:"id"`
RunID uint `gorm:"index" json:"runId"`
StageID uint `json:"stageId"`
Level string `gorm:"default:info" json:"level"` // debug|info|warn|error
Message string `json:"message"`
Source string `gorm:"default:runner" json:"source"`
Timestamp time.Time `json:"timestamp"`
}
// Application GitOps 应用
type Application struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
Repo string `json:"repo"`
Branch string `gorm:"default:main" json:"branch"`
Path string `json:"path"`
Cluster string `gorm:"default:default" json:"cluster"`
Namespace string `gorm:"default:default" json:"namespace"`
ManifestType string `gorm:"default:plain" json:"manifestType"` // helm|kustomize|plain
SyncPolicy string `gorm:"default:manual" json:"syncPolicy"` // manual|automated
AutoPrune bool `json:"autoPrune"`
SelfHeal bool `json:"selfHeal"`
SyncStatus string `gorm:"default:Synced" json:"syncStatus"` // Synced|OutOfSync|Syncing
HealthStatus string `gorm:"default:Healthy" json:"healthStatus"` // Healthy|Progressing|Degraded
LastSyncAt *time.Time `json:"lastSyncAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// Plugin 插件
type Plugin struct {
ID uint `gorm:"primaryKey" json:"id"`
PluginID string `gorm:"uniqueIndex" json:"pluginId"`
Name string `json:"name"`
Description string `json:"description"`
Version string `json:"version"`
Author string `json:"author"`
Category string `gorm:"default:general" json:"category"`
EntryPath string `json:"entryPath"`
Installed bool `gorm:"default:true" json:"installed"`
Enabled bool `gorm:"default:true" json:"enabled"`
Config map[string]interface{} `gorm:"serializer:json" json:"config"`
CreatedAt time.Time `json:"createdAt"`
}
// Host 主机资源
type Host struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
IP string `json:"ip"`
SSHPort int `gorm:"default:22" json:"port"`
Username string `gorm:"default:root" json:"username"`
Tags string `gorm:"type:text" json:"tags"` // JSON ["production","web"]
Status string `gorm:"default:offline" json:"status"` // online|offline
OS string `json:"os"`
Remark string `json:"remark"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// K8sCluster 集群资源
type K8sCluster struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
Context string `json:"context"`
APIServer string `json:"apiServer"`
Version string `json:"version"`
Kubeconfig string `gorm:"type:text" json:"-"` // enc:v1: 加密,不回显
KubeconfigSet bool `gorm:"-" json:"kubeconfigSet"`
NodeCount int `json:"nodes"`
Namespaces string `gorm:"type:text" json:"namespaces"` // JSON []
Status string `gorm:"default:disconnected" json:"status"` // connected|disconnected
LastHeartbeat *time.Time `json:"lastHeartbeat"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// Credential 凭证(内容 AES-GCM 加密,只写不读)
type Credential struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
Type string `gorm:"index" json:"type"` // ssh|password|docker|git|kubeconfig|aksk
Scope string `gorm:"default:全局" json:"scope"`
Content string `gorm:"type:text" json:"-"` // enc:v1: 加密 JSON
ContentSet bool `gorm:"-" json:"contentSet"`
Summary string `json:"summary"` // 脱敏摘要
UsageCount int `gorm:"default:0" json:"usageCount"`
LastUsedAt *time.Time `json:"lastUsedAt"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// BuildNode 构建节点
type BuildNode struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
IP string `json:"ip"`
Labels string `gorm:"type:text" json:"labels"` // JSON ["docker","go"]
MaxConcurrency int `gorm:"default:2" json:"maxConcurrency"`
WorkspacePath string `gorm:"default:/data/flowstack-workspace" json:"workspacePath"`
DiskInfo string `json:"diskInfo"` // 如 "45G/200G"
CredentialID *uint `json:"credentialId"` // SSH 凭证(磁盘性能测试等远程操作)
DiskWriteMBps float64 `gorm:"column:disk_write_mbps" json:"diskWriteMBps"`
DiskReadMBps float64 `gorm:"column:disk_read_mbps" json:"diskReadMBps"`
DiskTestMode string `json:"diskTestMode"` // local|ssh + /direct|/cache
DiskTestedAt *time.Time `json:"diskTestedAt"`
Enabled bool `gorm:"default:true" json:"enabled"`
Status string `gorm:"default:offline" json:"status"` // online|offline|busy
CurrentJobs int `gorm:"default:0" json:"currentJobs"`
LastHeartbeat *time.Time `json:"lastHeartbeat"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// DeployTool 构建工具(检测命令真实执行;安装为保守策略:仅检测不下载)
type DeployTool struct {
ID uint `gorm:"primaryKey" json:"id"`
ToolKey string `gorm:"uniqueIndex" json:"key"`
DisplayName string `json:"name"`
Category string `gorm:"default:build" json:"category"` // build|deploy
Status string `gorm:"default:not-installed" json:"status"` // not-installed|installed|installing|failed
Version string `json:"version"` // 默认/期望版本
InstalledVersion string `json:"installedVersion"` // 真实探测到的版本
InstallMode string `gorm:"default:lazy" json:"installMode"` // preinstalled|lazy|disabled
Path string `json:"path"`
CheckCommand string `gorm:"type:text" json:"checkCommand"` // 真实版本探测命令
InstallHint string `gorm:"type:text" json:"installHint"` // 安装命令提示(Ubuntu apt / nvm)
Enabled bool `gorm:"default:true" json:"enabled"`
LastCheck *time.Time `json:"lastCheck"`
ErrorMsg string `json:"errorMsg"`
SortOrder int `json:"sortOrder"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// WebhookEndpoint 出站 Webhook(HMAC-SHA256 签名)
type WebhookEndpoint struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `json:"name"`
URL string `json:"url"`
Secret string `gorm:"type:text" json:"-"` // enc:v1: 加密
SecretSet bool `gorm:"-" json:"secretSet"`
Events string `gorm:"type:text" json:"events"` // JSON ["pipeline.success",...]
Active bool `gorm:"default:true" json:"active"`
LastTriggeredAt *time.Time `json:"lastTriggered"`
LastStatus string `gorm:"default:none" json:"lastStatus"` // success|failed|none
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// JenkinsServer Jenkins 实例
type JenkinsServer struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
BaseURL string `json:"baseUrl"`
Username string `json:"username"`
Token string `gorm:"type:text" json:"-"` // enc:v1: 加密
TokenSet bool `gorm:"-" json:"tokenSet"`
Enabled bool `gorm:"default:true" json:"enabled"`
Remark string `json:"remark"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
// SystemSetting 系统设置(单行,ID 恒为 1)
type SystemSetting struct {
ID uint `gorm:"primaryKey" json:"id"`
Theme string `gorm:"type:text" json:"theme"` // JSON {mode,primaryColor,...}
Notification string `gorm:"type:text" json:"notification"` // JSON {email,browser,...}
ToolMode string `gorm:"default:local" json:"toolMode"` // local|jenkins
LlmEnabled bool `gorm:"default:false" json:"llmEnabled"`
LlmEndpoint string `gorm:"default:https://api.deepseek.com/v1" json:"llmEndpoint"`
LlmModel string `gorm:"default:deepseek-chat" json:"llmModel"`
LlmApiKey string `gorm:"type:text" json:"-"` // enc:v1: 加密,只写不读
LlmApiKeySet bool `gorm:"-" json:"llmApiKeySet"`
LlmMaxTokens int `gorm:"default:1200" json:"llmMaxTokens"`
LarkEnabled bool `gorm:"default:false" json:"larkEnabled"`
LarkWebhook string `json:"larkWebhook"` // 飞书群自定义机器人 Webhook
LarkSecret string `gorm:"type:text" json:"-"` // 加签密钥(可选),enc:v1: 加密
LarkSecretSet bool `gorm:"-" json:"larkSecretSet"`
LdapEnabled bool `json:"ldapEnabled"`
LdapHost string `json:"ldapHost"`
LdapPort int `gorm:"default:389" json:"ldapPort"`
LdapUseSSL bool `json:"ldapUseSSL"`
LdapBindDN string `json:"ldapBindDN"`
LdapBindPassword string `gorm:"type:text" json:"-"` // enc:v1: 加密只写
LdapBindPasswordSet bool `gorm:"-" json:"ldapBindPasswordSet"`
LdapBaseDN string `json:"ldapBaseDN"`
LdapUserFilter string `json:"ldapUserFilter"`
LdapUsernameAttr string `json:"ldapUsernameAttr"`
LdapNameAttr string `json:"ldapNameAttr"`
LdapEmailAttr string `json:"ldapEmailAttr"`
Extra string `gorm:"type:text" json:"extra"`
UpdatedAt time.Time `json:"updatedAt"`
}