diff --git a/agentdesk.go b/agentdesk.go new file mode 100644 index 0000000..105d62f --- /dev/null +++ b/agentdesk.go @@ -0,0 +1,36 @@ +package agentdesk + +import ( + "errors" + "net/http" + + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/bootstrap" + "code.tczkiot.com/wlw/ai-agent/internal/services" +) + +type Options struct { + ConfigPath string + QuerySubjects identity.QuerySubjectsFunc + Authorize identity.AuthorizeFunc +} + +// New initializes the customer-service business module. Authentication and +// authorization must already have been completed by the host system. +func New(options Options) (http.Handler, error) { + if options.QuerySubjects == nil { + return nil, errors.New("agent-desk: QuerySubjects is required") + } + if options.Authorize == nil { + return nil, errors.New("agent-desk: Authorize is required") + } + if options.ConfigPath == "" { + options.ConfigPath = "config/config.yaml" + } + services.SetQuerySubjects(options.QuerySubjects) + services.SetAuthorize(options.Authorize) + if err := bootstrap.Init(options.ConfigPath); err != nil { + return nil, err + } + return bootstrap.NewServer() +} diff --git a/cmd/generator/generator.go b/cmd/generator/generator.go index 283ad19..b226c26 100644 --- a/cmd/generator/generator.go +++ b/cmd/generator/generator.go @@ -1,7 +1,7 @@ package main import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/codegen" ) @@ -19,19 +19,10 @@ func main() { WebEdit: false, }, codegen.GetGenerateStruct(&models.Migration{}), - codegen.GetGenerateStruct(&models.User{}), - codegen.GetGenerateStruct(&models.UserIdentity{}), codegen.GetGenerateStruct(&models.Company{}), codegen.GetGenerateStruct(&models.Customer{}), codegen.GetGenerateStruct(&models.CustomerIdentity{}), codegen.GetGenerateStruct(&models.CustomerContact{}), - codegen.GetGenerateStruct(&models.Role{}), - codegen.GetGenerateStruct(&models.Permission{}), - codegen.GetGenerateStruct(&models.UserRole{}), - codegen.GetGenerateStruct(&models.RolePermission{}), - codegen.GetGenerateStruct(&models.UserPermission{}), - codegen.GetGenerateStruct(&models.LoginSession{}), - codegen.GetGenerateStruct(&models.LoginCredentialLog{}), codegen.GetGenerateStruct(&models.Asset{}), codegen.GetGenerateStruct(&models.Tag{}), codegen.GetGenerateStruct(&models.Conversation{}), diff --git a/cmd/migration/main.go b/cmd/migration/main.go index 7b15385..f7792ea 100644 --- a/cmd/migration/main.go +++ b/cmd/migration/main.go @@ -3,9 +3,9 @@ package main import ( "log/slog" - "agent-desk/internal/bootstrap" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/logx" + "code.tczkiot.com/wlw/ai-agent/internal/bootstrap" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/logx" ) func main() { diff --git a/cmd/server/main.go b/cmd/server/main.go index 1e478fa..811576f 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -4,8 +4,8 @@ import ( "flag" "log/slog" - "agent-desk/internal/bootstrap" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/bootstrap" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func main() { diff --git a/cmd/testdata/agentteam/init.go b/cmd/testdata/agentteam/init.go deleted file mode 100644 index bb1d68c..0000000 --- a/cmd/testdata/agentteam/init.go +++ /dev/null @@ -1,200 +0,0 @@ -package agentteam - -import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - "fmt" - "time" - - "github.com/mlogclub/simple/sqls" - "golang.org/x/crypto/bcrypt" -) - -type InitResult struct { - TeamCreated bool - UsersCreated int - ProfilesCreated int - UpdatesApplied int -} - -// Init 初始化客服组和客服用户 -// 创建: -// 1. 客服组,组长为管理员用户 -// 2. 客服A 用户 -// 3. 客服B 用户 -// 4. 为客服A和客服B创建客服档案,关联到该客服组 -func Init(lang seedlang.Language) (*InitResult, error) { - result := &InitResult{} - - // 获取管理员用户 - adminUser := repositories.UserRepository.Take( - sqls.DB(), - "username = ?", - constants.BootstrapAdminUsername, - ) - if adminUser == nil { - return result, fmt.Errorf("bootstrap admin user not found") - } - - err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - return initTeamAndUsers(ctx, adminUser, result, lang) - }) - if err != nil { - return result, fmt.Errorf("init team and users failed: %w", err) - } - - return result, nil -} - -func initTeamAndUsers(ctx *sqls.TxContext, leaderUser *models.User, result *InitResult, lang seedlang.Language) error { - teamName := seeds.AgentTeamName(lang) - now := time.Now() - - team := repositories.AgentTeamRepository.Take(ctx.Tx, "name = ?", teamName) - if team != nil { - if err := ctx.Tx.Model(team).Updates(map[string]any{ - "leader_user_id": leaderUser.ID, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, - "updated_at": now, - }).Error; err != nil { - return err - } - } else { - team = &models.AgentTeam{ - Name: teamName, - LeaderUserID: leaderUser.ID, - Status: enums.StatusOk, - Description: "Local testdata seed - default service team", - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - if err := ctx.Tx.Create(team).Error; err != nil { - return err - } - result.TeamCreated = true - } - - agentUsers := seeds.AgentUsers(lang, leaderUser.Username) - for _, agentUser := range agentUsers { - userID, userCreated, err := createOrGetUser(ctx, agentUser.Username, agentUser.Nickname) - if err != nil { - return err - } - if userCreated { - result.UsersCreated++ - } - - // 创建或更新客服档案 - profileCreated, err := createOrUpdateProfile(ctx, userID, team.ID, agentUser.Code, agentUser.Nickname) - if err != nil { - return err - } - if profileCreated { - result.ProfilesCreated++ - } else { - result.UpdatesApplied++ - } - } - - return nil -} - -func createOrGetUser(ctx *sqls.TxContext, username, nickname string) (int64, bool, error) { - user := repositories.UserRepository.Take( - ctx.Tx, - "username = ?", - username, - ) - - if user != nil { - return user.ID, false, nil - } - - // 创建新用户 - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(constants.BootstrapAdminPassword), bcrypt.DefaultCost) - if err != nil { - return 0, false, err - } - - now := time.Now() - newUser := &models.User{ - Username: username, - Nickname: nickname, - Password: string(hashedPassword), - Status: enums.StatusOk, - Remark: "Local testdata seed", - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - - if err := ctx.Tx.Create(newUser).Error; err != nil { - return 0, false, err - } - - return newUser.ID, true, nil -} - -func createOrUpdateProfile(ctx *sqls.TxContext, userID, teamID int64, agentCode, displayName string) (bool, error) { - profile := repositories.AgentProfileRepository.Take( - ctx.Tx, - "user_id = ?", - userID, - ) - - now := time.Now() - - if profile != nil { - // 档案已存在,更新关键信息 - return false, ctx.Tx.Model(profile).Updates(map[string]any{ - "team_id": teamID, - "agent_code": agentCode, - "display_name": displayName, - "status": enums.StatusOk, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, - "updated_at": now, - }).Error - } - - // 创建新档案 - newProfile := &models.AgentProfile{ - UserID: userID, - TeamID: teamID, - AgentCode: agentCode, - DisplayName: displayName, - Avatar: "", - ServiceStatus: enums.ServiceStatusIdle, - MaxConcurrentCount: 5, - PriorityLevel: 10, - AutoAssignEnabled: true, - Status: enums.StatusOk, - Remark: "Local testdata seed", - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - - return true, ctx.Tx.Create(newProfile).Error -} diff --git a/cmd/testdata/agentteam/init_test.go b/cmd/testdata/agentteam/init_test.go deleted file mode 100644 index e28a1eb..0000000 --- a/cmd/testdata/agentteam/init_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package agentteam - -import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "regexp" - "testing" -) - -var hanTextPattern = regexp.MustCompile(`\p{Han}`) - -func TestEnglishAgentTeamTextDoesNotContainChineseText(t *testing.T) { - values := []string{seeds.AgentTeamName(seedlang.English)} - for _, user := range seeds.AgentUsers(seedlang.English, "admin") { - values = append(values, user.Nickname) - } - - for _, value := range values { - if hanTextPattern.MatchString(value) { - t.Fatalf("english agent team seed contains Chinese text: %q", value) - } - } -} diff --git a/cmd/testdata/aiagent/init.go b/cmd/testdata/aiagent/init.go index f6f1bd5..7a77a4c 100644 --- a/cmd/testdata/aiagent/init.go +++ b/cmd/testdata/aiagent/init.go @@ -1,12 +1,12 @@ package aiagent import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "fmt" "strings" "time" diff --git a/cmd/testdata/aiagent/init_test.go b/cmd/testdata/aiagent/init_test.go index 0ecbd76..bef7ba2 100644 --- a/cmd/testdata/aiagent/init_test.go +++ b/cmd/testdata/aiagent/init_test.go @@ -1,8 +1,8 @@ package aiagent import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "strings" "testing" diff --git a/cmd/testdata/aiconfig/init.go b/cmd/testdata/aiconfig/init.go index 1f49cfd..e5a86e4 100644 --- a/cmd/testdata/aiconfig/init.go +++ b/cmd/testdata/aiconfig/init.go @@ -6,10 +6,10 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" "gopkg.in/yaml.v3" diff --git a/cmd/testdata/channel/init.go b/cmd/testdata/channel/init.go index 35a6e9a..9d6d949 100644 --- a/cmd/testdata/channel/init.go +++ b/cmd/testdata/channel/init.go @@ -1,11 +1,11 @@ package channel import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "fmt" "time" diff --git a/cmd/testdata/channel/init_test.go b/cmd/testdata/channel/init_test.go index dab1ad6..a144cdd 100644 --- a/cmd/testdata/channel/init_test.go +++ b/cmd/testdata/channel/init_test.go @@ -1,8 +1,8 @@ package channel import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "testing" ) diff --git a/cmd/testdata/kb/kb.go b/cmd/testdata/kb/kb.go index bfdc687..1b58e96 100644 --- a/cmd/testdata/kb/kb.go +++ b/cmd/testdata/kb/kb.go @@ -1,12 +1,12 @@ package kb import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "encoding/json" "time" diff --git a/cmd/testdata/kb/kb_test.go b/cmd/testdata/kb/kb_test.go index e9e131b..2743ac5 100644 --- a/cmd/testdata/kb/kb_test.go +++ b/cmd/testdata/kb/kb_test.go @@ -1,8 +1,8 @@ package kb import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "testing" ) diff --git a/cmd/testdata/main.go b/cmd/testdata/main.go index 792b8b8..dcb7e91 100644 --- a/cmd/testdata/main.go +++ b/cmd/testdata/main.go @@ -1,17 +1,16 @@ package main import ( - "agent-desk/cmd/testdata/agentteam" - "agent-desk/cmd/testdata/aiagent" - "agent-desk/cmd/testdata/aiconfig" - "agent-desk/cmd/testdata/channel" - "agent-desk/cmd/testdata/kb" - "agent-desk/cmd/testdata/quickreply" - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/skill" - "agent-desk/cmd/testdata/tag" - "agent-desk/internal/bootstrap" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/aiagent" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/aiconfig" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/channel" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/kb" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/quickreply" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/skill" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/tag" + "code.tczkiot.com/wlw/ai-agent/internal/bootstrap" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "flag" "fmt" "log/slog" @@ -94,16 +93,6 @@ func run() error { } slog.Info("skill init success", slog.Int("created", skillResult.Created), slog.Int("updated", skillResult.Updated)) - agentTeamResult, err := agentteam.Init(lang) - if err != nil { - return fmt.Errorf("init agent team failed: %w", err) - } - slog.Info("agent team init success", slog.Bool("teamCreated", agentTeamResult.TeamCreated), - slog.Int("usersCreated", agentTeamResult.UsersCreated), - slog.Int("profilesCreated", agentTeamResult.ProfilesCreated), - slog.Int("updatesApplied", agentTeamResult.UpdatesApplied), - ) - aiAgentResult, err := aiagent.Init(lang) if err != nil { return fmt.Errorf("init ai agent failed: %w", err) diff --git a/cmd/testdata/quickreply/init.go b/cmd/testdata/quickreply/init.go index 90cdc92..1dfd176 100644 --- a/cmd/testdata/quickreply/init.go +++ b/cmd/testdata/quickreply/init.go @@ -1,10 +1,10 @@ package quickreply import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "time" "github.com/mlogclub/simple/sqls" diff --git a/cmd/testdata/quickreply/init_test.go b/cmd/testdata/quickreply/init_test.go index 0c9572d..f4b9d34 100644 --- a/cmd/testdata/quickreply/init_test.go +++ b/cmd/testdata/quickreply/init_test.go @@ -1,8 +1,8 @@ package quickreply import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "testing" ) diff --git a/cmd/testdata/seeds/agentteam.go b/cmd/testdata/seeds/agentteam.go index fbf4b9a..6c7f1bc 100644 --- a/cmd/testdata/seeds/agentteam.go +++ b/cmd/testdata/seeds/agentteam.go @@ -1,6 +1,6 @@ package seeds -import "agent-desk/cmd/testdata/seedlang" +import "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" type AgentUserSeed struct { Username string diff --git a/cmd/testdata/seeds/aiagent.go b/cmd/testdata/seeds/aiagent.go index b1ac3e5..6d2115d 100644 --- a/cmd/testdata/seeds/aiagent.go +++ b/cmd/testdata/seeds/aiagent.go @@ -1,8 +1,8 @@ package seeds import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type AIAgentSeed struct { diff --git a/cmd/testdata/seeds/channel.go b/cmd/testdata/seeds/channel.go index 6cd5886..fc32258 100644 --- a/cmd/testdata/seeds/channel.go +++ b/cmd/testdata/seeds/channel.go @@ -1,9 +1,9 @@ package seeds import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/mlogclub/simple/common/jsons" ) diff --git a/cmd/testdata/seeds/kb.go b/cmd/testdata/seeds/kb.go index 3047a38..a4a3001 100644 --- a/cmd/testdata/seeds/kb.go +++ b/cmd/testdata/seeds/kb.go @@ -1,6 +1,6 @@ package seeds -import "agent-desk/cmd/testdata/seedlang" +import "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" type KnowledgeBaseSeed struct { Name string @@ -83,7 +83,6 @@ func chineseKnowledgeFAQSeeds() []KnowledgeFAQSeed { {Question: "新成员加入后如何开通后台账号?", Answer: "企业管理员进入“组织设置-成员管理”,点击“新增成员”,填写姓名、邮箱、所属团队和角色后保存。系统会自动发送激活邮件,成员首次登录时设置密码即可。若你们开通了单点登录,也可以直接从企业身份系统同步成员。", SimilarQuestions: []string{"怎么给新客服开账号", "新增员工账号在哪里", "成员怎么加入后台"}, Remark: "成员管理"}, {Question: "成员离职后如何停用账号?", Answer: "请在“组织设置-成员管理”中找到对应成员,点击“停用”即可。停用后该账号无法继续登录,但历史会话、工单处理记录和质检数据会保留,不会影响报表统计。若后续确认不再使用,也可以在完成交接后删除账号。", SimilarQuestions: []string{"离职员工账号怎么处理", "怎么禁用成员账号", "停用客服账号"}, Remark: "成员管理"}, {Question: "角色权限修改后多久生效?", Answer: "角色权限保存后通常即时生效。已在线的成员可能需要刷新页面或重新登录,才能拿到最新权限菜单和接口授权。如果修改后仍能访问原页面,请清理浏览器缓存后再试。", SimilarQuestions: []string{"权限修改什么时候生效", "调整角色后没变化", "角色更新后要重登吗"}, Remark: "成员管理"}, - {Question: "支持企业微信或钉钉单点登录吗?", Answer: "支持对接企业微信、钉钉和标准 SAML/OIDC 单点登录。开通后成员可通过企业身份系统直接登录平台,无需单独维护密码。具体配置需要管理员在“安全设置-单点登录”中填写回调地址、应用凭证并完成测试。", SimilarQuestions: []string{"能接企业微信登录吗", "支持钉钉 SSO 吗", "单点登录怎么接"}, Remark: "成员管理"}, {Question: "坐席在线、忙碌、离线状态有什么区别?", Answer: "在线表示可正常接待新会话,忙碌表示当前暂不分配新会话但仍可处理已有会话,离线表示不参与会话分配也不接收实时提醒。若开启自动状态切换,长时间无操作或退出登录后,系统会自动变更为离线。", SimilarQuestions: []string{"客服状态怎么理解", "在线忙碌离线区别", "坐席状态说明"}, Remark: "坐席接待"}, {Question: "会话是怎么分配给坐席的?", Answer: "默认按技能组和轮询策略分配,也可结合坐席当前负载、最近响应时长和优先级规则进行智能分流。若客户命中了指定渠道、语言或标签条件,系统会优先路由到匹配该条件的团队或坐席。", SimilarQuestions: []string{"客户咨询怎么分配", "会话路由规则是什么", "新会话按什么分给客服"}, Remark: "坐席接待"}, {Question: "如何把会话转接给其他团队?", Answer: "在会话详情页点击“转接”,选择目标团队或指定坐席,并填写转接备注即可。转接后,原坐席仍可在历史记录中查看会话内容,但新消息会优先提醒接收方。若目标团队离线人数过多,建议先确认有人值班。", SimilarQuestions: []string{"会话怎么转给别的组", "转接客服在哪里", "咨询如何分配给其他团队"}, Remark: "坐席接待"}, diff --git a/cmd/testdata/seeds/quickreply.go b/cmd/testdata/seeds/quickreply.go index a973a98..8b44d5f 100644 --- a/cmd/testdata/seeds/quickreply.go +++ b/cmd/testdata/seeds/quickreply.go @@ -1,8 +1,8 @@ package seeds import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type QuickReplySeed struct { diff --git a/cmd/testdata/seeds/skill.go b/cmd/testdata/seeds/skill.go index 7e87c2e..7c16ace 100644 --- a/cmd/testdata/seeds/skill.go +++ b/cmd/testdata/seeds/skill.go @@ -1,8 +1,8 @@ package seeds import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type SkillDefinitionSeed struct { diff --git a/cmd/testdata/seeds/tag.go b/cmd/testdata/seeds/tag.go index 60eba4e..63bfb6f 100644 --- a/cmd/testdata/seeds/tag.go +++ b/cmd/testdata/seeds/tag.go @@ -1,6 +1,6 @@ package seeds -import "agent-desk/cmd/testdata/seedlang" +import "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" type TagSeed struct { ID int64 diff --git a/cmd/testdata/skill/init.go b/cmd/testdata/skill/init.go index d2192bc..5f73f53 100644 --- a/cmd/testdata/skill/init.go +++ b/cmd/testdata/skill/init.go @@ -1,10 +1,10 @@ package skill import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "fmt" "strings" "time" diff --git a/cmd/testdata/skill/init_test.go b/cmd/testdata/skill/init_test.go index 0b054c4..81f2c09 100644 --- a/cmd/testdata/skill/init_test.go +++ b/cmd/testdata/skill/init_test.go @@ -1,8 +1,8 @@ package skill import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "testing" ) diff --git a/cmd/testdata/tag/init.go b/cmd/testdata/tag/init.go index a188fd0..f20c884 100644 --- a/cmd/testdata/tag/init.go +++ b/cmd/testdata/tag/init.go @@ -1,11 +1,11 @@ package tag import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "time" "github.com/mlogclub/simple/sqls" diff --git a/cmd/testdata/tag/init_test.go b/cmd/testdata/tag/init_test.go index b751556..408e9ac 100644 --- a/cmd/testdata/tag/init_test.go +++ b/cmd/testdata/tag/init_test.go @@ -1,8 +1,8 @@ package tag import ( - "agent-desk/cmd/testdata/seedlang" - "agent-desk/cmd/testdata/seeds" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seedlang" + "code.tczkiot.com/wlw/ai-agent/cmd/testdata/seeds" "regexp" "testing" ) diff --git a/config/config.example.yaml b/config/config.example.yaml index 18af117..73ca032 100644 --- a/config/config.example.yaml +++ b/config/config.example.yaml @@ -2,7 +2,7 @@ language: zh-CN server: port: 8083 - # Public address of the independently deployed frontend. Login callbacks redirect here. + # Public address of the independently deployed frontend. frontendUrl: http://127.0.0.1:3000 cors: # Browser CORS allowlist. In production, replace this with the actual frontend or embedded-site domains, such as https://support.example.com. @@ -34,25 +34,6 @@ logger: format: text addSource: false -auth: - # Login access token lifetime, in hours. Values <= 0 fall back to 12 hours. - # Applies to password login, OIDC login, and WeCom login sessions. - tokenTTLHours: 12 - # Maximum failed password attempts allowed within the lock window. - # Values <= 0 disable credential lockout. - maxFailedAttempts: 5 - # Failed-login lock window, in minutes. When maxFailedAttempts is reached within this window, login is temporarily blocked. - # Values <= 0 fall back to 15 minutes when lockout is enabled. - credentialLockMinute: 15 - -customerSession: - # Signing secret for customer service session tokens. Use a separate, high-entropy random string; do not reuse the channel userTokenSecret. - secret: "" - # Default lifetime for customer service session tokens, in minutes. - ttlMinutes: 120 - # Automatically refresh the token when its remaining lifetime falls below this value, in minutes. - refreshThresholdMinutes: 30 - storage: # Default file storage provider used for uploads. Supported values: local, oss. # Empty value is treated as local by the backend. @@ -108,25 +89,9 @@ mcp: # Extra HTTP headers sent to this MCP server on every request, for example Authorization or tenant headers. headers: {} -oidc: - # Whether to enable OIDC login. This system acts as the OIDC client. - enabled: false - # OIDC provider issuer, for example https://idp.example.com/realms/demo. - issuer: "" - clientId: "" - clientSecret: "" - # Must exactly match the redirect_uri registered with the OIDC provider. - redirectUrl: "http://127.0.0.1:8083/api/auth/oidc_callback" - # Signing secret for the OIDC login state. If left empty, clientSecret is used as the fallback. - stateSecret: "" - scopes: - - openid - - profile - - email - wxWork: # Whether to enable WeCom features. - # When set to false, the WeCom SDK is not initialized, and login, customer service callbacks, and app notifications are unavailable. + # When set to false, the WeCom SDK is not initialized, and customer service callbacks and app notifications are unavailable. enabled: false # WeCom corporate ID. # Example: wwxxxxxxxxxxxxxxxx, from the WeCom admin console. @@ -134,26 +99,13 @@ wxWork: # WeCom app secret. # Used by the backend to obtain access tokens and user identities. Keep it confidential. corpSecret: "" - # AgentID of the WeCom custom app. - # Used for web authorization when scope=snsapi_privateinfo. + # AgentID of the WeCom custom app, used for app notifications. agentId: - # WeCom web authorization callback URL. - # Must be a full URL pointing to the backend endpoint: - # Example: http://127.0.0.1:8083/api/auth/wxwork_callback - # In production, use an official domain that WeCom can access, and make sure the domain is configured in the WeCom admin console. - oauthRedirect: "" - # Signing secret for the WeCom login state. - # Used for tamper protection and replay protection. A separate random string is recommended. - # If left empty, the code falls back to corpSecret, but this is not recommended. - stateSecret: "" # Private key for decrypting WeCom callbacks. - # Not used by the current login flow. Reserved for message callbacks and similar scenarios. rsaPrivateKey: "" # WeCom callback token. - # Not used by the current login flow. Reserved for message callbacks and similar scenarios. token: "" # WeCom message encryption/decryption EncodingAESKey. - # Not used by the current login flow. Reserved for message callbacks and similar scenarios. encodingAESKey: "" notify: diff --git a/docker/agent-desk-lancedb.yaml b/docker/agent-desk-lancedb.yaml index 647d2b9..d8b7003 100644 --- a/docker/agent-desk-lancedb.yaml +++ b/docker/agent-desk-lancedb.yaml @@ -17,11 +17,6 @@ logger: format: text addSource: false -auth: - tokenTTLHours: 24 - maxFailedAttempts: 5 - credentialLockMinute: 30 - storage: default: local maxUploadSizeMB: 5 @@ -58,11 +53,3 @@ mcp: wxWork: enabled: false - -oidc: - enabled: false - -customerSession: - secret: change-me - ttlMinutes: 120 - refreshThresholdMinutes: 30 diff --git a/docker/agent-desk-sqlite-lancedb.yaml b/docker/agent-desk-sqlite-lancedb.yaml index bef90fc..9ec30e9 100644 --- a/docker/agent-desk-sqlite-lancedb.yaml +++ b/docker/agent-desk-sqlite-lancedb.yaml @@ -21,16 +21,6 @@ logger: format: text addSource: false -auth: - tokenTTLHours: 12 - maxFailedAttempts: 5 - credentialLockMinute: 15 - -customerSession: - secret: replace-with-a-random-secret - ttlMinutes: 120 - refreshThresholdMinutes: 30 - storage: default: local maxUploadSizeMB: 20 @@ -70,8 +60,6 @@ wxWork: corpId: "" corpSecret: "" agentId: "" - oauthRedirect: "" - stateSecret: "" rsaPrivateKey: "" token: "" encodingAESKey: "" @@ -81,15 +69,3 @@ wxWork: safe: false enableDuplicateCheck: true duplicateCheckInterval: 1800 - -oidc: - enabled: false - issuer: "" - clientId: "" - clientSecret: "" - redirectUrl: http://127.0.0.1:8083/api/auth/oidc_callback - stateSecret: "" - scopes: - - openid - - profile - - email diff --git a/docker/agent-desk.yaml b/docker/agent-desk.yaml index 6a121bc..a54fd38 100644 --- a/docker/agent-desk.yaml +++ b/docker/agent-desk.yaml @@ -22,16 +22,6 @@ logger: format: text addSource: false -auth: - tokenTTLHours: 12 - maxFailedAttempts: 5 - credentialLockMinute: 15 - -customerSession: - secret: replace-with-a-random-secret - ttlMinutes: 120 - refreshThresholdMinutes: 30 - storage: default: local maxUploadSizeMB: 20 @@ -72,8 +62,6 @@ wxWork: corpId: "" corpSecret: "" agentId: "" - oauthRedirect: "" - stateSecret: "" rsaPrivateKey: "" token: "" encodingAESKey: "" diff --git a/go.mod b/go.mod index e90322d..de55726 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module agent-desk +module code.tczkiot.com/wlw/ai-agent go 1.26.0 @@ -6,12 +6,10 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/cloudwego/eino v0.9.6 github.com/cloudwego/eino-ext/components/model/openai v0.1.13 - github.com/coreos/go-oidc/v3 v3.18.0 github.com/eino-contrib/jsonschema v1.0.3 github.com/gin-gonic/gin v1.12.0 github.com/glebarez/sqlite v1.11.0 github.com/go-playground/validator/v10 v10.30.1 - github.com/golang-jwt/jwt/v5 v5.3.1 github.com/gomarkdown/markdown v0.0.0-20240328165702-4d01890c35c0 github.com/google/uuid v1.6.0 github.com/gorilla/schema v1.4.1 @@ -30,18 +28,17 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 github.com/xuri/excelize/v2 v2.10.1 github.com/yuin/goldmark v1.4.13 - golang.org/x/crypto v0.53.0 golang.org/x/net v0.56.0 - golang.org/x/oauth2 v0.36.0 - golang.org/x/text v0.38.0 golang.org/x/tools v0.46.0 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 + gorm.io/driver/postgres v1.5.9 gorm.io/gorm v1.25.12 ) require ( github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect @@ -52,14 +49,15 @@ require ( github.com/spf13/pflag v1.0.10 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - gorm.io/driver/postgres v1.5.9 // indirect + golang.org/x/crypto v0.53.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/text v0.38.0 // indirect ) require ( github.com/apache/arrow/go/v17 v17.0.0 github.com/aymerick/douceur v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect - github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect github.com/buger/jsonparser v1.2.0 // indirect github.com/bytedance/gopkg v0.1.4 // indirect @@ -75,7 +73,6 @@ require ( github.com/gabriel-vasile/mimetype v1.4.12 // indirect github.com/gin-contrib/sse v1.1.0 // indirect github.com/glebarez/go-sqlite v1.21.2 // indirect - github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect diff --git a/go.sum b/go.sum index f1a6ca4..0b2a118 100644 --- a/go.sum +++ b/go.sum @@ -12,29 +12,19 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3 github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs= -github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g= github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= -github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM= github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4= github.com/bytedance/mockey v1.3.0 h1:ONLRdvhqmCfr9rTasUB8ZKCfvbdD2tohOg4u+4Q/ed0= github.com/bytedance/mockey v1.3.0/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= -github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= -github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= github.com/bytedance/sonic v1.15.2 h1:90H+rcF/FwLXwfB1cudOLq/je83n683Utf4Cbp0xHCo= github.com/bytedance/sonic v1.15.2/go.mod h1:mT2NbXunuaEbnZ+mRIX/vYqKISmgEuHFDI4UzmKx2SA= -github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= -github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/bytedance/sonic/loader v0.5.1 h1:Ygpfa9zwRCCKSlrp5bBP/b/Xzc3VxsAW+5NIYXrOOpI= github.com/bytedance/sonic/loader v0.5.1/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= @@ -44,24 +34,14 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= -github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI= github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg= -github.com/cloudwego/eino v0.8.7 h1:GlzrJa5hpovPdZ+loBvXs1W4D5gWC+a6PRqJmlj4iis= -github.com/cloudwego/eino v0.8.7/go.mod h1:+2N4nsMPxA6kGBHpH+75JuTfEcGprAMTdsZESrShKpU= github.com/cloudwego/eino v0.9.6 h1:M3IRhIpDxNwIuQ2SRUX1yUTkC8lcMggRI5wtHZy8A5M= github.com/cloudwego/eino v0.9.6/go.mod h1:OBD1mrkfkt/pJa4rkg1P0VnaMeOVl7l8IAdEqY//3IQ= -github.com/cloudwego/eino-ext/components/model/openai v0.1.11 h1:juf9kECfmxJBA0rJSxDT7XOUSgrbMHaGHgBwd06lYaI= -github.com/cloudwego/eino-ext/components/model/openai v0.1.11/go.mod h1:DBk44Dq1mhuoAacdUzzhZhSGeeBECDI2rIZnJFeVZoE= github.com/cloudwego/eino-ext/components/model/openai v0.1.13 h1:5XHRTiTD5bt9KQrMHcfvuWNklEC3tpm3XHejdozt9vM= github.com/cloudwego/eino-ext/components/model/openai v0.1.13/go.mod h1:mgIoqYYOc0eECCqvLbEYpOJrQNTNxkwXzSJzFU+v5sQ= -github.com/cloudwego/eino-ext/libs/acl/openai v0.1.15 h1:LbdSG9+qWzzp9RFW6dSFkaUW171JvCoYn/K63zX6dQE= -github.com/cloudwego/eino-ext/libs/acl/openai v0.1.15/go.mod h1:p+l0zBB0GjjX8HTlbTs3g3KfUFwZC11bsCGZOXW/3L0= github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17 h1:EeVcR1TslRA2IdNW1h/2LaGbPlffwGhQm99jM3zWZiI= github.com/cloudwego/eino-ext/libs/acl/openai v0.1.17/go.mod h1:Zkcx6DPTR2NfWmtSXbhItswGw6hqUezNPhNcke0pOG8= -github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A= -github.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -94,8 +74,6 @@ github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GM github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= -github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -180,7 +158,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -202,8 +179,6 @@ github.com/lancedb/lancedb-go v0.1.2 h1:ucM+KNN5J886OilSh4MRdyBa1sinHyrisoaswNIS github.com/lancedb/lancedb-go v0.1.2/go.mod h1:HzleylKfuw2HgfBBfrE3tb4LMKNdJ3/TQ1Ziyd+CLZk= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.9.2 h1:dX8U45hQsZpxd80nLvDGihsQ/OxlvTkVUXH2r/8cb2M= github.com/mailru/easyjson v0.9.2/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -212,8 +187,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/meguminnnnnnnnn/go-openai v0.1.2 h1:iXombGGjqjBrmE9WaSidUhhi3YQhf42QTHvHLMkgvCA= -github.com/meguminnnnnnnnn/go-openai v0.1.2/go.mod h1:qs96ysDmxhE4BZoU45I43zcyfnaYxU3X+aRzLko/htY= github.com/meguminnnnnnnnn/go-openai v0.1.5 h1:K9XFfnEUj9E+9djustmfa4eIdg8Q2vWD4mGv+AHbQ2k= github.com/meguminnnnnnnnn/go-openai v0.1.5/go.mod h1:qs96ysDmxhE4BZoU45I43zcyfnaYxU3X+aRzLko/htY= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= @@ -258,8 +231,6 @@ github.com/openai/openai-go/v3 v3.28.0 h1:2+FfrCVMdGXSQrBv1tLWtokm+BU7+3hJ/8rAHP github.com/openai/openai-go/v3 v3.28.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo= github.com/panjf2000/ants/v2 v2.12.0 h1:u9JhESo83i/GkZnhfTNuFMMWcNt7mnV1bGJ6FT4wXH8= github.com/panjf2000/ants/v2 v2.12.0/go.mod h1:tSQuaNQ6r6NRhPt+IZVUevvDyFMTs+eS4ztZc52uJTY= -github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= -github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc= github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= @@ -390,8 +361,6 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= -golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/arch v0.28.0 h1:wVwVdqsTuUbJvhYVCspQYwZXHNYeLSoZnmHD+ggddpQ= golang.org/x/arch v0.28.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -399,19 +368,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/exp v0.0.0-20260611194520-c48552f49976 h1:X8Hz2ImujgbmetVuW+w2YkyZChE3cBpZi2P158rTG9M= golang.org/x/exp v0.0.0-20260611194520-c48552f49976/go.mod h1:vnf4pv9iKZXY58sQE1L86zmNWJ4159e1RkcWiLCkeEY= golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -421,8 +384,6 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= @@ -430,8 +391,6 @@ golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -453,23 +412,16 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= -golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9 h1:FjUup8XrRy7lv+XHONi6KKUSizeF2NnVrTnz/HhbohQ= golang.org/x/telemetry v0.0.0-20260610154732-fb80ec83bdd9/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= @@ -477,8 +429,6 @@ golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/identity/identity.go b/identity/identity.go new file mode 100644 index 0000000..a777b9b --- /dev/null +++ b/identity/identity.go @@ -0,0 +1,46 @@ +package identity + +import "context" + +type SubjectType string + +const ( + SubjectAdmin SubjectType = "admin" + SubjectAgent SubjectType = "agent" + SubjectCard SubjectType = "card" + SubjectDevice SubjectType = "device" + SubjectMallUser SubjectType = "mall_user" +) + +type SubjectCategory string + +const ( + CategorySystem SubjectCategory = "system" + CategoryUser SubjectCategory = "user" +) + +type Subject struct { + Type SubjectType `json:"type"` + Category SubjectCategory `json:"category"` + ID int64 `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + Avatar string `json:"avatar"` + Identifier string `json:"identifier"` + Enabled bool `json:"enabled"` + Bindings map[string]string `json:"bindings,omitempty"` +} + +type Query struct { + Types []SubjectType + IDs []int64 + Keyword string + Current bool + EnabledOnly bool +} + +type QuerySubjectsFunc func(ctx context.Context, query Query) ([]Subject, error) + +// AuthorizeFunc delegates a customer-service operation to the host system. +// Returning a non-nil error denies the operation. +type AuthorizeFunc func(ctx context.Context, operation string) error diff --git a/internal/ai/application/runtime/agent_loop_engine.go b/internal/ai/application/runtime/agent_loop_engine.go index 6b067dd..c649ad4 100644 --- a/internal/ai/application/runtime/agent_loop_engine.go +++ b/internal/ai/application/runtime/agent_loop_engine.go @@ -11,20 +11,20 @@ import ( "strings" "time" - ai "agent-desk/internal/ai" - "agent-desk/internal/ai/runtime/instruction" - "agent-desk/internal/ai/runtime/readtools" - "agent-desk/internal/ai/runtime/retrievers" - runtimetooling "agent-desk/internal/ai/runtime/tooling" - workflowexecutor "agent-desk/internal/ai/runtime/workflow" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/pkg/utils" - svc "agent-desk/internal/services" + ai "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/instruction" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/readtools" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/retrievers" + runtimetooling "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + workflowexecutor "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/workflow" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/application/runtime/agent_loop_engine_test.go b/internal/ai/application/runtime/agent_loop_engine_test.go index 9b26b80..414f957 100644 --- a/internal/ai/application/runtime/agent_loop_engine_test.go +++ b/internal/ai/application/runtime/agent_loop_engine_test.go @@ -6,11 +6,11 @@ import ( "strings" "testing" - ai "agent-desk/internal/ai" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - svc "agent-desk/internal/services" + ai "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/application/runtime/agent_turn.go b/internal/ai/application/runtime/agent_turn.go index cb03503..010a7c2 100644 --- a/internal/ai/application/runtime/agent_turn.go +++ b/internal/ai/application/runtime/agent_turn.go @@ -5,11 +5,11 @@ import ( "fmt" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/pkg/utils" - svc "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) type agentLoopTurn struct { diff --git a/internal/ai/application/runtime/application_service.go b/internal/ai/application/runtime/application_service.go index 7419d19..8dced0f 100644 --- a/internal/ai/application/runtime/application_service.go +++ b/internal/ai/application/runtime/application_service.go @@ -4,9 +4,9 @@ import ( "context" "strings" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - svc "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) // ApplicationRunInput identifies the persisted inputs for an Agent reply. diff --git a/internal/ai/application/runtime/application_service_test.go b/internal/ai/application/runtime/application_service_test.go index 4ddac2e..1da30ca 100644 --- a/internal/ai/application/runtime/application_service_test.go +++ b/internal/ai/application/runtime/application_service_test.go @@ -4,8 +4,8 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/application/runtime/eino_agent_loop.go b/internal/ai/application/runtime/eino_agent_loop.go index dad2c9f..dad9038 100644 --- a/internal/ai/application/runtime/eino_agent_loop.go +++ b/internal/ai/application/runtime/eino_agent_loop.go @@ -8,8 +8,8 @@ import ( "strings" "time" - ai "agent-desk/internal/ai" - "agent-desk/internal/models" + ai "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/models" einoopenai "github.com/cloudwego/eino-ext/components/model/openai" einomodel "github.com/cloudwego/eino/components/model" diff --git a/internal/ai/application/runtime/evaluation.go b/internal/ai/application/runtime/evaluation.go index d8f3505..03783b2 100644 --- a/internal/ai/application/runtime/evaluation.go +++ b/internal/ai/application/runtime/evaluation.go @@ -6,9 +6,9 @@ import ( "strconv" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) // OfflineEvaluationCase is an isolated customer-service evaluation sample. diff --git a/internal/ai/application/runtime/service.go b/internal/ai/application/runtime/service.go index 20fb8ed..58f2400 100644 --- a/internal/ai/application/runtime/service.go +++ b/internal/ai/application/runtime/service.go @@ -6,9 +6,9 @@ import ( "strings" "time" - workflowexecutor "agent-desk/internal/ai/runtime/workflow" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + workflowexecutor "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/workflow" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/application/runtime/types.go b/internal/ai/application/runtime/types.go index 5001dd6..13b9176 100644 --- a/internal/ai/application/runtime/types.go +++ b/internal/ai/application/runtime/types.go @@ -1,7 +1,7 @@ package runtime import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "time" ) diff --git a/internal/ai/application/runtime/workflow_runtime.go b/internal/ai/application/runtime/workflow_runtime.go index e50a954..76b7cee 100644 --- a/internal/ai/application/runtime/workflow_runtime.go +++ b/internal/ai/application/runtime/workflow_runtime.go @@ -3,10 +3,10 @@ package runtime import ( "encoding/json" - "agent-desk/internal/ai/workflow/dsl" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/embedding.go b/internal/ai/embedding.go index 60c01e4..adeec0d 100644 --- a/internal/ai/embedding.go +++ b/internal/ai/embedding.go @@ -6,9 +6,9 @@ import ( openai "github.com/openai/openai-go/v3" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) type EmbeddingResult struct { diff --git a/internal/ai/llm.go b/internal/ai/llm.go index 8746669..d7881c3 100644 --- a/internal/ai/llm.go +++ b/internal/ai/llm.go @@ -10,8 +10,8 @@ import ( openai "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/shared" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type ChatCompletionResult struct { diff --git a/internal/ai/llm_test.go b/internal/ai/llm_test.go index 4774f38..4fa519c 100644 --- a/internal/ai/llm_test.go +++ b/internal/ai/llm_test.go @@ -7,7 +7,7 @@ import ( openai "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/shared" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestApplyProviderSpecificChatParamsIncludesDashScopeThinkingFlag(t *testing.T) { diff --git a/internal/ai/mcps/client.go b/internal/ai/mcps/client.go index 2eaf2da..65356e1 100644 --- a/internal/ai/mcps/client.go +++ b/internal/ai/mcps/client.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "github.com/modelcontextprotocol/go-sdk/mcp" ) diff --git a/internal/ai/mcps/providers/system_tools_provider.go b/internal/ai/mcps/providers/system_tools_provider.go index 65e2b92..9c547a7 100644 --- a/internal/ai/mcps/providers/system_tools_provider.go +++ b/internal/ai/mcps/providers/system_tools_provider.go @@ -1,7 +1,7 @@ package providers import ( - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "context" "time" diff --git a/internal/ai/mcps/registry.go b/internal/ai/mcps/registry.go index ba17aa9..5ee0092 100644 --- a/internal/ai/mcps/registry.go +++ b/internal/ai/mcps/registry.go @@ -1,7 +1,7 @@ package mcps import ( - "agent-desk/internal/ai/mcps/providers" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps/providers" "github.com/modelcontextprotocol/go-sdk/mcp" ) diff --git a/internal/ai/mcps/runtime.go b/internal/ai/mcps/runtime.go index bffcc14..3a6d546 100644 --- a/internal/ai/mcps/runtime.go +++ b/internal/ai/mcps/runtime.go @@ -4,8 +4,8 @@ import ( "context" "strings" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) type RuntimeService struct { diff --git a/internal/ai/openai_client.go b/internal/ai/openai_client.go index 2ae519b..6dfe892 100644 --- a/internal/ai/openai_client.go +++ b/internal/ai/openai_client.go @@ -7,10 +7,10 @@ import ( openai "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/option" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" ) func newOpenAIClient(config models.AIConfig) openai.Client { diff --git a/internal/ai/rag/answer.go b/internal/ai/rag/answer.go index 7ef1b10..6c75d42 100644 --- a/internal/ai/rag/answer.go +++ b/internal/ai/rag/answer.go @@ -8,14 +8,14 @@ import ( "github.com/mlogclub/simple/sqls" - "agent-desk/internal/ai" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" ) type answer struct { diff --git a/internal/ai/rag/answer_test.go b/internal/ai/rag/answer_test.go index ccb5b28..4e49ffc 100644 --- a/internal/ai/rag/answer_test.go +++ b/internal/ai/rag/answer_test.go @@ -3,9 +3,9 @@ package rag import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestBuildFallbackAnswer(t *testing.T) { diff --git a/internal/ai/rag/chunk/fixed_provider.go b/internal/ai/rag/chunk/fixed_provider.go index 757d85e..7e4fcbb 100644 --- a/internal/ai/rag/chunk/fixed_provider.go +++ b/internal/ai/rag/chunk/fixed_provider.go @@ -1,7 +1,7 @@ package chunk import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "context" ) diff --git a/internal/ai/rag/chunk/provider.go b/internal/ai/rag/chunk/provider.go index c19de3e..98adc0d 100644 --- a/internal/ai/rag/chunk/provider.go +++ b/internal/ai/rag/chunk/provider.go @@ -1,7 +1,7 @@ package chunk import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "context" ) diff --git a/internal/ai/rag/chunk/registry.go b/internal/ai/rag/chunk/registry.go index 6bf10cf..306903d 100644 --- a/internal/ai/rag/chunk/registry.go +++ b/internal/ai/rag/chunk/registry.go @@ -1,7 +1,7 @@ package chunk import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "context" "fmt" ) diff --git a/internal/ai/rag/chunk/structured_provider.go b/internal/ai/rag/chunk/structured_provider.go index d1f4fb4..786bb3d 100644 --- a/internal/ai/rag/chunk/structured_provider.go +++ b/internal/ai/rag/chunk/structured_provider.go @@ -1,7 +1,7 @@ package chunk import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "context" "strings" diff --git a/internal/ai/rag/chunk/types.go b/internal/ai/rag/chunk/types.go index 1254985..322d06c 100644 --- a/internal/ai/rag/chunk/types.go +++ b/internal/ai/rag/chunk/types.go @@ -1,6 +1,6 @@ package chunk -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type ChunkRequest struct { KnowledgeBaseID int64 diff --git a/internal/ai/rag/chunk/utils.go b/internal/ai/rag/chunk/utils.go index ad09214..e54e408 100644 --- a/internal/ai/rag/chunk/utils.go +++ b/internal/ai/rag/chunk/utils.go @@ -1,7 +1,7 @@ package chunk import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "crypto/sha256" "encoding/hex" "strings" diff --git a/internal/ai/rag/index.go b/internal/ai/rag/index.go index 4cb7e51..6abe382 100644 --- a/internal/ai/rag/index.go +++ b/internal/ai/rag/index.go @@ -9,12 +9,12 @@ import ( "log/slog" "time" - "agent-desk/internal/ai" - ragchunk "agent-desk/internal/ai/rag/chunk" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + ragchunk "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/chunk" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/google/uuid" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/rag/index_cleanup_helpers.go b/internal/ai/rag/index_cleanup_helpers.go index 89c57a1..37efeb6 100644 --- a/internal/ai/rag/index_cleanup_helpers.go +++ b/internal/ai/rag/index_cleanup_helpers.go @@ -5,9 +5,9 @@ import ( "fmt" "log/slog" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/rag/index_document_helpers.go b/internal/ai/rag/index_document_helpers.go index 9e55060..edaba00 100644 --- a/internal/ai/rag/index_document_helpers.go +++ b/internal/ai/rag/index_document_helpers.go @@ -6,12 +6,12 @@ import ( "log/slog" "time" - ragchunk "agent-desk/internal/ai/rag/chunk" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + ragchunk "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/chunk" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai" ) func (s *index) buildDocumentChunkRequest(document models.KnowledgeDocument, knowledgeBase models.KnowledgeBase) *ragchunk.ChunkRequest { diff --git a/internal/ai/rag/index_faq_helpers.go b/internal/ai/rag/index_faq_helpers.go index 7bb58db..7a83fc9 100644 --- a/internal/ai/rag/index_faq_helpers.go +++ b/internal/ai/rag/index_faq_helpers.go @@ -5,10 +5,10 @@ import ( "fmt" "time" - "agent-desk/internal/ai" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func buildFAQChunkModel(knowledgeBase models.KnowledgeBase, faq models.KnowledgeFAQ, content string) (models.KnowledgeChunk, string) { diff --git a/internal/ai/rag/index_flow.go b/internal/ai/rag/index_flow.go index 8e97384..09f0296 100644 --- a/internal/ai/rag/index_flow.go +++ b/internal/ai/rag/index_flow.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/rag/index_retrieve_helpers_test.go b/internal/ai/rag/index_retrieve_helpers_test.go index a05230d..9992724 100644 --- a/internal/ai/rag/index_retrieve_helpers_test.go +++ b/internal/ai/rag/index_retrieve_helpers_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestBuildFAQChunkContent(t *testing.T) { diff --git a/internal/ai/rag/index_run_helpers.go b/internal/ai/rag/index_run_helpers.go index 327db8c..13c7587 100644 --- a/internal/ai/rag/index_run_helpers.go +++ b/internal/ai/rag/index_run_helpers.go @@ -5,10 +5,10 @@ import ( "fmt" "log/slog" - "agent-desk/internal/ai" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/rag/index_status_helpers.go b/internal/ai/rag/index_status_helpers.go index bb344b3..38ab2e6 100644 --- a/internal/ai/rag/index_status_helpers.go +++ b/internal/ai/rag/index_status_helpers.go @@ -3,9 +3,9 @@ package rag import ( "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/rag/index_storage_helpers.go b/internal/ai/rag/index_storage_helpers.go index 9a4e7b2..1edd4f3 100644 --- a/internal/ai/rag/index_storage_helpers.go +++ b/internal/ai/rag/index_storage_helpers.go @@ -5,7 +5,7 @@ import ( "fmt" "log/slog" - "agent-desk/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" ) func (s *index) ensureCollection(ctx context.Context, provider vectordb.Provider, collectionName string, dimension int) error { diff --git a/internal/ai/rag/rerank.go b/internal/ai/rag/rerank.go index 01b1529..f126973 100644 --- a/internal/ai/rag/rerank.go +++ b/internal/ai/rag/rerank.go @@ -10,8 +10,8 @@ import ( "sort" "time" - "agent-desk/internal/ai" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type rerank struct{} diff --git a/internal/ai/rag/retrieve.go b/internal/ai/rag/retrieve.go index 0f442b6..1eb9ea1 100644 --- a/internal/ai/rag/retrieve.go +++ b/internal/ai/rag/retrieve.go @@ -6,10 +6,10 @@ import ( "log/slog" "strings" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/rag/retrieve_flow.go b/internal/ai/rag/retrieve_flow.go index 0459726..eb44bec 100644 --- a/internal/ai/rag/retrieve_flow.go +++ b/internal/ai/rag/retrieve_flow.go @@ -4,7 +4,7 @@ import ( "fmt" "log/slog" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func newRetrieveTrace() *RetrieveTrace { diff --git a/internal/ai/rag/retrieve_log.go b/internal/ai/rag/retrieve_log.go index 55677f4..a24c9fb 100644 --- a/internal/ai/rag/retrieve_log.go +++ b/internal/ai/rag/retrieve_log.go @@ -5,9 +5,9 @@ import ( "fmt" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" "github.com/google/uuid" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/rag/retrieve_search.go b/internal/ai/rag/retrieve_search.go index bd8daf2..bc23268 100644 --- a/internal/ai/rag/retrieve_search.go +++ b/internal/ai/rag/retrieve_search.go @@ -8,11 +8,11 @@ import ( "strings" "time" - "agent-desk/internal/ai" - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/rag/retrieve_test.go b/internal/ai/rag/retrieve_test.go index da40133..b6c556a 100644 --- a/internal/ai/rag/retrieve_test.go +++ b/internal/ai/rag/retrieve_test.go @@ -3,7 +3,7 @@ package rag import ( "testing" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestResolveKnowledgeBaseSearchOptionsUsesKnowledgeBaseDefaults(t *testing.T) { diff --git a/internal/ai/rag/utils.go b/internal/ai/rag/utils.go index 9f9e454..424091a 100644 --- a/internal/ai/rag/utils.go +++ b/internal/ai/rag/utils.go @@ -1,7 +1,7 @@ package rag import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "strings" "github.com/yuin/goldmark" diff --git a/internal/ai/rag/utils_test.go b/internal/ai/rag/utils_test.go index 54b1601..1d17641 100644 --- a/internal/ai/rag/utils_test.go +++ b/internal/ai/rag/utils_test.go @@ -1,8 +1,8 @@ package rag import ( - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "testing" ) diff --git a/internal/ai/rag/vectordb/lancedb.go b/internal/ai/rag/vectordb/lancedb.go index 9293a52..c1abb5f 100644 --- a/internal/ai/rag/vectordb/lancedb.go +++ b/internal/ai/rag/vectordb/lancedb.go @@ -10,7 +10,7 @@ import ( "strconv" "strings" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "github.com/apache/arrow/go/v17/arrow" "github.com/apache/arrow/go/v17/arrow/array" diff --git a/internal/ai/rag/vectordb/lancedb_stub.go b/internal/ai/rag/vectordb/lancedb_stub.go index 33224d4..d4a5863 100644 --- a/internal/ai/rag/vectordb/lancedb_stub.go +++ b/internal/ai/rag/vectordb/lancedb_stub.go @@ -5,7 +5,7 @@ package vectordb import ( "fmt" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func NewLanceDBProvider(_ *config.LanceDBVectorDBConfig) (Provider, error) { diff --git a/internal/ai/rag/vectordb/lancedb_test.go b/internal/ai/rag/vectordb/lancedb_test.go index cdff34d..28a9e22 100644 --- a/internal/ai/rag/vectordb/lancedb_test.go +++ b/internal/ai/rag/vectordb/lancedb_test.go @@ -6,7 +6,7 @@ import ( "context" "testing" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func TestLanceDBProviderVectorLifecycle(t *testing.T) { diff --git a/internal/ai/rag/vectordb/provider.go b/internal/ai/rag/vectordb/provider.go index d60fcb3..0410253 100644 --- a/internal/ai/rag/vectordb/provider.go +++ b/internal/ai/rag/vectordb/provider.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) var defaultProvider Provider diff --git a/internal/ai/rag/vectordb/provider_test.go b/internal/ai/rag/vectordb/provider_test.go index fd2a283..e361737 100644 --- a/internal/ai/rag/vectordb/provider_test.go +++ b/internal/ai/rag/vectordb/provider_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func TestInitLanceDBWithoutBuildTagReturnsActionableError(t *testing.T) { diff --git a/internal/ai/rag/vectordb/qdrant.go b/internal/ai/rag/vectordb/qdrant.go index 5c005c7..70125f2 100644 --- a/internal/ai/rag/vectordb/qdrant.go +++ b/internal/ai/rag/vectordb/qdrant.go @@ -6,7 +6,7 @@ import ( "github.com/qdrant/go-client/qdrant" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) type QdrantProvider struct { diff --git a/internal/ai/runtime/debug_run.go b/internal/ai/runtime/debug_run.go index 7741645..d9f50cf 100644 --- a/internal/ai/runtime/debug_run.go +++ b/internal/ai/runtime/debug_run.go @@ -5,14 +5,14 @@ import ( "fmt" "strings" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) func init() { diff --git a/internal/ai/runtime/evaluation_run.go b/internal/ai/runtime/evaluation_run.go index 1d0cf50..ea8f6a6 100644 --- a/internal/ai/runtime/evaluation_run.go +++ b/internal/ai/runtime/evaluation_run.go @@ -3,12 +3,12 @@ package runtime import ( "context" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) func init() { diff --git a/internal/ai/runtime/graphs/analyze_conversation_graph.go b/internal/ai/runtime/graphs/analyze_conversation_graph.go index 7890434..63ea57d 100644 --- a/internal/ai/runtime/graphs/analyze_conversation_graph.go +++ b/internal/ai/runtime/graphs/analyze_conversation_graph.go @@ -6,8 +6,8 @@ import ( "fmt" "strings" - "agent-desk/internal/models" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) type AnalyzeConversationInput struct { diff --git a/internal/ai/runtime/graphs/analyze_conversation_graph_test.go b/internal/ai/runtime/graphs/analyze_conversation_graph_test.go index 495f5d6..8aae07e 100644 --- a/internal/ai/runtime/graphs/analyze_conversation_graph_test.go +++ b/internal/ai/runtime/graphs/analyze_conversation_graph_test.go @@ -3,8 +3,8 @@ package graphs import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestBuildAnalyzeConversationResult_RecommendsHandoffForComplaint(t *testing.T) { diff --git a/internal/ai/runtime/graphs/create_ticket_graph.go b/internal/ai/runtime/graphs/create_ticket_graph.go index 26017ac..9c0126e 100644 --- a/internal/ai/runtime/graphs/create_ticket_graph.go +++ b/internal/ai/runtime/graphs/create_ticket_graph.go @@ -6,12 +6,12 @@ import ( "fmt" "strings" - "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" componenttool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/graphs/handoff_graph.go b/internal/ai/runtime/graphs/handoff_graph.go index e537d0c..a068ac7 100644 --- a/internal/ai/runtime/graphs/handoff_graph.go +++ b/internal/ai/runtime/graphs/handoff_graph.go @@ -6,11 +6,11 @@ import ( "fmt" "strings" - "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/tracex" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" + "code.tczkiot.com/wlw/ai-agent/internal/services" componenttool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/graphs/handoff_graph_test.go b/internal/ai/runtime/graphs/handoff_graph_test.go index e4887f4..74219e0 100644 --- a/internal/ai/runtime/graphs/handoff_graph_test.go +++ b/internal/ai/runtime/graphs/handoff_graph_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/runtime/graphs/hitl.go b/internal/ai/runtime/graphs/hitl.go index 077f4d2..1b45c57 100644 --- a/internal/ai/runtime/graphs/hitl.go +++ b/internal/ai/runtime/graphs/hitl.go @@ -3,7 +3,7 @@ package graphs import ( "strings" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" ) const ( diff --git a/internal/ai/runtime/graphs/prepare_ticket_draft_graph.go b/internal/ai/runtime/graphs/prepare_ticket_draft_graph.go index 049619c..0e22d93 100644 --- a/internal/ai/runtime/graphs/prepare_ticket_draft_graph.go +++ b/internal/ai/runtime/graphs/prepare_ticket_draft_graph.go @@ -6,9 +6,9 @@ import ( "fmt" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) type PrepareTicketDraftInput struct { diff --git a/internal/ai/runtime/graphs/prepare_ticket_draft_graph_test.go b/internal/ai/runtime/graphs/prepare_ticket_draft_graph_test.go index 2602f3d..4b2f0c8 100644 --- a/internal/ai/runtime/graphs/prepare_ticket_draft_graph_test.go +++ b/internal/ai/runtime/graphs/prepare_ticket_draft_graph_test.go @@ -3,8 +3,8 @@ package graphs import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestBuildPrepareTicketDraftResult_UsesConversationFallbacks(t *testing.T) { diff --git a/internal/ai/runtime/graphs/triage_service_request_graph.go b/internal/ai/runtime/graphs/triage_service_request_graph.go index a95615f..48409ad 100644 --- a/internal/ai/runtime/graphs/triage_service_request_graph.go +++ b/internal/ai/runtime/graphs/triage_service_request_graph.go @@ -6,8 +6,8 @@ import ( "fmt" "strings" - "agent-desk/internal/models" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) type TriageServiceRequestInput struct { diff --git a/internal/ai/runtime/graphs/triage_service_request_graph_test.go b/internal/ai/runtime/graphs/triage_service_request_graph_test.go index 6fedd96..de01cb4 100644 --- a/internal/ai/runtime/graphs/triage_service_request_graph_test.go +++ b/internal/ai/runtime/graphs/triage_service_request_graph_test.go @@ -3,8 +3,8 @@ package graphs import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestTriageServiceRequestResult_PrepareTicket(t *testing.T) { diff --git a/internal/ai/runtime/instruction/helpers.go b/internal/ai/runtime/instruction/helpers.go index e297966..c06198a 100644 --- a/internal/ai/runtime/instruction/helpers.go +++ b/internal/ai/runtime/instruction/helpers.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - runtimetooling "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/toolx" + runtimetooling "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) func BuildSelectedSkillActivationInstruction(skill *models.SkillDefinition) string { diff --git a/internal/ai/runtime/instruction/providers.go b/internal/ai/runtime/instruction/providers.go index e37f83f..91d2c70 100644 --- a/internal/ai/runtime/instruction/providers.go +++ b/internal/ai/runtime/instruction/providers.go @@ -1,9 +1,9 @@ package instruction import ( - "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) type ToolAppendixProvider struct{} diff --git a/internal/ai/runtime/instruction/service.go b/internal/ai/runtime/instruction/service.go index b3c941c..cbdf679 100644 --- a/internal/ai/runtime/instruction/service.go +++ b/internal/ai/runtime/instruction/service.go @@ -3,8 +3,8 @@ package instruction import ( "strings" - runtimetooling "agent-desk/internal/ai/runtime/tooling" - "agent-desk/internal/models" + runtimetooling "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) type Service struct { diff --git a/internal/ai/runtime/readtools/graph_executor.go b/internal/ai/runtime/readtools/graph_executor.go index 5a4f762..f301599 100644 --- a/internal/ai/runtime/readtools/graph_executor.go +++ b/internal/ai/runtime/readtools/graph_executor.go @@ -9,11 +9,11 @@ import ( "strings" "time" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/retrievers" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/retrievers" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) func ExecuteGraphTool(ctx context.Context, conversation models.Conversation, toolCode string, arguments map[string]any, policy aitooling.Policy) (aitooling.Definition, string, error) { diff --git a/internal/ai/runtime/readtools/graph_executor_test.go b/internal/ai/runtime/readtools/graph_executor_test.go index 4d479c8..92de4b6 100644 --- a/internal/ai/runtime/readtools/graph_executor_test.go +++ b/internal/ai/runtime/readtools/graph_executor_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/toolx" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) func TestExecuteGraphToolRejectsDisallowedToolBeforeGraphExecution(t *testing.T) { diff --git a/internal/ai/runtime/registry/registry.go b/internal/ai/runtime/registry/registry.go index b9391f2..f51ed50 100644 --- a/internal/ai/runtime/registry/registry.go +++ b/internal/ai/runtime/registry/registry.go @@ -3,7 +3,7 @@ package registry import ( "strings" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" ) diff --git a/internal/ai/runtime/registry/registry_test.go b/internal/ai/runtime/registry/registry_test.go index f0b4240..a140200 100644 --- a/internal/ai/runtime/registry/registry_test.go +++ b/internal/ai/runtime/registry/registry_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/registry/types.go b/internal/ai/runtime/registry/types.go index ec578b2..eac0a37 100644 --- a/internal/ai/runtime/registry/types.go +++ b/internal/ai/runtime/registry/types.go @@ -1,9 +1,9 @@ package registry import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" ) diff --git a/internal/ai/runtime/reply_commit_service.go b/internal/ai/runtime/reply_commit_service.go index 56b7110..72ec960 100644 --- a/internal/ai/runtime/reply_commit_service.go +++ b/internal/ai/runtime/reply_commit_service.go @@ -4,14 +4,14 @@ import ( "fmt" "strings" - aitooling "agent-desk/internal/ai/tooling" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - svc "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/runtime/reply_commit_service_test.go b/internal/ai/runtime/reply_commit_service_test.go index ca18ed2..1884114 100644 --- a/internal/ai/runtime/reply_commit_service_test.go +++ b/internal/ai/runtime/reply_commit_service_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/ai/runtime/reply_context.go b/internal/ai/runtime/reply_context.go index 29151a6..35c8b3b 100644 --- a/internal/ai/runtime/reply_context.go +++ b/internal/ai/runtime/reply_context.go @@ -1,8 +1,8 @@ package runtime import ( - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/models" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) type aiReplyContext struct { diff --git a/internal/ai/runtime/reply_eligibility.go b/internal/ai/runtime/reply_eligibility.go index d2d2ae4..621fe89 100644 --- a/internal/ai/runtime/reply_eligibility.go +++ b/internal/ai/runtime/reply_eligibility.go @@ -5,8 +5,8 @@ import ( "encoding/binary" "fmt" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/mlogclub/simple/common/strs" ) diff --git a/internal/ai/runtime/reply_helpers_test.go b/internal/ai/runtime/reply_helpers_test.go index cd22ed1..0ee8f8a 100644 --- a/internal/ai/runtime/reply_helpers_test.go +++ b/internal/ai/runtime/reply_helpers_test.go @@ -3,8 +3,8 @@ package runtime import ( "testing" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/models" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestExtractInterruptMessageAndCheckpointError(t *testing.T) { diff --git a/internal/ai/runtime/reply_interrupt_helpers.go b/internal/ai/runtime/reply_interrupt_helpers.go index e4a471c..6818109 100644 --- a/internal/ai/runtime/reply_interrupt_helpers.go +++ b/internal/ai/runtime/reply_interrupt_helpers.go @@ -5,10 +5,10 @@ import ( "strings" "time" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) type interruptMessagePreview struct { diff --git a/internal/ai/runtime/reply_interrupt_service.go b/internal/ai/runtime/reply_interrupt_service.go index 43c47e5..d469f89 100644 --- a/internal/ai/runtime/reply_interrupt_service.go +++ b/internal/ai/runtime/reply_interrupt_service.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/ai/runtime/graphs" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) type replyInterruptService struct{} diff --git a/internal/ai/runtime/reply_service.go b/internal/ai/runtime/reply_service.go index 5e11ebd..b4ca21c 100644 --- a/internal/ai/runtime/reply_service.go +++ b/internal/ai/runtime/reply_service.go @@ -3,8 +3,8 @@ package runtime import ( "strings" - applicationruntime "agent-desk/internal/ai/application/runtime" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) var AIReplyService = newAIReplyService() diff --git a/internal/ai/runtime/reply_service_test.go b/internal/ai/runtime/reply_service_test.go index 9f44e9d..cac3e43 100644 --- a/internal/ai/runtime/reply_service_test.go +++ b/internal/ai/runtime/reply_service_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestReplyEligibilityCanReply(t *testing.T) { diff --git a/internal/ai/runtime/reply_trigger_service.go b/internal/ai/runtime/reply_trigger_service.go index f3a18e0..f61865c 100644 --- a/internal/ai/runtime/reply_trigger_service.go +++ b/internal/ai/runtime/reply_trigger_service.go @@ -6,11 +6,11 @@ import ( "strings" "time" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/tracex" - svc "agent-desk/internal/services" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" + svc "code.tczkiot.com/wlw/ai-agent/internal/services" ) func (s *aiReplyService) resolveReplyTimeout(aiAgent models.AIAgent) time.Duration { diff --git a/internal/ai/runtime/retrievers/knowledge_retriever.go b/internal/ai/runtime/retrievers/knowledge_retriever.go index 661799b..d78c363 100644 --- a/internal/ai/runtime/retrievers/knowledge_retriever.go +++ b/internal/ai/runtime/retrievers/knowledge_retriever.go @@ -4,11 +4,11 @@ import ( "context" "strings" - "agent-desk/internal/ai/rag" - "agent-desk/internal/ai/runtime/traces" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/traces" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/ai/runtime/runtime_reply_executor.go b/internal/ai/runtime/runtime_reply_executor.go index 9e670ed..7416bec 100644 --- a/internal/ai/runtime/runtime_reply_executor.go +++ b/internal/ai/runtime/runtime_reply_executor.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - applicationruntime "agent-desk/internal/ai/application/runtime" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/models" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) type runtimeReplyExecutor struct{} diff --git a/internal/ai/runtime/service.go b/internal/ai/runtime/service.go index 49abfd9..a63a5a0 100644 --- a/internal/ai/runtime/service.go +++ b/internal/ai/runtime/service.go @@ -3,7 +3,7 @@ package runtime import ( "context" - applicationruntime "agent-desk/internal/ai/application/runtime" + applicationruntime "code.tczkiot.com/wlw/ai-agent/internal/ai/application/runtime" ) var Service = newService() diff --git a/internal/ai/runtime/tooling/tool_result_reducer.go b/internal/ai/runtime/tooling/tool_result_reducer.go index bea27dc..e6737e0 100644 --- a/internal/ai/runtime/tooling/tool_result_reducer.go +++ b/internal/ai/runtime/tooling/tool_result_reducer.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "agent-desk/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" ) const ( diff --git a/internal/ai/runtime/tooling/tool_result_reducer_test.go b/internal/ai/runtime/tooling/tool_result_reducer_test.go index 6eb8c23..63ca9df 100644 --- a/internal/ai/runtime/tooling/tool_result_reducer_test.go +++ b/internal/ai/runtime/tooling/tool_result_reducer_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "agent-desk/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" ) func TestBuildReducedToolResultSummaryDeduplicatesStructuredAndTextContent(t *testing.T) { diff --git a/internal/ai/runtime/tools/analyze_conversation_tool.go b/internal/ai/runtime/tools/analyze_conversation_tool.go index dd0315a..01cff9a 100644 --- a/internal/ai/runtime/tools/analyze_conversation_tool.go +++ b/internal/ai/runtime/tools/analyze_conversation_tool.go @@ -3,11 +3,11 @@ package tools import ( "context" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/tools/create_ticket_confirm_tool.go b/internal/ai/runtime/tools/create_ticket_confirm_tool.go index 7d0145f..910bd79 100644 --- a/internal/ai/runtime/tools/create_ticket_confirm_tool.go +++ b/internal/ai/runtime/tools/create_ticket_confirm_tool.go @@ -3,11 +3,11 @@ package tools import ( "context" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/tools/handoff_graph_tool.go b/internal/ai/runtime/tools/handoff_graph_tool.go index c21e2e6..ffc8f39 100644 --- a/internal/ai/runtime/tools/handoff_graph_tool.go +++ b/internal/ai/runtime/tools/handoff_graph_tool.go @@ -3,11 +3,11 @@ package tools import ( "context" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/tools/helper.go b/internal/ai/runtime/tools/helper.go index 9fb02e8..003df40 100644 --- a/internal/ai/runtime/tools/helper.go +++ b/internal/ai/runtime/tools/helper.go @@ -3,8 +3,8 @@ package tools import ( "strings" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) type Decision string diff --git a/internal/ai/runtime/tools/helper_test.go b/internal/ai/runtime/tools/helper_test.go index 9db43fc..e39e795 100644 --- a/internal/ai/runtime/tools/helper_test.go +++ b/internal/ai/runtime/tools/helper_test.go @@ -3,7 +3,7 @@ package tools import ( "testing" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) func TestNewRuntimeStaticTool(t *testing.T) { diff --git a/internal/ai/runtime/tools/prepare_ticket_draft_tool.go b/internal/ai/runtime/tools/prepare_ticket_draft_tool.go index 8c551c7..8641f79 100644 --- a/internal/ai/runtime/tools/prepare_ticket_draft_tool.go +++ b/internal/ai/runtime/tools/prepare_ticket_draft_tool.go @@ -3,11 +3,11 @@ package tools import ( "context" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/tools/tool_search_tool.go b/internal/ai/runtime/tools/tool_search_tool.go index ce56cac..66133b3 100644 --- a/internal/ai/runtime/tools/tool_search_tool.go +++ b/internal/ai/runtime/tools/tool_search_tool.go @@ -7,12 +7,12 @@ import ( "slices" "strings" - "agent-desk/internal/ai/mcps" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/ai/runtime/tooling" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/tooling" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/tools/triage_service_request_tool.go b/internal/ai/runtime/tools/triage_service_request_tool.go index 24eab35..b02f44d 100644 --- a/internal/ai/runtime/tools/triage_service_request_tool.go +++ b/internal/ai/runtime/tools/triage_service_request_tool.go @@ -3,11 +3,11 @@ package tools import ( "context" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" diff --git a/internal/ai/runtime/workflow/executor.go b/internal/ai/runtime/workflow/executor.go index 1633a9c..298ce05 100644 --- a/internal/ai/runtime/workflow/executor.go +++ b/internal/ai/runtime/workflow/executor.go @@ -11,16 +11,16 @@ import ( "strings" "time" - "agent-desk/internal/ai" - "agent-desk/internal/ai/runtime/graphs" - "agent-desk/internal/ai/runtime/readtools" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/graphs" + "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime/readtools" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) const maxWorkflowSteps = 128 diff --git a/internal/ai/runtime/workflow/executor_test.go b/internal/ai/runtime/workflow/executor_test.go index ecf08d6..c7a6d88 100644 --- a/internal/ai/runtime/workflow/executor_test.go +++ b/internal/ai/runtime/workflow/executor_test.go @@ -3,15 +3,17 @@ package workflow import ( "context" "encoding/json" + "slices" "strings" "testing" "time" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" @@ -913,7 +915,6 @@ func setupWorkflowExecutorHandoffDB(t *testing.T) *gorm.DB { } }) if err := db.AutoMigrate( - &models.User{}, &models.Customer{}, &models.CustomerIdentity{}, &models.AIAgent{}, @@ -975,14 +976,20 @@ func createWorkflowExecutorHandoffActiveSchedule(t *testing.T, db *gorm.DB, team func createWorkflowExecutorHandoffAgentProfile(t *testing.T, db *gorm.DB, userID int64, teamID int64) { t.Helper() - if err := db.Create(&models.User{ - ID: userID, - Username: "agent", - Nickname: "客服", - Status: enums.StatusOk, - }).Error; err != nil { - t.Fatalf("create user error = %v", err) - } + services.SetQuerySubjects(func(_ context.Context, query identity.Query) ([]identity.Subject, error) { + if len(query.IDs) > 0 && !slices.Contains(query.IDs, userID) { + return nil, nil + } + return []identity.Subject{{ + Type: identity.SubjectAgent, + Category: identity.CategorySystem, + ID: userID, + Username: "agent", + Name: "客服", + Identifier: "agent", + Enabled: true, + }}, nil + }) if err := db.Create(&models.AgentProfile{ UserID: userID, TeamID: teamID, diff --git a/internal/ai/tool_loop.go b/internal/ai/tool_loop.go index 578154d..2ed572c 100644 --- a/internal/ai/tool_loop.go +++ b/internal/ai/tool_loop.go @@ -8,7 +8,7 @@ import ( openai "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/shared" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) type ToolDefinition struct { diff --git a/internal/ai/tool_loop_test.go b/internal/ai/tool_loop_test.go index 84500d2..629cb06 100644 --- a/internal/ai/tool_loop_test.go +++ b/internal/ai/tool_loop_test.go @@ -8,8 +8,8 @@ import ( "sync/atomic" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func TestChatWithToolsExecutesToolAndContinuesConversation(t *testing.T) { diff --git a/internal/ai/tooling/executor.go b/internal/ai/tooling/executor.go index d6c0147..a17a6e5 100644 --- a/internal/ai/tooling/executor.go +++ b/internal/ai/tooling/executor.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "agent-desk/internal/ai/mcps" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) // MCPExecutor is the single execution boundary for dynamically discovered diff --git a/internal/ai/tooling/registry.go b/internal/ai/tooling/registry.go index 120e020..9a25a07 100644 --- a/internal/ai/tooling/registry.go +++ b/internal/ai/tooling/registry.go @@ -6,8 +6,8 @@ import ( "fmt" "strings" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) const ( diff --git a/internal/ai/tooling/registry_test.go b/internal/ai/tooling/registry_test.go index fa4c226..4088a25 100644 --- a/internal/ai/tooling/registry_test.go +++ b/internal/ai/tooling/registry_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) func TestRegistryResolvesRegisteredToolPolicy(t *testing.T) { diff --git a/internal/ai/workflow/dsl/types_test.go b/internal/ai/workflow/dsl/types_test.go index e1e4b7c..de523a1 100644 --- a/internal/ai/workflow/dsl/types_test.go +++ b/internal/ai/workflow/dsl/types_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "agent-desk/internal/ai/workflow/dsl" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" ) func TestDefinitionUnmarshalsFlowGramStyleSchema(t *testing.T) { diff --git a/internal/ai/workflow/registry/registry.go b/internal/ai/workflow/registry/registry.go index e627c42..021883e 100644 --- a/internal/ai/workflow/registry/registry.go +++ b/internal/ai/workflow/registry/registry.go @@ -1,6 +1,6 @@ package registry -import "agent-desk/internal/ai/workflow/dsl" +import "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" const ( NodeTypeStart = "start" diff --git a/internal/ai/workflow/registry/spec.go b/internal/ai/workflow/registry/spec.go index 192fa8b..5c80d43 100644 --- a/internal/ai/workflow/registry/spec.go +++ b/internal/ai/workflow/registry/spec.go @@ -1,6 +1,6 @@ package registry -import "agent-desk/internal/ai/workflow/dsl" +import "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" type NodeRiskLevel string diff --git a/internal/ai/workflow/validator/validator.go b/internal/ai/workflow/validator/validator.go index 598111b..b296122 100644 --- a/internal/ai/workflow/validator/validator.go +++ b/internal/ai/workflow/validator/validator.go @@ -5,8 +5,8 @@ import ( "fmt" "strings" - "agent-desk/internal/ai/workflow/dsl" - "agent-desk/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" ) type Error struct { diff --git a/internal/ai/workflow/validator/validator_test.go b/internal/ai/workflow/validator/validator_test.go index f8b22e4..0b8c326 100644 --- a/internal/ai/workflow/validator/validator_test.go +++ b/internal/ai/workflow/validator/validator_test.go @@ -5,9 +5,9 @@ import ( "strings" "testing" - "agent-desk/internal/ai/workflow/dsl" - "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/ai/workflow/validator" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/validator" ) func TestValidateDefinitionAcceptsMinimalFlowGramStyleFlow(t *testing.T) { diff --git a/internal/bootstrap/banner.go b/internal/bootstrap/banner.go index ce709ad..833f1bf 100644 --- a/internal/bootstrap/banner.go +++ b/internal/bootstrap/banner.go @@ -5,7 +5,7 @@ import ( "io" "os" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func printBanner() { diff --git a/internal/bootstrap/banner_test.go b/internal/bootstrap/banner_test.go index ac92790..11377ba 100644 --- a/internal/bootstrap/banner_test.go +++ b/internal/bootstrap/banner_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func TestRenderBanner(t *testing.T) { diff --git a/internal/bootstrap/db.go b/internal/bootstrap/db.go index f567bf1..f26a4b0 100644 --- a/internal/bootstrap/db.go +++ b/internal/bootstrap/db.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "github.com/mlogclub/simple/sqls" "gorm.io/driver/mysql" diff --git a/internal/bootstrap/db_test.go b/internal/bootstrap/db_test.go index 2de2917..c317108 100644 --- a/internal/bootstrap/db_test.go +++ b/internal/bootstrap/db_test.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func TestNewDialector(t *testing.T) { diff --git a/internal/bootstrap/init.go b/internal/bootstrap/init.go index 21d1bae..3d639bf 100644 --- a/internal/bootstrap/init.go +++ b/internal/bootstrap/init.go @@ -1,17 +1,15 @@ package bootstrap import ( - "agent-desk/internal/ai/rag/vectordb" - "agent-desk/internal/oidcclient" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/logx" - "agent-desk/internal/services/cronx" - "agent-desk/internal/wxwork" - "context" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag/vectordb" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/logx" + "code.tczkiot.com/wlw/ai-agent/internal/services/cronx" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "log/slog" - _ "agent-desk/internal/services/event_handlers" + _ "code.tczkiot.com/wlw/ai-agent/internal/services/event_handlers" ) func Init(configPath string) error { @@ -46,9 +44,5 @@ func Init(configPath string) error { cronx.Init() wxwork.Init() - if err := oidcclient.Init(context.Background()); err != nil { - slog.Error("init oidc failed", "error", err) - return err - } return nil } diff --git a/internal/bootstrap/migration.go b/internal/bootstrap/migration.go index fd5afcd..3fece14 100644 --- a/internal/bootstrap/migration.go +++ b/internal/bootstrap/migration.go @@ -1,8 +1,8 @@ package bootstrap import ( - "agent-desk/internal/migration" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/migration" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/bootstrap/routes.go b/internal/bootstrap/routes.go index 234b4e7..c438df7 100644 --- a/internal/bootstrap/routes.go +++ b/internal/bootstrap/routes.go @@ -1,34 +1,17 @@ package bootstrap import ( - "agent-desk/internal/handlers/api" - "agent-desk/internal/handlers/dashboard" - "agent-desk/internal/handlers/third" + "code.tczkiot.com/wlw/ai-agent/internal/handlers/api" + "code.tczkiot.com/wlw/ai-agent/internal/handlers/dashboard" + "code.tczkiot.com/wlw/ai-agent/internal/handlers/third" "github.com/gin-gonic/gin" ) -func registerApiAuthRoutes(group *gin.RouterGroup) { - group.POST("/login", api.Login) - group.POST("/logout", api.Logout) - group.GET("/profile", api.Profile) - group.GET("/wxwork_callback", api.WxWorkCallback) - group.POST("/wxwork_exchange", api.WxWorkExchange) - group.GET("/wxwork_login", api.WxWorkLogin) - group.GET("/wxwork_qr_login", api.WxWorkQRLogin) - group.GET("/oidc_callback", api.OIDCCallback) - group.POST("/oidc_exchange", api.OIDCExchange) - group.GET("/oidc_login", api.OIDCLogin) -} - func registerApiChannelRoutes(group *gin.RouterGroup) { group.Any("/config", api.ChannelAnyConfig) } -func registerApiCustomerRoutes(group *gin.RouterGroup) { - group.POST("/session_exchange", api.CustomerPostSession_exchange) -} - func registerApiConversationRoutes(group *gin.RouterGroup) { group.GET("/:id", api.ConversationGetBy) group.POST("/close", api.ConversationPostClose) @@ -47,19 +30,6 @@ func registerDashboardDashboardRoutes(group *gin.RouterGroup) { group.GET("/overview", dashboard.DashboardGetOverview) } -func registerDashboardUserRoutes(group *gin.RouterGroup) { - group.GET("/:id", dashboard.UserGetBy) - group.POST("/assign_role", dashboard.UserPostAssign_role) - group.POST("/change_password", dashboard.UserPostChange_password) - group.POST("/create", dashboard.UserPostCreate) - group.POST("/delete", dashboard.UserPostDelete) - group.Any("/list", dashboard.UserAnyList) - group.Any("/list_all", dashboard.UserAnyList_all) - group.POST("/reset_password", dashboard.UserPostReset_password) - group.POST("/update", dashboard.UserPostUpdate) - group.POST("/update_status", dashboard.UserPostUpdate_status) -} - func registerDashboardCompanyRoutes(group *gin.RouterGroup) { group.GET("/:id", dashboard.CompanyGetBy) group.POST("/create", dashboard.CompanyPostCreate) @@ -86,30 +56,6 @@ func registerDashboardCustomerContactRoutes(group *gin.RouterGroup) { group.POST("/update", dashboard.CustomerContactPostUpdate) } -func registerDashboardRoleRoutes(group *gin.RouterGroup) { - group.GET("/:id", dashboard.RoleGetBy) - group.POST("/assign_permission", dashboard.RolePostAssign_permission) - group.POST("/create", dashboard.RolePostCreate) - group.POST("/delete", dashboard.RolePostDelete) - group.Any("/list", dashboard.RoleAnyList) - group.GET("/list_all", dashboard.RoleGetList_all) - group.POST("/update", dashboard.RolePostUpdate) - group.POST("/update_sort", dashboard.RolePostUpdate_sort) - group.POST("/update_status", dashboard.RolePostUpdate_status) -} - -func registerDashboardPermissionRoutes(group *gin.RouterGroup) { - group.GET("/:id", dashboard.PermissionGetBy) - group.Any("/list", dashboard.PermissionAnyList) - group.POST("/sync", dashboard.PermissionPostSync) -} - -func registerDashboardSessionRoutes(group *gin.RouterGroup) { - group.Any("/list", dashboard.SessionAnyList) - group.POST("/revoke", dashboard.SessionPostRevoke) - group.POST("/revoke/by/user", dashboard.SessionPostRevokeByUser) -} - func registerDashboardTagRoutes(group *gin.RouterGroup) { group.GET("/:id", dashboard.TagGetBy) group.POST("/create", dashboard.TagPostCreate) @@ -178,7 +124,6 @@ func registerDashboardChannelRoutes(group *gin.RouterGroup) { group.POST("/create", dashboard.ChannelPostCreate) group.POST("/delete", dashboard.ChannelPostDelete) group.Any("/list", dashboard.ChannelAnyList) - group.POST("/reset_user_token_secret", dashboard.ChannelPostReset_user_token_secret) group.POST("/rollback_ai_agent_rollout", dashboard.ChannelPostRollback_ai_agent_rollout) group.POST("/update", dashboard.ChannelPostUpdate) group.POST("/update_status", dashboard.ChannelPostUpdate_status) @@ -194,6 +139,7 @@ func registerDashboardAgentRoutes(group *gin.RouterGroup) { group.POST("/delete", dashboard.AgentPostDelete) group.Any("/list", dashboard.AgentAnyList) group.GET("/list_all", dashboard.AgentGetList_all) + group.GET("/user-options", dashboard.AgentGetUser_options) group.POST("/update", dashboard.AgentPostUpdate) } diff --git a/internal/bootstrap/server.go b/internal/bootstrap/server.go index 39b6b1e..de5dbb6 100644 --- a/internal/bootstrap/server.go +++ b/internal/bootstrap/server.go @@ -6,21 +6,21 @@ import ( "strings" "time" - "agent-desk/internal/ai/mcps" - _ "agent-desk/internal/ai/runtime" - "agent-desk/internal/handlers/api" - "agent-desk/internal/middleware" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/ginx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/tracex" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + _ "code.tczkiot.com/wlw/ai-agent/internal/ai/runtime" + "code.tczkiot.com/wlw/ai-agent/internal/handlers/api" + "code.tczkiot.com/wlw/ai-agent/internal/middleware" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/ginx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" - _ "agent-desk/internal/services/wx_callback_handlers" + _ "code.tczkiot.com/wlw/ai-agent/internal/services/wx_callback_handlers" ) func NewServer() (*gin.Engine, error) { @@ -60,8 +60,8 @@ func NewServer() (*gin.Engine, error) { func corsMiddleware() gin.HandlerFunc { allowedOrigins := config.Current().Server.CORS.AllowedOrigins - allowHeaders := "Origin, Content-Type, Accept, Authorization, X-Requested-With, X-Guest-Id, X-Channel-Id, X-External-Id, X-External-Name, X-Customer-Session-Token, X-Customer-Session-Expires-At" - exposeHeaders := "Content-Length, Content-Type, Authorization, X-Guest-Id, X-Channel-Id, X-External-Id, X-External-Name, X-Customer-Session-Token, X-Customer-Session-Expires-At" + allowHeaders := "Origin, Content-Type, Accept, Authorization, X-Requested-With, X-Channel-Id" + exposeHeaders := "Content-Length, Content-Type, Authorization" allowMethods := "GET, POST, PUT, PATCH, DELETE, OPTIONS" allowedOriginSet := make(map[string]struct{}, len(allowedOrigins)) for _, origin := range allowedOrigins { @@ -152,9 +152,7 @@ func addRouter(app *gin.Engine) { apiGroup := app.Group("/api") apiGroup.GET("/health", api.Health) apiGroup.GET("/config", api.PublicConfig) - registerApiAuthRoutes(apiGroup.Group("/auth")) registerApiChannelRoutes(apiGroup.Group("/channel")) - registerApiCustomerRoutes(apiGroup.Group("/customer")) registerApiConversationRoutes(apiGroup.Group("/conversation", middleware.ExternalUserMiddleware)) registerApiMessageRoutes(apiGroup.Group("/message", middleware.ExternalUserMiddleware)) @@ -165,13 +163,9 @@ func addRouter(app *gin.Engine) { dashboardGroup := app.Group("/api/dashboard", middleware.AuthMiddleware) registerDashboardDashboardRoutes(dashboardGroup.Group("/dashboard")) - registerDashboardUserRoutes(dashboardGroup.Group("/user")) registerDashboardCompanyRoutes(dashboardGroup.Group("/company")) registerDashboardCustomerRoutes(dashboardGroup.Group("/customer")) registerDashboardCustomerContactRoutes(dashboardGroup.Group("/customer-contact")) - registerDashboardRoleRoutes(dashboardGroup.Group("/role")) - registerDashboardPermissionRoutes(dashboardGroup.Group("/permission")) - registerDashboardSessionRoutes(dashboardGroup.Group("/session")) registerDashboardTagRoutes(dashboardGroup.Group("/tag")) registerDashboardConversationRoutes(dashboardGroup.Group("/conversation")) registerDashboardTicketRoutes(dashboardGroup.Group("/ticket")) diff --git a/internal/bootstrap/server_route_test.go b/internal/bootstrap/server_route_test.go index 22e7e91..b8980ce 100644 --- a/internal/bootstrap/server_route_test.go +++ b/internal/bootstrap/server_route_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" ) func TestNewServerRegistersGinRoutes(t *testing.T) { @@ -31,16 +31,8 @@ func TestNewServerRegistersGinRoutes(t *testing.T) { } expected := []string{ - http.MethodPost + " /api/auth/login", http.MethodGet + " /api/config", http.MethodGet + " /api/health", - http.MethodGet + " /api/auth/oidc_login", - http.MethodGet + " /api/auth/oidc_callback", - http.MethodPost + " /api/auth/oidc_exchange", - http.MethodGet + " /api/auth/profile", - http.MethodGet + " /api/dashboard/user/list", - http.MethodGet + " /api/dashboard/user/:id", - http.MethodPost + " /api/dashboard/user/create", http.MethodPost + " /api/dashboard/conversation/send_message", http.MethodGet + " /api/dashboard/ai-workflow/default-definition", http.MethodGet + " /api/dashboard/ai-workflow/template/list", @@ -61,6 +53,20 @@ func TestNewServerRegistersGinRoutes(t *testing.T) { t.Fatalf("expected route %s to be registered", route) } } + + removed := []string{ + http.MethodPost + " /api/auth/login", + http.MethodGet + " /api/auth/profile", + http.MethodGet + " /api/dashboard/user/list", + http.MethodGet + " /api/dashboard/role/list", + http.MethodGet + " /api/dashboard/permission/list", + http.MethodGet + " /api/dashboard/session/list", + } + for _, route := range removed { + if routes[route] { + t.Fatalf("removed local auth route %s is still registered", route) + } + } } func TestNewServerHealthEndpointIsPublic(t *testing.T) { @@ -114,10 +120,6 @@ func TestNewServerExposesPublicConfig(t *testing.T) { WxWork: config.WxWorkConfig{ Enabled: true, }, - OIDC: config.OIDCConfig{ - Enabled: false, - ClientSecret: "must-not-leak", - }, }) app, err := NewServer() @@ -135,9 +137,7 @@ func TestNewServerExposesPublicConfig(t *testing.T) { var body struct { Success bool `json:"success"` Data struct { - Language string `json:"language"` - WxWorkEnabled bool `json:"wxworkEnabled"` - OIDCEnabled bool `json:"oidcEnabled"` + Language string `json:"language"` } `json:"data"` } if err := json.Unmarshal(rec.Body.Bytes(), &body); err != nil { @@ -149,14 +149,8 @@ func TestNewServerExposesPublicConfig(t *testing.T) { if body.Data.Language != "zh-CN" { t.Fatalf("language=%q want zh-CN", body.Data.Language) } - if !body.Data.WxWorkEnabled { - t.Fatalf("wxworkEnabled=false want true") - } - if body.Data.OIDCEnabled { - t.Fatalf("oidcEnabled=true want false") - } - if strings.Contains(rec.Body.String(), "must-not-leak") { - t.Fatalf("response leaked sensitive OIDC config: %s", rec.Body.String()) + if strings.Contains(rec.Body.String(), "wxworkEnabled") || strings.Contains(rec.Body.String(), "oidcEnabled") { + t.Fatalf("response still exposes removed login options: %s", rec.Body.String()) } } diff --git a/internal/builders/agent_profile_builder.go b/internal/builders/agent_profile_builder.go index 8179de8..1cb41fb 100644 --- a/internal/builders/agent_profile_builder.go +++ b/internal/builders/agent_profile_builder.go @@ -1,10 +1,10 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) func BuildAgentProfileList(items []models.AgentProfile) []response.AgentProfileResponse { @@ -26,7 +26,7 @@ func BuildAgentProfileList(items []models.AgentProfile) []response.AgentProfileR users := services.UserService.FindByIds(userIDs) teams := services.AgentTeamService.FindByIds(teamIDs) - userMap := make(map[int64]*models.User, len(users)) + userMap := make(map[int64]*services.ExternalUser, len(users)) for i := range users { userMap[users[i].ID] = &users[i] } @@ -51,7 +51,7 @@ func BuildAgentProfileResponse(item *models.AgentProfile) *response.AgentProfile return doBuildAgentProfileResponse(item, user, team) } -func doBuildAgentProfileResponse(item *models.AgentProfile, user *models.User, team *models.AgentTeam) *response.AgentProfileResponse { +func doBuildAgentProfileResponse(item *models.AgentProfile, user *services.ExternalUser, team *models.AgentTeam) *response.AgentProfileResponse { if item == nil { return nil } diff --git a/internal/builders/agent_revision_builder.go b/internal/builders/agent_revision_builder.go index eb24cdc..70680f6 100644 --- a/internal/builders/agent_revision_builder.go +++ b/internal/builders/agent_revision_builder.go @@ -1,8 +1,8 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" ) func BuildAgentRevision(item *models.AgentRevision) response.AgentRevisionResponse { diff --git a/internal/builders/agent_run_builder.go b/internal/builders/agent_run_builder.go index d7554ba..1bc13fb 100644 --- a/internal/builders/agent_run_builder.go +++ b/internal/builders/agent_run_builder.go @@ -3,8 +3,8 @@ package builders import ( "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" ) func BuildAgentRun(item *models.AgentRun) response.AgentRunResponse { diff --git a/internal/builders/agent_team_schedule_builder.go b/internal/builders/agent_team_schedule_builder.go index 3e314a9..5d23bf2 100644 --- a/internal/builders/agent_team_schedule_builder.go +++ b/internal/builders/agent_team_schedule_builder.go @@ -1,8 +1,8 @@ package builders import ( - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/services" "time" ) diff --git a/internal/builders/ai_workflow_builder.go b/internal/builders/ai_workflow_builder.go index 7fcf5d8..08c2b49 100644 --- a/internal/builders/ai_workflow_builder.go +++ b/internal/builders/ai_workflow_builder.go @@ -4,11 +4,11 @@ import ( "encoding/json" "time" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) func BuildAIWorkflow(item *models.AIWorkflow) response.AIWorkflowResponse { diff --git a/internal/builders/ai_workflow_builder_test.go b/internal/builders/ai_workflow_builder_test.go index 93389da..a2926f1 100644 --- a/internal/builders/ai_workflow_builder_test.go +++ b/internal/builders/ai_workflow_builder_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestBuildAIWorkflowNodeSpecsIncludesVariableContracts(t *testing.T) { diff --git a/internal/builders/asset_builder.go b/internal/builders/asset_builder.go index 52e1f66..c743851 100644 --- a/internal/builders/asset_builder.go +++ b/internal/builders/asset_builder.go @@ -1,9 +1,9 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/services/storage" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/services/storage" "log/slog" ) diff --git a/internal/builders/company_builder.go b/internal/builders/company_builder.go index d1651f0..1641466 100644 --- a/internal/builders/company_builder.go +++ b/internal/builders/company_builder.go @@ -1,8 +1,8 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" "time" ) diff --git a/internal/builders/conversation_builder.go b/internal/builders/conversation_builder.go index 0846aec..88a7094 100644 --- a/internal/builders/conversation_builder.go +++ b/internal/builders/conversation_builder.go @@ -3,12 +3,12 @@ package builders import ( "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/builders/conversation_builder_test.go b/internal/builders/conversation_builder_test.go index 78cc802..3fb1dae 100644 --- a/internal/builders/conversation_builder_test.go +++ b/internal/builders/conversation_builder_test.go @@ -5,9 +5,9 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" ) func TestLocalizeConversationSummary(t *testing.T) { diff --git a/internal/builders/customer_builder.go b/internal/builders/customer_builder.go index 2ea02c6..670feea 100644 --- a/internal/builders/customer_builder.go +++ b/internal/builders/customer_builder.go @@ -1,10 +1,10 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/services" "time" ) diff --git a/internal/builders/customer_contact_builder.go b/internal/builders/customer_contact_builder.go index b7d1325..f1c39ca 100644 --- a/internal/builders/customer_contact_builder.go +++ b/internal/builders/customer_contact_builder.go @@ -1,9 +1,9 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" "time" ) diff --git a/internal/builders/knowledge_builder.go b/internal/builders/knowledge_builder.go index f5833fc..d630d21 100644 --- a/internal/builders/knowledge_builder.go +++ b/internal/builders/knowledge_builder.go @@ -1,9 +1,9 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "encoding/json" ) diff --git a/internal/builders/notification_builder.go b/internal/builders/notification_builder.go index 16f84a6..419feaf 100644 --- a/internal/builders/notification_builder.go +++ b/internal/builders/notification_builder.go @@ -1,10 +1,10 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" "regexp" "strings" ) diff --git a/internal/builders/notification_builder_test.go b/internal/builders/notification_builder_test.go index ebd4a90..4a46c10 100644 --- a/internal/builders/notification_builder_test.go +++ b/internal/builders/notification_builder_test.go @@ -3,8 +3,8 @@ package builders import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" ) func TestBuildNotificationListReturnsEmptySlice(t *testing.T) { diff --git a/internal/builders/quick_reply_builder.go b/internal/builders/quick_reply_builder.go index d46138e..34f4791 100644 --- a/internal/builders/quick_reply_builder.go +++ b/internal/builders/quick_reply_builder.go @@ -1,8 +1,8 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" ) func BuildQuickReplyResponse(item *models.QuickReply) *response.QuickReplyResponse { diff --git a/internal/builders/skill_builder.go b/internal/builders/skill_builder.go index ed53208..600660b 100644 --- a/internal/builders/skill_builder.go +++ b/internal/builders/skill_builder.go @@ -3,9 +3,9 @@ package builders import ( "encoding/json" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) func BuildSkillDefinitionResponse(item *models.SkillDefinition) response.SkillDefinitionResponse { diff --git a/internal/builders/tag_builder.go b/internal/builders/tag_builder.go index d27a21d..1076dc8 100644 --- a/internal/builders/tag_builder.go +++ b/internal/builders/tag_builder.go @@ -1,8 +1,8 @@ package builders import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" "time" ) diff --git a/internal/builders/ticket_builder.go b/internal/builders/ticket_builder.go index a1dcb91..63d0dfb 100644 --- a/internal/builders/ticket_builder.go +++ b/internal/builders/ticket_builder.go @@ -4,20 +4,20 @@ import ( "encoding/json" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) type TicketBuildContext struct { TagsByTicketID map[int64][]models.Tag - Users map[int64]*models.User + Users map[int64]*services.ExternalUser Customers map[int64]*models.Customer } type TicketDetailBuildContext struct { - Users map[int64]*models.User + Users map[int64]*services.ExternalUser } func BuildTicket(item *models.Ticket) *response.TicketResponse { @@ -180,7 +180,7 @@ func BuildTicketViewList(list []models.TicketView) []response.TicketViewResponse return results } -func buildTicketUserDisplayName(user *models.User) string { +func buildTicketUserDisplayName(user *services.ExternalUser) string { if user == nil { return "" } diff --git a/internal/builders/ticket_builder_test.go b/internal/builders/ticket_builder_test.go index 0515de1..d5a26b0 100644 --- a/internal/builders/ticket_builder_test.go +++ b/internal/builders/ticket_builder_test.go @@ -4,8 +4,9 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" ) func TestBuildLightweightTicket(t *testing.T) { @@ -32,7 +33,7 @@ func TestBuildLightweightTicket(t *testing.T) { TagsByTicketID: map[int64][]models.Tag{ 12: {{ID: 8, Name: "登录", Status: enums.StatusOk}}, }, - Users: map[int64]*models.User{ + Users: map[int64]*services.ExternalUser{ 5: {ID: 5, Username: "agent", Nickname: "客服"}, }, Customers: map[int64]*models.Customer{ @@ -101,7 +102,7 @@ func TestBuildTicketProgress(t *testing.T) { CreatedAt: now, } ctx := &TicketDetailBuildContext{ - Users: map[int64]*models.User{ + Users: map[int64]*services.ExternalUser{ 3: {ID: 3, Username: "agent", Nickname: "客服"}, }, } diff --git a/internal/builders/user_builder.go b/internal/builders/user_builder.go deleted file mode 100644 index 893923e..0000000 --- a/internal/builders/user_builder.go +++ /dev/null @@ -1,68 +0,0 @@ -package builders - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" -) - -type UserBuildOptions struct { - Roles bool - Permissions bool -} - -func BuildUserList(items []models.User, options UserBuildOptions) []response.UserResponse { - results := make([]response.UserResponse, 0, len(items)) - for _, item := range items { - results = append(results, *BuildUserResponse(&item, options)) - } - return results -} - -func BuildUserResponse(item *models.User, options UserBuildOptions) *response.UserResponse { - if item == nil { - return nil - } - ret := &response.UserResponse{ - ID: item.ID, - Username: item.Username, - Nickname: item.Nickname, - Avatar: item.Avatar, - Status: item.Status, - LastLoginAt: utils.FormatTimePtr(item.LastLoginAt), - LastLoginIP: item.LastLoginIP, - } - - if item.Mobile != nil { - ret.Mobile = *item.Mobile - } - if item.Email != nil { - ret.Email = *item.Email - } - - if options.Roles { - ret.Roles = buildAssignedRoles(item.ID) - } - if options.Permissions { - permissionCodes, _ := services.AuthService.GetUserPermissions(item.ID) - ret.Permissions = permissionCodes - } - return ret -} - -func buildAssignedRoles(userID int64) []response.RoleResponse { - roles, _ := services.AuthService.GetUserRoles(userID) - results := make([]response.RoleResponse, 0, len(roles)) - for _, role := range roles { - results = append(results, response.RoleResponse{ - ID: role.ID, - Name: role.Name, - Code: role.Code, - Status: role.Status, - IsSystem: role.IsSystem, - SortNo: role.SortNo, - }) - } - return results -} diff --git a/internal/handlers/api/auth_handler.go b/internal/handlers/api/auth_handler.go deleted file mode 100644 index c385b1b..0000000 --- a/internal/handlers/api/auth_handler.go +++ /dev/null @@ -1,160 +0,0 @@ -package api - -import ( - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/services" - "net/http" - "net/url" - "strings" - - "github.com/gin-gonic/gin" -) - -func Login(ctx *gin.Context) { - cfg := config.Current() - req := request.LoginRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - ret, err := services.AuthService.Login(req, cfg.Auth, ctx.ClientIP(), ctx.GetHeader("User-Agent")) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, ret) -} - -func PublicConfig(ctx *gin.Context) { - cfg := config.Current() - httpx.WriteJSON(ctx, &response.PublicConfigResponse{ - Language: cfg.LanguageOrDefault(), - WxWorkEnabled: cfg.WxWork.Enabled, - OIDCEnabled: cfg.OIDC.Enabled, - }) -} - -func WxWorkLogin(ctx *gin.Context) { - loginURL, err := services.WxWorkLoginService.BuildWxWorkLoginURL(ctx.Query("next")) - if err != nil { - redirectToFrontend(ctx, "/login?wxworkError="+url.QueryEscape(wxWorkErrorMessage(err.Error()))) - return - } - ctx.Redirect(http.StatusFound, loginURL) -} - -func WxWorkQRLogin(ctx *gin.Context) { - loginURL, err := services.WxWorkLoginService.BuildWxWorkQRCodeLoginURL(ctx.Query("next")) - if err != nil { - redirectToFrontend(ctx, "/login?wxworkError="+url.QueryEscape(wxWorkErrorMessage(err.Error()))) - return - } - ctx.Redirect(http.StatusFound, loginURL) -} - -func WxWorkCallback(ctx *gin.Context) { - cfg := config.Current() - ticket, next, err := services.WxWorkLoginService.LoginByWxWork( - ctx.Query("code"), - ctx.Query("state"), - cfg.Auth, - ctx.ClientIP(), - ctx.GetHeader("User-Agent"), - ) - if err != nil { - redirectToFrontend(ctx, "/login?wxworkError="+url.QueryEscape(wxWorkErrorMessage(err.Error()))) - return - } - redirectToFrontend(ctx, "/dashboard/login/wxwork/callback?ticket="+url.QueryEscape(ticket)+"&next="+url.QueryEscape(next)) -} - -func WxWorkExchange(ctx *gin.Context) { - req := request.WxWorkExchangeRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - ret, err := services.WxWorkLoginService.ExchangeWxWorkLoginTicket(req.Ticket) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, ret) -} - -func OIDCLogin(ctx *gin.Context) { - loginURL, err := services.OIDCLoginService.BuildOIDCLoginURL(ctx.Query("next")) - if err != nil { - redirectToFrontend(ctx, "/dashboard/login?oidcError="+url.QueryEscape(loginErrorMessage(err.Error()))) - return - } - ctx.Redirect(http.StatusFound, loginURL) -} - -func OIDCCallback(ctx *gin.Context) { - cfg := config.Current() - ticket, next, err := services.OIDCLoginService.LoginByOIDC( - ctx.Request.Context(), - ctx.Query("code"), - ctx.Query("state"), - cfg.Auth, - ctx.ClientIP(), - ctx.GetHeader("User-Agent"), - ) - if err != nil { - redirectToFrontend(ctx, "/dashboard/login?oidcError="+url.QueryEscape(loginErrorMessage(err.Error()))) - return - } - redirectToFrontend(ctx, "/dashboard/login/oidc/callback?ticket="+url.QueryEscape(ticket)+"&next="+url.QueryEscape(next)) -} - -func OIDCExchange(ctx *gin.Context) { - req := request.OIDCExchangeRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - ret, err := services.OIDCLoginService.ExchangeOIDCLoginTicket(req.Ticket) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, ret) -} - -func Logout(ctx *gin.Context) { - if err := services.AuthService.Logout(ctx.GetHeader("Authorization")); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func Profile(ctx *gin.Context) { - ret, err := services.AuthService.CurrentProfile(ctx) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, ret) -} - -func wxWorkErrorMessage(message string) string { - return loginErrorMessage(message) -} - -func loginErrorMessage(message string) string { - if idx := strings.Index(message, ": "); idx >= 0 { - message = message[idx+2:] - } - return message -} - -func redirectToFrontend(ctx *gin.Context, path string) { - ctx.Redirect(http.StatusFound, config.Current().Server.FrontendBaseURL()+path) -} diff --git a/internal/handlers/api/channel_handler.go b/internal/handlers/api/channel_handler.go index 28faf49..72716c7 100644 --- a/internal/handlers/api/channel_handler.go +++ b/internal/handlers/api/channel_handler.go @@ -1,11 +1,11 @@ package api import ( - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/api/config_handler.go b/internal/handlers/api/config_handler.go new file mode 100644 index 0000000..98c1fb7 --- /dev/null +++ b/internal/handlers/api/config_handler.go @@ -0,0 +1,16 @@ +package api + +import ( + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + + "github.com/gin-gonic/gin" +) + +func PublicConfig(ctx *gin.Context) { + cfg := config.Current() + httpx.WriteJSON(ctx, &response.PublicConfigResponse{ + Language: cfg.LanguageOrDefault(), + }) +} diff --git a/internal/handlers/api/conversation_handler.go b/internal/handlers/api/conversation_handler.go index 93472e1..a47ff77 100644 --- a/internal/handlers/api/conversation_handler.go +++ b/internal/handlers/api/conversation_handler.go @@ -1,14 +1,14 @@ package api import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/api/customer_handler.go b/internal/handlers/api/customer_handler.go deleted file mode 100644 index 18a2b06..0000000 --- a/internal/handlers/api/customer_handler.go +++ /dev/null @@ -1,28 +0,0 @@ -package api - -import ( - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/services" - - "github.com/gin-gonic/gin" -) - -func CustomerPostSession_exchange(ctx *gin.Context) { - channel := services.ChannelService.GetEnabledChannel(ctx) - if channel == nil { - httpx.WriteJSON(ctx, httpx.JsonErrorMsg(ctx, "error.e0209")) - return - } - externalUser, err := openidentity.GetExternalUser(ctx, services.ChannelService.GetUserTokenSecret(channel)) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - resp, err := services.CustomerSessionService.Exchange(channel, *externalUser) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, resp) -} diff --git a/internal/handlers/api/health_handler.go b/internal/handlers/api/health_handler.go index 094ab17..7b97b6a 100644 --- a/internal/handlers/api/health_handler.go +++ b/internal/handlers/api/health_handler.go @@ -1,7 +1,7 @@ package api import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/api/message_handler.go b/internal/handlers/api/message_handler.go index 05cf819..ee309fd 100644 --- a/internal/handlers/api/message_handler.go +++ b/internal/handlers/api/message_handler.go @@ -1,16 +1,16 @@ package api import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "strconv" "strings" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/spf13/cast" diff --git a/internal/handlers/dashboard/agent_handler.go b/internal/handlers/dashboard/agent_handler.go index 6dcd17f..8941bbd 100644 --- a/internal/handlers/dashboard/agent_handler.go +++ b/internal/handlers/dashboard/agent_handler.go @@ -1,13 +1,14 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" @@ -44,6 +45,21 @@ func AgentGetList_all(ctx *gin.Context) { httpx.WriteJSON(ctx, builders.BuildAgentProfileList(list)) } +func AgentGetUser_options(ctx *gin.Context) { + if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionAgentView); err != nil { + httpx.WriteJSON(ctx, err) + return + } + users := services.UserService.Find(ctx.Query("keyword")) + results := make([]response.AgentUserOptionResponse, 0, len(users)) + for _, user := range users { + results = append(results, response.AgentUserOptionResponse{ + ID: user.ID, Username: user.Username, Nickname: user.Nickname, Avatar: user.Avatar, + }) + } + httpx.WriteJSON(ctx, results) +} + func AgentGetBy(ctx *gin.Context) { id, ok := httpx.GetPathInt64(ctx, "id") if !ok { diff --git a/internal/handlers/dashboard/agent_run_handler.go b/internal/handlers/dashboard/agent_run_handler.go index 9e35dbf..6c4a55b 100644 --- a/internal/handlers/dashboard/agent_run_handler.go +++ b/internal/handlers/dashboard/agent_run_handler.go @@ -1,12 +1,12 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/agent_team_handler.go b/internal/handlers/dashboard/agent_team_handler.go index b9c8bdc..623cc9f 100644 --- a/internal/handlers/dashboard/agent_team_handler.go +++ b/internal/handlers/dashboard/agent_team_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/agent_team_schedule_handler.go b/internal/handlers/dashboard/agent_team_schedule_handler.go index 568b13c..9745b91 100644 --- a/internal/handlers/dashboard/agent_team_schedule_handler.go +++ b/internal/handlers/dashboard/agent_team_schedule_handler.go @@ -1,16 +1,16 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/ai_agent_handler.go b/internal/handlers/dashboard/ai_agent_handler.go index 6d7e8e7..9b20811 100644 --- a/internal/handlers/dashboard/ai_agent_handler.go +++ b/internal/handlers/dashboard/ai_agent_handler.go @@ -1,22 +1,22 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "encoding/json" "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/ai_agent_handler_test.go b/internal/handlers/dashboard/ai_agent_handler_test.go index cb5c09e..eb19307 100644 --- a/internal/handlers/dashboard/ai_agent_handler_test.go +++ b/internal/handlers/dashboard/ai_agent_handler_test.go @@ -3,7 +3,7 @@ package dashboard import ( "testing" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/ai_config_handler.go b/internal/handlers/dashboard/ai_config_handler.go index 10a8fe0..50a38a7 100644 --- a/internal/handlers/dashboard/ai_config_handler.go +++ b/internal/handlers/dashboard/ai_config_handler.go @@ -1,14 +1,14 @@ package dashboard import ( - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/ai_workflow_handler.go b/internal/handlers/dashboard/ai_workflow_handler.go index 72fbd48..5791c3d 100644 --- a/internal/handlers/dashboard/ai_workflow_handler.go +++ b/internal/handlers/dashboard/ai_workflow_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/asset_handler.go b/internal/handlers/dashboard/asset_handler.go index 78ac2a3..4b20623 100644 --- a/internal/handlers/dashboard/asset_handler.go +++ b/internal/handlers/dashboard/asset_handler.go @@ -1,16 +1,16 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "strings" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/channel_handler.go b/internal/handlers/dashboard/channel_handler.go index bbf79ed..e64f3be 100644 --- a/internal/handlers/dashboard/channel_handler.go +++ b/internal/handlers/dashboard/channel_handler.go @@ -1,17 +1,17 @@ package dashboard import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "strings" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" @@ -206,25 +206,6 @@ func ChannelPostUpdate_status(ctx *gin.Context) { httpx.WriteJSON(ctx, nil) } -func ChannelPostReset_user_token_secret(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionChannelUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - req := request.ResetChannelUserTokenSecretRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - secret, err := services.ChannelService.ResetUserTokenSecret(req.ID, operator) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, map[string]string{"userTokenSecret": secret}) -} - func ChannelPostDelete(ctx *gin.Context) { operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionChannelDelete) if err != nil { diff --git a/internal/handlers/dashboard/company_handler.go b/internal/handlers/dashboard/company_handler.go index 84b219d..fa3de03 100644 --- a/internal/handlers/dashboard/company_handler.go +++ b/internal/handlers/dashboard/company_handler.go @@ -1,14 +1,14 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/conversation_handler.go b/internal/handlers/dashboard/conversation_handler.go index 50c4c82..163267d 100644 --- a/internal/handlers/dashboard/conversation_handler.go +++ b/internal/handlers/dashboard/conversation_handler.go @@ -1,18 +1,18 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "strconv" "strings" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/common/strs" diff --git a/internal/handlers/dashboard/customer_contact_handler.go b/internal/handlers/dashboard/customer_contact_handler.go index 90e27b2..43f19be 100644 --- a/internal/handlers/dashboard/customer_contact_handler.go +++ b/internal/handlers/dashboard/customer_contact_handler.go @@ -1,13 +1,13 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/dashboard/customer_handler.go b/internal/handlers/dashboard/customer_handler.go index b5c8f95..3cd587e 100644 --- a/internal/handlers/dashboard/customer_handler.go +++ b/internal/handlers/dashboard/customer_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/dashboard_handler.go b/internal/handlers/dashboard/dashboard_handler.go index 3c7e718..23fbbfd 100644 --- a/internal/handlers/dashboard/dashboard_handler.go +++ b/internal/handlers/dashboard/dashboard_handler.go @@ -1,11 +1,11 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/dashboard/knowledge_base_handler.go b/internal/handlers/dashboard/knowledge_base_handler.go index c6b70c3..8696a31 100644 --- a/internal/handlers/dashboard/knowledge_base_handler.go +++ b/internal/handlers/dashboard/knowledge_base_handler.go @@ -1,19 +1,19 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "context" "log/slog" - "agent-desk/internal/ai/rag" - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/repositories" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/knowledge_directory_handler.go b/internal/handlers/dashboard/knowledge_directory_handler.go index 070b647..5c6724c 100644 --- a/internal/handlers/dashboard/knowledge_directory_handler.go +++ b/internal/handlers/dashboard/knowledge_directory_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/dashboard/knowledge_document_handler.go b/internal/handlers/dashboard/knowledge_document_handler.go index cc36a53..e2115d6 100644 --- a/internal/handlers/dashboard/knowledge_document_handler.go +++ b/internal/handlers/dashboard/knowledge_document_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/knowledge_faq_handler.go b/internal/handlers/dashboard/knowledge_faq_handler.go index 50b149f..b0d6768 100644 --- a/internal/handlers/dashboard/knowledge_faq_handler.go +++ b/internal/handlers/dashboard/knowledge_faq_handler.go @@ -1,18 +1,18 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "fmt" "net/http" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/knowledge_retrieve_handler.go b/internal/handlers/dashboard/knowledge_retrieve_handler.go index bf46330..ea6dcfb 100644 --- a/internal/handlers/dashboard/knowledge_retrieve_handler.go +++ b/internal/handlers/dashboard/knowledge_retrieve_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "context" - "agent-desk/internal/ai/rag" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/dashboard/knowledge_retrieve_log_handler.go b/internal/handlers/dashboard/knowledge_retrieve_log_handler.go index 84a152f..5d3988a 100644 --- a/internal/handlers/dashboard/knowledge_retrieve_log_handler.go +++ b/internal/handlers/dashboard/knowledge_retrieve_log_handler.go @@ -1,13 +1,13 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/mcp_handler.go b/internal/handlers/dashboard/mcp_handler.go index 456a44d..f769e20 100644 --- a/internal/handlers/dashboard/mcp_handler.go +++ b/internal/handlers/dashboard/mcp_handler.go @@ -1,16 +1,16 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "context" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" ) diff --git a/internal/handlers/dashboard/notification_handler.go b/internal/handlers/dashboard/notification_handler.go index 7b46d3d..18aed53 100644 --- a/internal/handlers/dashboard/notification_handler.go +++ b/internal/handlers/dashboard/notification_handler.go @@ -1,18 +1,18 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "strings" - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/permission_handler.go b/internal/handlers/dashboard/permission_handler.go deleted file mode 100644 index 4af49af..0000000 --- a/internal/handlers/dashboard/permission_handler.go +++ /dev/null @@ -1,89 +0,0 @@ -package dashboard - -import ( - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/common/strs" - "github.com/mlogclub/simple/web" -) - -func PermissionAnyList(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionPermissionView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - cnd := params.NewPagedSqlCnd(ctx, - params.QueryFilter{ParamName: "groupName"}, - params.QueryFilter{ParamName: "type"}, - params.QueryFilter{ParamName: "status"}, - ).Desc("id") - - if keyword, _ := params.Get(ctx, "keyword"); strs.IsNotBlank(keyword) { - cnd.Where("(name LIKE ? OR code LIKE ?)", "%"+keyword+"%", "%"+keyword+"%") - } - - list, paging := services.PermissionService.FindPageByCnd(cnd) - results := make([]response.PermissionResponse, 0, len(list)) - for _, item := range list { - results = append(results, response.PermissionResponse{ - ID: item.ID, - Name: item.Name, - Code: item.Code, - Type: item.Type, - GroupName: item.GroupName, - Method: item.Method, - ApiPath: item.APIPath, - Status: item.Status, - SortNo: item.SortNo, - }) - } - httpx.WriteJSON(ctx, &web.PageResult{Results: results, Page: paging}) -} - -func PermissionGetBy(ctx *gin.Context) { - id, ok := httpx.GetPathInt64(ctx, "id") - if !ok { - return - } - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionPermissionView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - item := services.PermissionService.Get(id) - if item == nil { - httpx.WriteJSON(ctx, httpx.JsonErrorMsg(ctx, "error.e0236")) - return - } - httpx.WriteJSON(ctx, &response.PermissionResponse{ - ID: item.ID, - Name: item.Name, - Code: item.Code, - Type: item.Type, - GroupName: item.GroupName, - Method: item.Method, - ApiPath: item.APIPath, - Status: item.Status, - SortNo: item.SortNo, - }) -} - -func PermissionPostSync(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionPermissionSync); err != nil { - httpx.WriteJSON(ctx, err) - return - } - result, err := services.PermissionService.SyncBuiltinPermissions() - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, result) -} diff --git a/internal/handlers/dashboard/quick_reply_handler.go b/internal/handlers/dashboard/quick_reply_handler.go index 261bbe0..13df991 100644 --- a/internal/handlers/dashboard/quick_reply_handler.go +++ b/internal/handlers/dashboard/quick_reply_handler.go @@ -1,14 +1,14 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/role_handler.go b/internal/handlers/dashboard/role_handler.go deleted file mode 100644 index 1690eaa..0000000 --- a/internal/handlers/dashboard/role_handler.go +++ /dev/null @@ -1,210 +0,0 @@ -package dashboard - -import ( - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/sqls" - "github.com/mlogclub/simple/web" -) - -func RoleAnyList(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - cnd := params.NewPagedSqlCnd(ctx, - params.QueryFilter{ParamName: "status"}, - params.QueryFilter{ParamName: "code", Op: params.Like}, - ).Asc("sort_no").Desc("id") - list, paging := services.RoleService.FindPageByCnd(cnd) - results := make([]response.RoleResponse, 0, len(list)) - for _, item := range list { - results = append(results, response.RoleResponse{ - ID: item.ID, - Name: item.Name, - Code: item.Code, - Status: item.Status, - IsSystem: item.IsSystem, - SortNo: item.SortNo, - }) - } - httpx.WriteJSON(ctx, &web.PageResult{Results: results, Page: paging}) -} - -func RoleGetList_all(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - list := services.RoleService.Find(sqls.NewCnd().Asc("sort_no").Desc("id")) - results := make([]response.RoleResponse, 0, len(list)) - for _, item := range list { - results = append(results, response.RoleResponse{ - ID: item.ID, - Name: item.Name, - Code: item.Code, - Status: item.Status, - IsSystem: item.IsSystem, - SortNo: item.SortNo, - }) - } - httpx.WriteJSON(ctx, results) -} - -func RoleGetBy(ctx *gin.Context) { - id, ok := httpx.GetPathInt64(ctx, "id") - if !ok { - return - } - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - item := services.RoleService.Get(id) - if item == nil { - httpx.WriteJSON(ctx, httpx.JsonErrorMsg(ctx, "error.e0305")) - return - } - - permissionCodes := make([]string, 0) - list := services.RolePermissionService.Find(sqls.NewCnd().Eq("role_id", item.ID)) - for _, relation := range list { - permission := services.PermissionService.Get(relation.PermissionID) - if permission != nil { - permissionCodes = append(permissionCodes, permission.Code) - } - } - httpx.WriteJSON(ctx, &response.RoleResponse{ - ID: item.ID, - Name: item.Name, - Code: item.Code, - Status: item.Status, - IsSystem: item.IsSystem, - SortNo: item.SortNo, - Permissions: permissionCodes, - }) -} - -func RolePostCreate(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleCreate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.CreateRoleRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - role, err := services.RoleService.CreateRole(req, operator) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, &response.RoleResponse{ - ID: role.ID, - Name: role.Name, - Code: role.Code, - Status: role.Status, - IsSystem: role.IsSystem, - SortNo: role.SortNo, - }) -} - -func RolePostUpdate(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.UpdateRoleRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.RoleService.UpdateRole(req, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func RolePostDelete(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleDelete); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.DeleteRoleRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.RoleService.DeleteRole(req.ID); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func RolePostUpdate_status(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.UpdateRoleStatusRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.RoleService.UpdateStatus(req.ID, req.Status, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func RolePostAssign_permission(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionRoleAssignPermission) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.AssignPermissionRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.RoleService.AssignPermissions(req.RoleID, req.PermissionIDs, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func RolePostUpdate_sort(ctx *gin.Context) { - var ids []int64 - if err := params.ReadJSON(ctx, &ids); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.RoleService.UpdateSort(ids); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} diff --git a/internal/handlers/dashboard/session_handler.go b/internal/handlers/dashboard/session_handler.go deleted file mode 100644 index 662a4d4..0000000 --- a/internal/handlers/dashboard/session_handler.go +++ /dev/null @@ -1,86 +0,0 @@ -package dashboard - -import ( - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/services" - "time" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/web" -) - -func SessionAnyList(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - cnd := params.NewPagedSqlCnd(ctx, - params.QueryFilter{ParamName: "userId"}, - params.QueryFilter{ParamName: "clientType"}, - ).Desc("id") - list, paging := services.LoginSessionService.FindPageByCnd(cnd) - results := make([]response.SessionResponse, 0, len(list)) - for _, item := range list { - username := "" - if user := services.UserService.Get(item.UserID); user != nil { - username = user.Username - } - results = append(results, response.SessionResponse{ - ID: item.ID, - UserID: item.UserID, - Username: username, - ClientType: item.ClientType, - ClientIP: item.ClientIP, - UserAgent: item.UserAgent, - ExpiredAt: item.ExpiredAt.Format(time.DateTime), - RevokedAt: utils.FormatTimePtr(item.RevokedAt), - LastSeenAt: utils.FormatTimePtr(item.LastSeenAt), - }) - } - httpx.WriteJSON(ctx, &web.PageResult{Results: results, Page: paging}) -} - -func SessionPostRevoke(ctx *gin.Context) { - user, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionRevoke) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.RevokeSessionRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.LoginSessionService.Revoke(req.ID, user.UserID, user.Username); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func SessionPostRevokeByUser(ctx *gin.Context) { - user, err := services.AuthService.RequirePermission(ctx, constants.PermissionSessionRevoke) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.RevokeUserSessionsRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.LoginSessionService.RevokeByUser(req.UserID, user.UserID, user.Username); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} diff --git a/internal/handlers/dashboard/skill_definition_handler.go b/internal/handlers/dashboard/skill_definition_handler.go index 3b671fa..7a7f17c 100644 --- a/internal/handlers/dashboard/skill_definition_handler.go +++ b/internal/handlers/dashboard/skill_definition_handler.go @@ -1,19 +1,19 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "context" "strings" "time" - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/tag_handler.go b/internal/handlers/dashboard/tag_handler.go index 8bd779e..5e52dab 100644 --- a/internal/handlers/dashboard/tag_handler.go +++ b/internal/handlers/dashboard/tag_handler.go @@ -1,13 +1,13 @@ package dashboard import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/handlers/dashboard/ticket_handler.go b/internal/handlers/dashboard/ticket_handler.go index 3ab5bae..561e903 100644 --- a/internal/handlers/dashboard/ticket_handler.go +++ b/internal/handlers/dashboard/ticket_handler.go @@ -1,15 +1,15 @@ package dashboard import ( - "agent-desk/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" "strings" - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/builders" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/services" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/sqls" diff --git a/internal/handlers/dashboard/user_handler.go b/internal/handlers/dashboard/user_handler.go deleted file mode 100644 index d0127d4..0000000 --- a/internal/handlers/dashboard/user_handler.go +++ /dev/null @@ -1,227 +0,0 @@ -package dashboard - -import ( - "agent-desk/internal/builders" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/web" -) - -func UserAnyList(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - cnd := params.NewPagedSqlCnd(ctx, - params.QueryFilter{ParamName: "status"}, - params.QueryFilter{ParamName: "username", Op: params.Like}, - params.QueryFilter{ParamName: "nickname", Op: params.Like}, - ).Desc("id") - cnd.Where("status <> ?", enums.StatusDeleted) - list, paging := services.UserService.FindPageByCnd(cnd) - results := builders.BuildUserList(list, builders.UserBuildOptions{ - Roles: true, - Permissions: false, - }) - httpx.WriteJSON(ctx, &web.PageResult{Results: results, Page: paging}) -} - -func UserAnyList_all(ctx *gin.Context) { - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - cnd := params.NewSqlCnd(ctx, - params.QueryFilter{ParamName: "status"}, - params.QueryFilter{ParamName: "username", Op: params.Like}, - params.QueryFilter{ParamName: "nickname", Op: params.Like}, - ).Desc("id") - cnd.Where("status <> ?", enums.StatusDeleted) - - list := services.UserService.Find(cnd) - results := builders.BuildUserList(list, builders.UserBuildOptions{ - Roles: true, - Permissions: false, - }) - httpx.WriteJSON(ctx, results) -} - -func UserGetBy(ctx *gin.Context) { - id, ok := httpx.GetPathInt64(ctx, "id") - if !ok { - return - } - if _, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserView); err != nil { - httpx.WriteJSON(ctx, err) - return - } - - item := services.UserService.Get(id) - if item == nil { - httpx.WriteJSON(ctx, httpx.JsonErrorMsg(ctx, "error.e0255")) - return - } - httpx.WriteJSON(ctx, builders.BuildUserResponse(item, builders.UserBuildOptions{ - Roles: true, - Permissions: true, - })) -} - -func UserPostCreate(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserCreate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.CreateUserRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - user, generatedPassword, err := services.UserService.CreateUser(req, operator) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, &response.CreateUserResultResponse{ - User: builders.BuildUserResponse(user, builders.UserBuildOptions{Roles: true, Permissions: true}), - Password: generatedPassword, - }) -} - -func UserPostUpdate(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.UpdateUserRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.UserService.UpdateUser(req, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func UserPostDelete(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserDelete) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.DeleteUserRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.UserService.DeleteUser(req.ID, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func UserPostUpdate_status(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.UpdateUserStatusRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.UserService.UpdateStatus(req.ID, req.Status, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func UserPostReset_password(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserUpdate) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - var req struct { - UserID int64 `json:"userId"` - } - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - password, err := services.UserService.ResetPassword(req.UserID, operator) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, map[string]any{ - "password": password, - }) -} - -func UserPostChange_password(ctx *gin.Context) { - principal := services.AuthService.GetAuthPrincipal(ctx) - if principal == nil { - if _, err := services.AuthService.Authenticate(ctx); err != nil { - httpx.WriteJSON(ctx, err) - return - } - principal = services.AuthService.GetAuthPrincipal(ctx) - } - if principal == nil { - httpx.WriteJSON(ctx, httpx.JsonErrorMsg(ctx, "error.auth.expired")) - return - } - - req := request.ChangePasswordRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.UserService.ChangeOwnPassword(req.Password, principal); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} - -func UserPostAssign_role(ctx *gin.Context) { - operator, err := services.AuthService.RequirePermission(ctx, constants.PermissionUserAssignRole) - if err != nil { - httpx.WriteJSON(ctx, err) - return - } - - req := request.AssignRoleRequest{} - if err := params.ReadJSON(ctx, &req); err != nil { - httpx.WriteJSON(ctx, err) - return - } - if err := services.UserService.AssignRoles(req.UserID, req.RoleIDs, operator); err != nil { - httpx.WriteJSON(ctx, err) - return - } - httpx.WriteJSON(ctx, nil) -} diff --git a/internal/handlers/third/wechat_handler.go b/internal/handlers/third/wechat_handler.go index 440e272..f370e59 100644 --- a/internal/handlers/third/wechat_handler.go +++ b/internal/handlers/third/wechat_handler.go @@ -1,8 +1,8 @@ package third import ( - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/wxwork" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "io" "net/http" diff --git a/internal/middleware/auth_middleware.go b/internal/middleware/auth_middleware.go index 27f71bc..7eec2c1 100644 --- a/internal/middleware/auth_middleware.go +++ b/internal/middleware/auth_middleware.go @@ -1,8 +1,8 @@ package middleware import ( - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/middleware/chat_middleware.go b/internal/middleware/chat_middleware.go index c608800..addc604 100644 --- a/internal/middleware/chat_middleware.go +++ b/internal/middleware/chat_middleware.go @@ -1,11 +1,10 @@ package middleware import ( - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/web" ) func ExternalUserMiddleware(ctx *gin.Context) { @@ -15,13 +14,12 @@ func ExternalUserMiddleware(ctx *gin.Context) { ctx.Abort() return } - result, err := services.CustomerSessionService.VerifyRequest(ctx, channel) + external, err := services.SubjectService.CurrentExternal(ctx.Request.Context()) if err != nil { - ctx.JSON(200, web.JsonError(err)) + ctx.JSON(200, httpx.JsonErrorMsg(ctx, "error.auth.expired")) ctx.Abort() return } - services.CustomerSessionService.SetRefreshHeaders(ctx, result) - httpx.SetExternalUser(ctx, result.ExternalUser) + httpx.SetExternalUser(ctx, external) ctx.Next() } diff --git a/internal/migration/000002_init_auth_data.go b/internal/migration/000002_init_auth_data.go deleted file mode 100644 index 177b537..0000000 --- a/internal/migration/000002_init_auth_data.go +++ /dev/null @@ -1,255 +0,0 @@ -package migration - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - "errors" - "log/slog" - "strings" - "time" - - "github.com/mlogclub/simple/sqls" - "golang.org/x/crypto/bcrypt" - "gorm.io/gorm" -) - -func init() { - register(2, "init auth builtin data", func() error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - permissions, err := ensurePermissions(ctx.Tx) - if err != nil { - return err - } - - roles, err := ensureRoles(ctx.Tx) - if err != nil { - return err - } - - if err = ensureRolePermissions(ctx.Tx, roles, permissions); err != nil { - return err - } - - return ensureBootstrapAdmin(ctx.Tx, roles[constants.RoleCodeSuperAdmin]) - }) - }) -} - -func ensurePermissions(tx *gorm.DB) (map[string]*models.Permission, error) { - permissions := make(map[string]*models.Permission, len(constants.Permissions)) - now := time.Now() - - for _, spec := range constants.Permissions { - permission := repositories.PermissionRepository.FindOne(tx, sqls.NewCnd().Eq("code", spec.Code)) - if permission == nil { - permission = &models.Permission{ - Name: spec.Name, - Code: spec.Code, - Type: spec.Type, - GroupName: spec.GroupName, - Method: spec.Method, - APIPath: spec.APIPath, - SortNo: spec.SortNo, - Status: enums.StatusOk, - IsBuiltin: true, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - if err := repositories.PermissionRepository.Create(tx, permission); err != nil { - return nil, err - } - // slog.Info("initialized builtin permission", "code", spec.Code) - } else { - if err := repositories.PermissionRepository.Updates(tx, permission.ID, map[string]any{ - "name": spec.Name, - "type": spec.Type, - "group_name": spec.GroupName, - "method": spec.Method, - "api_path": spec.APIPath, - "sort_no": spec.SortNo, - "status": enums.StatusOk, - "is_builtin": true, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, - "updated_at": now, - }); err != nil { - return nil, err - } - permission = repositories.PermissionRepository.Get(tx, permission.ID) - } - permissions[spec.Code] = permission - } - - return permissions, nil -} - -func ensureRoles(tx *gorm.DB) (map[string]*models.Role, error) { - roles := make(map[string]*models.Role, len(constants.Roles)) - now := time.Now() - - for _, spec := range constants.Roles { - role := repositories.RoleRepository.GetByCode(tx, spec.Code) - if role == nil { - role = &models.Role{ - Name: spec.Name, - Code: spec.Code, - Status: enums.StatusOk, - IsSystem: true, - SortNo: spec.SortNo, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - if err := repositories.RoleRepository.Create(tx, role); err != nil { - return nil, err - } - // slog.Info("initialized builtin role", "code", spec.Code) - } else { - if err := repositories.RoleRepository.Updates(tx, role.ID, map[string]any{ - "name": spec.Name, - "sort_no": spec.SortNo, - "status": enums.StatusOk, - "is_system": true, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, - "updated_at": now, - }); err != nil { - return nil, err - } - role = repositories.RoleRepository.Get(tx, role.ID) - } - roles[spec.Code] = role - } - - return roles, nil -} - -func ensureRolePermissions(tx *gorm.DB, roles map[string]*models.Role, permissions map[string]*models.Permission) error { - now := time.Now() - - for roleCode, rolePermissions := range constants.RolePermissions { - role := roles[roleCode] - if role == nil { - return errors.New("builtin role not found: " + roleCode) - } - - for _, permissionSpec := range rolePermissions { - permission := permissions[permissionSpec.Code] - if permission == nil { - return errors.New("builtin permission not found: " + permissionSpec.Code) - } - - exists := repositories.RolePermissionRepository.FindOne(tx, sqls.NewCnd(). - Eq("role_id", role.ID). - Eq("permission_id", permission.ID)) - if exists != nil { - continue - } - - if err := repositories.RolePermissionRepository.Create(tx, &models.RolePermission{ - RoleID: role.ID, - PermissionID: permission.ID, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - }); err != nil { - return err - } - } - } - - return nil -} - -func ensureBootstrapAdmin(tx *gorm.DB, superAdminRole *models.Role) error { - if superAdminRole == nil { - return errors.New("super admin role not found") - } - - username := constants.BootstrapAdminUsername - nickname := constants.BootstrapAdminNickname - password := constants.BootstrapAdminPassword - - if strings.TrimSpace(password) == "" { - password = "ChangeMe123!" - slog.Warn("bootstrap admin password is empty, using default password", "username", username) - } - - user := repositories.UserRepository.FindOne(tx, sqls.NewCnd().Eq("username", username)) - now := time.Now() - if user == nil { - hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) - if err != nil { - return err - } - - user = &models.User{ - Username: username, - Nickname: nickname, - Password: string(hashedPassword), - Status: enums.StatusOk, - Remark: "bootstrap super admin", - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - } - if err := repositories.UserRepository.Create(tx, user); err != nil { - return err - } - slog.Warn("initialized bootstrap admin user", "username", username) - } else { - if err := repositories.UserRepository.Updates(tx, user.ID, map[string]any{ - "nickname": nickname, - "status": enums.StatusOk, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, - "updated_at": now, - }); err != nil { - return err - } - user = repositories.UserRepository.Get(tx, user.ID) - } - - exists := repositories.UserRoleRepository.FindOne(tx, sqls.NewCnd(). - Eq("user_id", user.ID). - Eq("role_id", superAdminRole.ID)) - if exists != nil { - return nil - } - - return repositories.UserRoleRepository.Create(tx, &models.UserRole{ - UserID: user.ID, - RoleID: superAdminRole.ID, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: constants.SystemAuditUserID, - CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, - UpdateUserID: constants.SystemAuditUserID, - UpdateUserName: constants.SystemAuditUserName, - }, - }) -} diff --git a/internal/migration/000004_sync_ai_agent_permissions.go b/internal/migration/000004_sync_ai_agent_permissions.go deleted file mode 100644 index e633247..0000000 --- a/internal/migration/000004_sync_ai_agent_permissions.go +++ /dev/null @@ -1,21 +0,0 @@ -package migration - -import "github.com/mlogclub/simple/sqls" - -func init() { - register(4, "sync ai agent permissions", func() error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - permissions, err := ensurePermissions(ctx.Tx) - if err != nil { - return err - } - - roles, err := ensureRoles(ctx.Tx) - if err != nil { - return err - } - - return ensureRolePermissions(ctx.Tx, roles, permissions) - }) - }) -} diff --git a/internal/migration/000006_backfill_conversation_customer_name.go b/internal/migration/000006_backfill_conversation_customer_name.go index d250b42..8734c74 100644 --- a/internal/migration/000006_backfill_conversation_customer_name.go +++ b/internal/migration/000006_backfill_conversation_customer_name.go @@ -1,7 +1,7 @@ package migration import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/migration/000007_sync_notification_permissions.go b/internal/migration/000007_sync_notification_permissions.go deleted file mode 100644 index c309663..0000000 --- a/internal/migration/000007_sync_notification_permissions.go +++ /dev/null @@ -1,21 +0,0 @@ -package migration - -import "github.com/mlogclub/simple/sqls" - -func init() { - register(7, "sync notification permissions", func() error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - permissions, err := ensurePermissions(ctx.Tx) - if err != nil { - return err - } - - roles, err := ensureRoles(ctx.Tx) - if err != nil { - return err - } - - return ensureRolePermissions(ctx.Tx, roles, permissions) - }) - }) -} diff --git a/internal/migration/000009_sync_wxwork_outbox_permissions.go b/internal/migration/000009_sync_wxwork_outbox_permissions.go deleted file mode 100644 index 8eadd90..0000000 --- a/internal/migration/000009_sync_wxwork_outbox_permissions.go +++ /dev/null @@ -1,21 +0,0 @@ -package migration - -import "github.com/mlogclub/simple/sqls" - -func init() { - register(9, "sync wxwork outbox permissions", func() error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - permissions, err := ensurePermissions(ctx.Tx) - if err != nil { - return err - } - - roles, err := ensureRoles(ctx.Tx) - if err != nil { - return err - } - - return ensureRolePermissions(ctx.Tx, roles, permissions) - }) - }) -} diff --git a/internal/migration/migration.go b/internal/migration/migration.go index b254854..758b4d8 100644 --- a/internal/migration/migration.go +++ b/internal/migration/migration.go @@ -1,8 +1,8 @@ package migration import ( - "agent-desk/internal/models" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/services" "errors" "log/slog" "sync" diff --git a/internal/models/models.go b/internal/models/models.go index 8ccbbc0..a5923b0 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -1,26 +1,17 @@ package models import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "time" ) // Models 注册所有需要迁移和代码生成的模型。 var Models = []any{ &Migration{}, - &User{}, - &UserIdentity{}, &Company{}, &Customer{}, &CustomerIdentity{}, &CustomerContact{}, - &Role{}, - &Permission{}, - &UserRole{}, - &RolePermission{}, - &UserPermission{}, - &LoginSession{}, - &LoginCredentialLog{}, &Asset{}, &Tag{}, &Conversation{}, @@ -156,39 +147,6 @@ type AuditFields struct { UpdateUserName string `gorm:"type:varchar(100);not null;default:''"` // UpdateUserName 记录最后更新人名称;系统任务写system。 } -// User 后台用户账号。 -type User struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - Username string `gorm:"type:varchar(100);not null;uniqueIndex"` - Nickname string `gorm:"type:varchar(100);not null;default:'';index"` - Avatar string `gorm:"type:varchar(255);not null;default:''"` - Mobile *string `gorm:"type:varchar(32);uniqueIndex"` - Email *string `gorm:"type:varchar(100);uniqueIndex"` - Password string `gorm:"type:varchar(255);not null;default:''"` - PasswordSalt string `gorm:"type:varchar(64);not null;default:''"` - Status enums.Status `gorm:"type:int;not null;default:0;index"` - LastLoginAt *time.Time - LastLoginIP string `gorm:"type:varchar(64);not null;default:''"` - Remark string `gorm:"type:text"` - DeletedAt *time.Time `gorm:"index"` - AuditFields -} - -// UserIdentity 第三方身份绑定信息。 -type UserIdentity struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - UserID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_provider_user"` - Provider enums.ThirdProvider `gorm:"type:varchar(50);not null;default:'';index;uniqueIndex:uk_provider_user;uniqueIndex:uk_provider_union"` - ProviderUserID string `gorm:"type:varchar(128);not null;default:'';uniqueIndex:uk_provider_user"` - ProviderUnionID *string `gorm:"type:varchar(128);uniqueIndex:uk_provider_union"` - ProviderCorpID string `gorm:"type:varchar(128);not null;default:'';index"` - ProviderName string `gorm:"type:varchar(100);not null;default:''"` - RawProfile string `gorm:"type:text"` - Status enums.Status `gorm:"type:int;not null;default:0;index"` - LastAuthAt *time.Time - AuditFields -} - // Company 客户公司(组织)表。 // // 用于存储公司主体信息;Customer(人)可通过 CompanyID 关联到所属公司。 @@ -245,91 +203,6 @@ type CustomerContact struct { AuditFields } -// Role 角色定义。 -type Role struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - Name string `gorm:"type:varchar(100);not null;default:'';index"` - Code string `gorm:"type:varchar(100);not null;uniqueIndex"` - Status enums.Status `gorm:"type:int;not null;default:0;index"` - IsSystem bool `gorm:"not null;default:false;index"` - SortNo int `gorm:"type:int;not null;default:0;index"` - Remark string `gorm:"type:text"` - AuditFields -} - -// Permission 权限点定义。 -type Permission struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - Name string `gorm:"type:varchar(100);not null;default:''"` - Code string `gorm:"type:varchar(150);not null;uniqueIndex"` - Type string `gorm:"type:varchar(20);not null;default:'';index"` - GroupName string `gorm:"type:varchar(100);not null;default:'';index"` - ParentID int64 `gorm:"type:bigint;not null;default:0;index"` - Path string `gorm:"type:varchar(255);not null;default:''"` - Method string `gorm:"type:varchar(20);not null;default:''"` - APIPath string `gorm:"type:varchar(255);not null;default:''"` - SortNo int `gorm:"type:int;not null;default:0;index"` - Status enums.Status `gorm:"type:int;not null;default:0;index"` - IsBuiltin bool `gorm:"not null;default:true;index"` - Remark string `gorm:"type:text"` - AuditFields -} - -// UserRole 用户和角色关联。 -type UserRole struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - UserID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_user_role"` - RoleID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_user_role"` - AuditFields -} - -// RolePermission 角色和权限关联。 -type RolePermission struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - RoleID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_role_permission"` - PermissionID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_role_permission"` - AuditFields -} - -// UserPermission 用户级例外权限。 -// -// 用于处理少量临时授权或拒绝授权场景。 -type UserPermission struct { - ID int64 `gorm:"primaryKey;autoIncrement"` - UserID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_user_permission"` - PermissionID int64 `gorm:"type:bigint;not null;index;uniqueIndex:uk_user_permission"` - Effect int `gorm:"type:int;not null;default:1;index"` // Effect 表示权限生效方式:1允许 -1拒绝。 - ExpiredAt *time.Time - Remark string `gorm:"type:text"` - AuditFields -} - -// LoginSession 表示一次后台登录会话。 -type LoginSession struct { - ID int64 `gorm:"primaryKey;autoIncrement"` // ID 为登录会话主键。 - UserID int64 `gorm:"type:bigint;not null;index"` // UserID 为登录用户 ID。 - Token string `gorm:"type:varchar(128);not null;uniqueIndex"` // Token 为随机不透明登录凭证,使用 ak_ 前缀。 - ClientType string `gorm:"type:varchar(50);not null;default:'';index"` // ClientType 为客户端类型,后台 Web 端固定为 admin_web。 - ClientIP string `gorm:"type:varchar(64);not null;default:''"` // ClientIP 为登录请求来源 IP。 - UserAgent string `gorm:"type:varchar(255);not null;default:''"` // UserAgent 为登录请求浏览器或客户端 UA。 - ExpiredAt time.Time `gorm:"not null;index"` // ExpiredAt 为 token 过期时间。 - RevokedAt *time.Time `gorm:"index"` // RevokedAt 为主动注销或踢下线时间,非空表示已失效。 - LastSeenAt *time.Time // LastSeenAt 为最近一次成功鉴权时间。 - AuditFields -} - -// LoginCredentialLog 记录一次后台登录凭证校验结果。 -type LoginCredentialLog struct { - ID int64 `gorm:"primaryKey;autoIncrement"` // ID 为登录凭证日志主键。 - Principal string `gorm:"type:varchar(100);not null;default:'';index"` // Principal 为用户输入的登录名。 - UserID int64 `gorm:"type:bigint;not null;default:0;index"` // UserID 为匹配到的用户 ID,未匹配时为 0。 - Success bool `gorm:"not null;default:false;index"` // Success 表示本次凭证校验是否成功。 - ClientIP string `gorm:"type:varchar(64);not null;default:''"` // ClientIP 为登录请求来源 IP。 - UserAgent string `gorm:"type:varchar(255);not null;default:''"` // UserAgent 为登录请求浏览器或客户端 UA。 - Reason string `gorm:"type:varchar(255);not null;default:''"` // Reason 为校验结果原因。 - CreatedAt time.Time `gorm:"not null;index"` // CreatedAt 为日志创建时间。 -} - // Asset 存储的文件资源,如上传的附件等。 type Asset struct { ID int64 `gorm:"primaryKey;autoIncrement"` diff --git a/internal/oidcclient/oidcclient.go b/internal/oidcclient/oidcclient.go deleted file mode 100644 index 4e9cd37..0000000 --- a/internal/oidcclient/oidcclient.go +++ /dev/null @@ -1,332 +0,0 @@ -package oidcclient - -import ( - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "context" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "encoding/json" - "strings" - "sync" - "time" - - gooidc "github.com/coreos/go-oidc/v3/oidc" - "golang.org/x/oauth2" -) - -const ( - StateTTL = 5 * time.Minute - LoginTicketTTL = 1 * time.Minute - defaultLoginNextPath = "/dashboard" -) - -var ( - oidcCfg config.OIDCConfig - provider *gooidc.Provider - oauthConfig *oauth2.Config - idTokenVerifier *gooidc.IDTokenVerifier - loginTicketStore sync.Map -) - -type Profile struct { - Subject string `json:"sub"` - Email string `json:"email,omitempty"` - PreferredUsername string `json:"preferred_username,omitempty"` - Name string `json:"name,omitempty"` - Picture string `json:"picture,omitempty"` - RawProfile string `json:"-"` -} - -type statePayload struct { - Next string `json:"next"` - Nonce string `json:"nonce"` - ExpiredAt int64 `json:"expiredAt"` -} - -type loginTicket struct { - Response *response.LoginResponse - ExpiredAt time.Time -} - -func Init(ctx context.Context) error { - provider = nil - oauthConfig = nil - idTokenVerifier = nil - oidcCfg = config.OIDCConfig{} - - cfg := config.Current().OIDC - if !cfg.Enabled { - return nil - } - oidcCfg = cfg - if strings.TrimSpace(cfg.Issuer) == "" { - return i18nx.Errorf("error.e0039") - } - if strings.TrimSpace(cfg.ClientID) == "" { - return i18nx.Errorf("error.e0036") - } - if strings.TrimSpace(cfg.ClientSecret) == "" { - return i18nx.Errorf("error.e0037") - } - if strings.TrimSpace(cfg.RedirectURL) == "" { - return i18nx.Errorf("error.e0040") - } - - p, err := gooidc.NewProvider(ctx, strings.TrimSpace(cfg.Issuer)) - if err != nil { - return err - } - scopes := cfg.Scopes - if len(scopes) == 0 { - scopes = []string{gooidc.ScopeOpenID, "profile", "email"} - } - provider = p - oauthConfig = &oauth2.Config{ - ClientID: strings.TrimSpace(cfg.ClientID), - ClientSecret: strings.TrimSpace(cfg.ClientSecret), - Endpoint: p.Endpoint(), - RedirectURL: strings.TrimSpace(cfg.RedirectURL), - Scopes: scopes, - } - idTokenVerifier = p.Verifier(&gooidc.Config{ClientID: strings.TrimSpace(cfg.ClientID)}) - return nil -} - -func Enabled() bool { - return oidcCfg.Enabled && provider != nil && oauthConfig != nil && idTokenVerifier != nil -} - -func BuildAuthCodeURL(next string) (string, error) { - if !Enabled() { - return "", errorsx.BusinessErrorI18n(1, "error.oidc.loginDisabled") - } - state, err := CreateState(next) - if err != nil { - return "", err - } - return oauthConfig.AuthCodeURL(state), nil -} - -func ExchangeCode(ctx context.Context, code string) (*Profile, error) { - if !Enabled() { - return nil, errorsx.BusinessErrorI18n(1, "error.oidc.loginDisabled") - } - code = strings.TrimSpace(code) - if code == "" { - return nil, errorsx.InvalidParamI18n("error.e0041") - } - token, err := oauthConfig.Exchange(ctx, code) - if err != nil { - return nil, err - } - rawIDToken, ok := token.Extra("id_token").(string) - if !ok || strings.TrimSpace(rawIDToken) == "" { - return nil, errorsx.UnauthorizedI18n("error.e0038") - } - idToken, err := idTokenVerifier.Verify(ctx, rawIDToken) - if err != nil { - return nil, err - } - profile, err := profileFromIDToken(idToken) - if err != nil { - return nil, err - } - userInfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(token)) - if err == nil && userInfo != nil && strings.TrimSpace(userInfo.Subject) == profile.Subject { - if mergedProfile, mergeErr := profileFromUserInfo(userInfo, profile); mergeErr == nil { - profile = mergedProfile - } - } - return profile, nil -} - -func CreateState(next string) (string, error) { - secret := stateSecret() - if secret == "" { - return "", errorsx.BusinessErrorI18n(2, "error.oidc.stateSecretMissing") - } - nonce, err := randomToken("os_") - if err != nil { - return "", err - } - payload := statePayload{ - Next: sanitizeNextPath(next), - Nonce: nonce, - ExpiredAt: time.Now().Add(StateTTL).Unix(), - } - body, err := json.Marshal(payload) - if err != nil { - return "", err - } - encoded := base64.RawURLEncoding.EncodeToString(body) - return encoded + "." + signState(encoded, secret), nil -} - -func ParseState(state string) (string, error) { - secret := stateSecret() - if secret == "" { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - parts := strings.Split(strings.TrimSpace(state), ".") - if len(parts) != 2 { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - if !hmac.Equal([]byte(parts[1]), []byte(signState(parts[0], secret))) { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - body, err := base64.RawURLEncoding.DecodeString(parts[0]) - if err != nil { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - payload := statePayload{} - if err = json.Unmarshal(body, &payload); err != nil { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - if payload.ExpiredAt <= time.Now().Unix() { - return "", errorsx.UnauthorizedI18n("error.e0046") - } - return sanitizeNextPath(payload.Next), nil -} - -func IssueLoginTicket(loginResp *response.LoginResponse) (string, error) { - if loginResp == nil { - return "", i18nx.Errorf("error.e0272") - } - ticket, err := randomToken("olt_") - if err != nil { - return "", err - } - cleanupExpiredLoginTickets() - loginTicketStore.Store(ticket, loginTicket{ - Response: loginResp, - ExpiredAt: time.Now().Add(LoginTicketTTL), - }) - return ticket, nil -} - -func ConsumeLoginTicket(ticket string) (*response.LoginResponse, error) { - ticket = strings.TrimSpace(ticket) - if ticket == "" { - return nil, errorsx.InvalidParamI18n("error.e0072") - } - value, ok := loginTicketStore.LoadAndDelete(ticket) - if !ok { - return nil, errorsx.UnauthorizedI18n("error.e0271") - } - record, ok := value.(loginTicket) - if !ok || record.Response == nil || time.Now().After(record.ExpiredAt) { - return nil, errorsx.UnauthorizedI18n("error.e0271") - } - return record.Response, nil -} - -func profileFromIDToken(idToken *gooidc.IDToken) (*Profile, error) { - var claims map[string]any - if err := idToken.Claims(&claims); err != nil { - return nil, err - } - raw, _ := json.Marshal(claims) - profile := &Profile{ - Subject: claimString(claims, "sub"), - Email: claimString(claims, "email"), - PreferredUsername: claimString(claims, "preferred_username"), - Name: claimString(claims, "name"), - Picture: claimString(claims, "picture"), - RawProfile: string(raw), - } - if strings.TrimSpace(profile.Subject) == "" { - return nil, errorsx.UnauthorizedI18n("error.e0043") - } - return profile, nil -} - -func profileFromUserInfo(userInfo *gooidc.UserInfo, fallback *Profile) (*Profile, error) { - var claims map[string]any - if err := userInfo.Claims(&claims); err != nil { - return nil, err - } - raw, _ := json.Marshal(claims) - profile := &Profile{ - Subject: strings.TrimSpace(userInfo.Subject), - Email: claimString(claims, "email"), - PreferredUsername: claimString(claims, "preferred_username"), - Name: claimString(claims, "name"), - Picture: claimString(claims, "picture"), - RawProfile: string(raw), - } - if fallback != nil { - profile.Email = firstNonEmpty(profile.Email, fallback.Email) - profile.PreferredUsername = firstNonEmpty(profile.PreferredUsername, fallback.PreferredUsername) - profile.Name = firstNonEmpty(profile.Name, fallback.Name) - profile.Picture = firstNonEmpty(profile.Picture, fallback.Picture) - } - if profile.RawProfile == "" { - if fallback != nil { - profile.RawProfile = fallback.RawProfile - } - } - if strings.TrimSpace(profile.Subject) == "" { - return nil, errorsx.UnauthorizedI18n("error.e0043") - } - return profile, nil -} - -func firstNonEmpty(values ...string) string { - for _, value := range values { - if value = strings.TrimSpace(value); value != "" { - return value - } - } - return "" -} - -func claimString(claims map[string]any, key string) string { - value, _ := claims[key].(string) - return strings.TrimSpace(value) -} - -func stateSecret() string { - if strings.TrimSpace(oidcCfg.StateSecret) != "" { - return strings.TrimSpace(oidcCfg.StateSecret) - } - return strings.TrimSpace(oidcCfg.ClientSecret) -} - -func signState(content, secret string) string { - mac := hmac.New(sha256.New, []byte(secret)) - _, _ = mac.Write([]byte(content)) - return hex.EncodeToString(mac.Sum(nil)) -} - -func cleanupExpiredLoginTickets() { - now := time.Now() - loginTicketStore.Range(func(key, value any) bool { - record, ok := value.(loginTicket) - if !ok || now.After(record.ExpiredAt) { - loginTicketStore.Delete(key) - } - return true - }) -} - -func sanitizeNextPath(next string) string { - next = strings.TrimSpace(next) - if next == "" || !strings.HasPrefix(next, "/") || strings.HasPrefix(next, "//") { - return defaultLoginNextPath - } - return next -} - -func randomToken(prefix string) (string, error) { - buf := make([]byte, 24) - if _, err := rand.Read(buf); err != nil { - return "", err - } - return prefix + hex.EncodeToString(buf), nil -} diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 39b9c90..e99d255 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -1,7 +1,7 @@ package config import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "fmt" "strings" @@ -9,17 +9,14 @@ import ( ) type Config struct { - Language string `yaml:"language"` - Server ServerConfig `yaml:"server"` - DB DBConfig `yaml:"db"` - Logger LoggerConfig `yaml:"logger"` - Auth AuthConfig `yaml:"auth"` - Storage StorageConfig `yaml:"storage"` - VectorDB VectorDBConfig `yaml:"vectorDB"` - MCP MCPConfig `yaml:"mcp"` - WxWork WxWorkConfig `yaml:"wxWork"` - OIDC OIDCConfig `yaml:"oidc"` - CustomerSession CustomerSessionConfig `yaml:"customerSession"` + Language string `yaml:"language"` + Server ServerConfig `yaml:"server"` + DB DBConfig `yaml:"db"` + Logger LoggerConfig `yaml:"logger"` + Storage StorageConfig `yaml:"storage"` + VectorDB VectorDBConfig `yaml:"vectorDB"` + MCP MCPConfig `yaml:"mcp"` + WxWork WxWorkConfig `yaml:"wxWork"` } func (c Config) LanguageOrDefault() string { @@ -82,32 +79,6 @@ type LoggerConfig struct { AddSource bool `yaml:"addSource"` } -type AuthConfig struct { - TokenTTLHours int `yaml:"tokenTTLHours"` - MaxFailedAttempts int `yaml:"maxFailedAttempts"` - CredentialLockMinute int `yaml:"credentialLockMinute"` -} - -type CustomerSessionConfig struct { - Secret string `yaml:"secret"` - TTLMinutes int `yaml:"ttlMinutes"` - RefreshThresholdMinutes int `yaml:"refreshThresholdMinutes"` -} - -func (c CustomerSessionConfig) TTL() int { - if c.TTLMinutes <= 0 { - return 120 - } - return c.TTLMinutes -} - -func (c CustomerSessionConfig) RefreshThreshold() int { - if c.RefreshThresholdMinutes <= 0 { - return 30 - } - return c.RefreshThresholdMinutes -} - type StorageConfig struct { Default enums.AssetProvider `yaml:"default"` MaxUploadSizeMB int64 `yaml:"maxUploadSizeMB"` @@ -171,27 +142,10 @@ type MCPServerConfig struct { Headers map[string]string `yaml:"headers"` } -type OIDCConfig struct { - Enabled bool `yaml:"enabled"` - Issuer string `yaml:"issuer"` - ClientID string `yaml:"clientId"` - ClientSecret string `yaml:"clientSecret"` - RedirectURL string `yaml:"redirectUrl"` - StateSecret string `yaml:"stateSecret"` - Scopes []string `yaml:"scopes"` -} - -// WxWorkConfig 定义企业微信接入配置。 -// -// 当前主要用于后台管理台的企业微信登录流程: -// 1. /api/auth/wxwork/login 生成企业微信授权地址 -// 2. 企业微信回调到 OAuthRedirect -// 3. 后端通过 code 换取企业成员身份并完成系统登录 -// -// 其中 OAuthRedirect、CorpID、CorpSecret、AgentID 为登录流程核心配置。 +// WxWorkConfig defines the WeCom application used for customer-service +// callbacks and notifications. Dashboard login is owned by be-system. type WxWorkConfig struct { - // Enabled 表示是否启用企业微信登录能力。 - // false 时不会初始化企业微信 SDK,相关登录接口不可用。 + // Enabled controls whether the WeCom SDK is initialized. Enabled bool `yaml:"enabled"` // CorpID 为企业微信公司 ID,例如 wwxxxxxxxxxxxxxxxx。 CorpID string `yaml:"corpId"` @@ -199,20 +153,11 @@ type WxWorkConfig struct { CorpSecret string `yaml:"corpSecret"` // AgentID 为企业微信自建应用 AgentID。 AgentID string `yaml:"agentId"` - // OAuthRedirect 为企业微信网页授权回调地址。 - // 必须填写完整 URL,且通常指向后端接口 /api/auth/wxwork/callback。 - OAuthRedirect string `yaml:"oauthRedirect"` - // StateSecret 为登录 state 的签名密钥,用于防止篡改和重放。 - // 建议填写独立随机字符串;留空时业务代码会退回使用 CorpSecret。 - StateSecret string `yaml:"stateSecret"` // RSAPrivateKey 为企业微信回调解密私钥。 - // 当前登录流程未使用,保留给消息回调等场景。 RSAPrivateKey string `yaml:"rsaPrivateKey"` // Token 为企业微信回调 Token。 - // 当前登录流程未使用,保留给消息回调等场景。 Token string `yaml:"token"` // EncodingAESKey 为企业微信消息加解密密钥。 - // 当前登录流程未使用,保留给消息回调等场景。 EncodingAESKey string `yaml:"encodingAESKey"` // Notify 为企业微信应用消息通知配置。 Notify WxWorkNotifyConfig `yaml:"notify"` diff --git a/internal/pkg/constants/auth.go b/internal/pkg/constants/auth.go index 2dc4b8c..dd0a445 100644 --- a/internal/pkg/constants/auth.go +++ b/internal/pkg/constants/auth.go @@ -1,27 +1,6 @@ package constants -const ( - RoleCodeSuperAdmin = "super_admin" // 超管 - RoleCodeAdmin = "admin" // 管理员 - RoleCodeCsTeamLeader = "cs_team_leader" // 客服组长 - RoleCodeCsUser = "cs_user" // 客服 -) - -const ( - AuthTokenPrefix = "ak_" -) - -const ( - ClientTypeAdminWeb = "admin_web" -) - -const ( - BootstrapAdminUsername = "admin" - BootstrapAdminPassword = "ChangeMe123!" - BootstrapAdminNickname = "Super Admin" -) - -// Permission 权限结构体 +// Permission 仅描述客服业务操作,由宿主系统执行权限验证 type Permission struct { Name string Code string @@ -34,28 +13,6 @@ type Permission struct { // 权限常量定义 var ( - // 用户相关权限 - PermissionUserView = Permission{Name: "查看用户", Code: "user.view", Type: "api", GroupName: "user", Method: "ANY", APIPath: "/api/dashboard/user/list", SortNo: 10} - PermissionUserCreate = Permission{Name: "创建用户", Code: "user.create", Type: "api", GroupName: "user", Method: "POST", APIPath: "/api/dashboard/user/create", SortNo: 20} - PermissionUserUpdate = Permission{Name: "更新用户", Code: "user.update", Type: "api", GroupName: "user", Method: "POST", APIPath: "/api/dashboard/user/update", SortNo: 30} - PermissionUserDelete = Permission{Name: "删除用户", Code: "user.delete", Type: "api", GroupName: "user", Method: "POST", APIPath: "/api/dashboard/user/delete", SortNo: 40} - PermissionUserAssignRole = Permission{Name: "分配用户角色", Code: "user.assignRole", Type: "api", GroupName: "user", Method: "POST", APIPath: "/api/dashboard/user/assign_role", SortNo: 50} - - // 角色相关权限 - PermissionRoleView = Permission{Name: "查看角色", Code: "role.view", Type: "api", GroupName: "role", Method: "ANY", APIPath: "/api/dashboard/role/list", SortNo: 110} - PermissionRoleCreate = Permission{Name: "创建角色", Code: "role.create", Type: "api", GroupName: "role", Method: "POST", APIPath: "/api/dashboard/role/create", SortNo: 120} - PermissionRoleUpdate = Permission{Name: "更新角色", Code: "role.update", Type: "api", GroupName: "role", Method: "POST", APIPath: "/api/dashboard/role/update", SortNo: 130} - PermissionRoleDelete = Permission{Name: "删除角色", Code: "role.delete", Type: "api", GroupName: "role", Method: "POST", APIPath: "/api/dashboard/role/delete", SortNo: 140} - PermissionRoleAssignPermission = Permission{Name: "分配角色权限", Code: "role.assignPermission", Type: "api", GroupName: "role", Method: "POST", APIPath: "/api/dashboard/role/assign_permission", SortNo: 150} - - // 权限相关权限 - PermissionPermissionView = Permission{Name: "查看权限", Code: "permission.view", Type: "api", GroupName: "permission", Method: "ANY", APIPath: "/api/dashboard/permission/list", SortNo: 210} - PermissionPermissionSync = Permission{Name: "同步权限", Code: "permission.sync", Type: "api", GroupName: "permission", Method: "POST", APIPath: "/api/dashboard/permission/sync", SortNo: 220} - - // 会话相关权限 - PermissionSessionView = Permission{Name: "查看会话", Code: "session.view", Type: "api", GroupName: "session", Method: "ANY", APIPath: "/api/dashboard/session/list", SortNo: 310} - PermissionSessionRevoke = Permission{Name: "踢除会话", Code: "session.revoke", Type: "api", GroupName: "session", Method: "POST", APIPath: "/api/dashboard/session/revoke", SortNo: 320} - // 客服会话相关权限 PermissionConversationView = Permission{Name: "查看会话", Code: "conversation.view", Type: "api", GroupName: "conversation", Method: "ANY", APIPath: "/api/dashboard/conversation/list", SortNo: 410} PermissionConversationAssign = Permission{Name: "分配会话", Code: "conversation.assign", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/assign", SortNo: 430} @@ -63,8 +20,6 @@ var ( PermissionConversationClose = Permission{Name: "关闭会话", Code: "conversation.close", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/close", SortNo: 450} PermissionConversationSend = Permission{Name: "发送会话消息", Code: "conversation.send", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/send_message", SortNo: 460} PermissionConversationTag = Permission{Name: "管理会话标签", Code: "conversation.tag", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/add_tag", SortNo: 470} - PermissionConversationHandover = Permission{Name: "处理会话交接", Code: "conversation.handover", Type: "api", GroupName: "conversation", Method: "ANY", APIPath: "/api/dashboard/conversation/handover_list", SortNo: 480} - PermissionConversationRecycle = Permission{Name: "回收会话", Code: "conversation.recycle", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/recycle", SortNo: 490} PermissionConversationLinkCustomer = Permission{Name: "关联会话客户", Code: "conversation.linkCustomer", Type: "api", GroupName: "conversation", Method: "POST", APIPath: "/api/dashboard/conversation/link_customer", SortNo: 495} // 工单相关权限 @@ -118,8 +73,6 @@ var ( PermissionAgentCreate = Permission{Name: "创建客服", Code: "agent.create", Type: "api", GroupName: "agent", Method: "POST", APIPath: "/api/dashboard/agent/create", SortNo: 620} PermissionAgentUpdate = Permission{Name: "更新客服", Code: "agent.update", Type: "api", GroupName: "agent", Method: "POST", APIPath: "/api/dashboard/agent/update", SortNo: 630} PermissionAgentDelete = Permission{Name: "删除客服", Code: "agent.delete", Type: "api", GroupName: "agent", Method: "POST", APIPath: "/api/dashboard/agent/delete", SortNo: 640} - PermissionAgentUpdateStatus = Permission{Name: "更新客服状态", Code: "agent.updateStatus", Type: "api", GroupName: "agent", Method: "POST", APIPath: "/api/dashboard/agent/update_status", SortNo: 650} - PermissionAgentConfig = Permission{Name: "配置客服服务规则", Code: "agent.config", Type: "api", GroupName: "agent", Method: "POST", APIPath: "/api/dashboard/agent/update_service_config", SortNo: 660} // 客服组相关权限 PermissionAgentTeamView = Permission{Name: "查看客服组", Code: "agentTeam.view", Type: "api", GroupName: "agentTeam", Method: "ANY", APIPath: "/api/dashboard/agent-team/list", SortNo: 710} @@ -177,303 +130,3 @@ var ( PermissionMCPView = Permission{Name: "查看MCP调试信息", Code: "mcp.view", Type: "api", GroupName: "mcp", Method: "POST", APIPath: "/api/dashboard/mcp/list_tools", SortNo: 1710} PermissionMCPCall = Permission{Name: "调用MCP工具", Code: "mcp.call", Type: "api", GroupName: "mcp", Method: "POST", APIPath: "/api/dashboard/mcp/call_tool", SortNo: 1720} ) - -// Permissions 内置权限列表 -var Permissions = []Permission{ - PermissionUserView, - PermissionUserCreate, - PermissionUserUpdate, - PermissionUserDelete, - PermissionUserAssignRole, - PermissionRoleView, - PermissionRoleCreate, - PermissionRoleUpdate, - PermissionRoleDelete, - PermissionRoleAssignPermission, - PermissionPermissionView, - PermissionPermissionSync, - PermissionSessionView, - PermissionSessionRevoke, - PermissionConversationView, - PermissionConversationAssign, - PermissionConversationTransfer, - PermissionConversationClose, - PermissionConversationSend, - PermissionConversationTag, - PermissionConversationHandover, - PermissionConversationRecycle, - PermissionConversationLinkCustomer, - PermissionTicketView, - PermissionTicketCreate, - PermissionTicketUpdate, - PermissionTicketAssign, - PermissionTicketChangeStatus, - PermissionTicketProgress, - PermissionNotificationView, - PermissionNotificationUpdate, - PermissionQuickReplyView, - PermissionQuickReplyCreate, - PermissionQuickReplyUpdate, - PermissionQuickReplyDelete, - PermissionTagView, - PermissionTagCreate, - PermissionTagUpdate, - PermissionTagDelete, - PermissionCompanyView, - PermissionCompanyCreate, - PermissionCompanyUpdate, - PermissionCompanyDelete, - PermissionChannelView, - PermissionChannelCreate, - PermissionChannelUpdate, - PermissionChannelDelete, - PermissionWxWorkOutboxView, - PermissionWxWorkOutboxUpdate, - PermissionCustomerView, - PermissionCustomerCreate, - PermissionCustomerUpdate, - PermissionCustomerDelete, - PermissionAgentView, - PermissionAgentCreate, - PermissionAgentUpdate, - PermissionAgentDelete, - PermissionAgentUpdateStatus, - PermissionAgentConfig, - PermissionAgentTeamView, - PermissionAgentTeamCreate, - PermissionAgentTeamUpdate, - PermissionAgentTeamDelete, - PermissionAgentTeamScheduleView, - PermissionAgentTeamScheduleCreate, - PermissionAgentTeamScheduleUpdate, - PermissionAgentTeamScheduleDelete, - PermissionAgentTeamScheduleBatchGenerate, - PermissionAssetView, - PermissionAssetCreate, - PermissionAssetDelete, - PermissionAIAgentView, - PermissionAIAgentCreate, - PermissionAIAgentUpdate, - PermissionAIAgentDelete, - PermissionAIConfigView, - PermissionAIConfigCreate, - PermissionAIConfigUpdate, - PermissionAIConfigDelete, - PermissionKnowledgeBaseView, - PermissionKnowledgeBaseCreate, - PermissionKnowledgeBaseUpdate, - PermissionKnowledgeBaseDelete, - PermissionKnowledgeDocumentView, - PermissionKnowledgeDocumentCreate, - PermissionKnowledgeDocumentUpdate, - PermissionKnowledgeDocumentDelete, - PermissionKnowledgeFAQView, - PermissionKnowledgeFAQCreate, - PermissionKnowledgeFAQUpdate, - PermissionKnowledgeFAQDelete, - PermissionSkillDefinitionView, - PermissionSkillDefinitionCreate, - PermissionSkillDefinitionUpdate, - PermissionSkillDefinitionDelete, - PermissionMCPView, - PermissionMCPCall, -} - -// PermissionMap 权限映射,用于通过 Code 查找 Permission -var PermissionMap = make(map[string]Permission) - -// init 初始化 PermissionMap -func init() { - normalizeBuiltinPermissionNames() - for _, permission := range Permissions { - PermissionMap[permission.Code] = permission - } -} - -func normalizeBuiltinPermissionNames() { - for i := range Permissions { - Permissions[i].Name = builtinPermissionName(Permissions[i].Code, Permissions[i].Name) - } -} - -func builtinPermissionName(code string, fallback string) string { - if name, ok := builtinPermissionNameOverrides[code]; ok { - return name - } - resourceKey, actionKey, ok := splitPermissionCode(code) - if !ok { - return fallback - } - action, ok := builtinPermissionActionLabels[actionKey] - if !ok { - return fallback - } - resource, ok := builtinPermissionResourceLabels[resourceKey] - if !ok { - return fallback - } - return action + " " + resource -} - -func splitPermissionCode(code string) (string, string, bool) { - for i := 0; i < len(code); i++ { - if code[i] == '.' { - return code[:i], code[i+1:], i > 0 && i < len(code)-1 - } - } - return "", "", false -} - -var builtinPermissionActionLabels = map[string]string{ - "view": "View", - "create": "Create", - "update": "Update", - "delete": "Delete", - "assignRole": "Assign roles to", - "assignPermission": "Assign permissions to", - "sync": "Sync", - "revoke": "Revoke", - "assign": "Assign", - "transfer": "Transfer", - "close": "Close", - "send": "Send", - "tag": "Manage tags for", - "handover": "Handle handoffs for", - "recycle": "Recycle", - "linkCustomer": "Link customers to", - "changeStatus": "Change status for", - "progress": "Update progress for", - "updateStatus": "Update status for", - "config": "Configure service rules for", - "batchGenerate": "Batch generate", - "call": "Call", -} - -var builtinPermissionResourceLabels = map[string]string{ - "user": "users", - "role": "roles", - "permission": "permissions", - "session": "sessions", - "conversation": "conversations", - "ticket": "tickets", - "notification": "notifications", - "quickReply": "quick replies", - "tag": "tags", - "company": "companies", - "channel": "channels", - "wxworkOutbox": "WeCom outbox records", - "customer": "customers", - "agent": "agents", - "agentTeam": "agent teams", - "agentTeamSchedule": "agent team schedules", - "asset": "file assets", - "aiAgent": "AI Agents", - "aiConfig": "AI configurations", - "knowledgeBase": "knowledge bases", - "knowledgeDocument": "knowledge documents", - "knowledgeFAQ": "knowledge FAQs", - "skillDefinition": "Skill definitions", - "mcp": "MCP tools", -} - -var builtinPermissionNameOverrides = map[string]string{ - "user.assignRole": "Assign user roles", - "role.assignPermission": "Assign role permissions", - "session.revoke": "Revoke sessions", - "conversation.send": "Send conversation messages", - "conversation.linkCustomer": "Link conversation customer", - "ticket.changeStatus": "Change ticket status", - "ticket.progress": "Update ticket progress", - "agent.config": "Configure agent service rules", - "agentTeamSchedule.batchGenerate": "Batch generate agent team schedules", - "wxworkOutbox.update": "Handle WeCom outbox records", - "mcp.view": "View MCP debug information", - "mcp.call": "Call MCP tools", -} - -type RoleSpec struct { - Name string - Code string - SortNo int -} - -var Roles = []RoleSpec{ - {Name: "Super Admin", Code: RoleCodeSuperAdmin, SortNo: 1}, - {Name: "Admin", Code: RoleCodeAdmin, SortNo: 2}, - {Name: "Support Team Lead", Code: RoleCodeCsTeamLeader, SortNo: 3}, - {Name: "Support Agent", Code: RoleCodeCsUser, SortNo: 4}, -} - -var RolePermissions = map[string][]Permission{ - RoleCodeSuperAdmin: Permissions, - RoleCodeAdmin: { - PermissionUserView, PermissionUserCreate, PermissionUserUpdate, PermissionUserAssignRole, - PermissionRoleView, PermissionRoleCreate, PermissionRoleUpdate, PermissionRoleAssignPermission, - PermissionPermissionView, PermissionPermissionSync, - PermissionSessionView, PermissionSessionRevoke, - PermissionConversationView, PermissionConversationAssign, PermissionConversationTransfer, PermissionConversationClose, PermissionConversationSend, PermissionConversationTag, PermissionConversationHandover, PermissionConversationRecycle, PermissionConversationLinkCustomer, - PermissionTicketView, PermissionTicketCreate, PermissionTicketUpdate, PermissionTicketAssign, PermissionTicketChangeStatus, PermissionTicketProgress, - PermissionNotificationView, PermissionNotificationUpdate, - PermissionQuickReplyView, PermissionQuickReplyCreate, PermissionQuickReplyUpdate, PermissionQuickReplyDelete, - PermissionTagView, PermissionTagCreate, PermissionTagUpdate, PermissionTagDelete, - PermissionCompanyView, PermissionCompanyCreate, PermissionCompanyUpdate, PermissionCompanyDelete, - PermissionChannelView, PermissionChannelCreate, PermissionChannelUpdate, PermissionChannelDelete, PermissionWxWorkOutboxView, PermissionWxWorkOutboxUpdate, - PermissionCustomerView, PermissionCustomerCreate, PermissionCustomerUpdate, PermissionCustomerDelete, - PermissionAgentView, PermissionAgentCreate, PermissionAgentUpdate, PermissionAgentDelete, PermissionAgentUpdateStatus, PermissionAgentConfig, - PermissionAgentTeamView, PermissionAgentTeamCreate, PermissionAgentTeamUpdate, PermissionAgentTeamDelete, - PermissionAgentTeamScheduleView, PermissionAgentTeamScheduleCreate, PermissionAgentTeamScheduleUpdate, PermissionAgentTeamScheduleDelete, PermissionAgentTeamScheduleBatchGenerate, - PermissionAssetView, PermissionAssetCreate, PermissionAssetDelete, - PermissionAIAgentView, PermissionAIAgentCreate, PermissionAIAgentUpdate, PermissionAIAgentDelete, - PermissionAIConfigView, PermissionAIConfigCreate, PermissionAIConfigUpdate, PermissionAIConfigDelete, - PermissionSkillDefinitionView, PermissionSkillDefinitionCreate, PermissionSkillDefinitionUpdate, PermissionSkillDefinitionDelete, - }, - RoleCodeCsTeamLeader: { - PermissionUserView, - PermissionRoleView, - PermissionPermissionView, - PermissionSessionView, - PermissionConversationView, PermissionConversationClose, PermissionConversationSend, PermissionConversationTag, PermissionConversationHandover, PermissionConversationRecycle, PermissionConversationLinkCustomer, - PermissionTicketView, PermissionTicketCreate, PermissionTicketUpdate, PermissionTicketAssign, PermissionTicketChangeStatus, PermissionTicketProgress, - PermissionNotificationView, PermissionNotificationUpdate, - PermissionQuickReplyView, PermissionQuickReplyCreate, PermissionQuickReplyUpdate, PermissionQuickReplyDelete, - PermissionTagView, PermissionTagCreate, PermissionTagUpdate, PermissionTagDelete, - PermissionCompanyView, - PermissionChannelView, PermissionChannelCreate, PermissionChannelUpdate, - PermissionCustomerView, PermissionCustomerCreate, PermissionCustomerUpdate, - PermissionAgentView, PermissionAgentUpdate, - PermissionAgentTeamView, - PermissionAgentTeamScheduleView, PermissionAgentTeamScheduleCreate, PermissionAgentTeamScheduleUpdate, PermissionAgentTeamScheduleDelete, PermissionAgentTeamScheduleBatchGenerate, - PermissionAssetView, PermissionAssetCreate, PermissionAssetDelete, - PermissionAIAgentView, PermissionAIAgentCreate, PermissionAIAgentUpdate, - PermissionAIConfigView, - PermissionSkillDefinitionView, PermissionSkillDefinitionCreate, PermissionSkillDefinitionUpdate, - }, - RoleCodeCsUser: { - PermissionUserView, - PermissionRoleView, - PermissionPermissionView, - PermissionConversationView, - PermissionTicketView, PermissionTicketCreate, PermissionTicketAssign, PermissionTicketChangeStatus, PermissionTicketProgress, - PermissionNotificationView, PermissionNotificationUpdate, - PermissionQuickReplyView, - PermissionTagView, - PermissionCompanyView, - PermissionChannelView, - PermissionCustomerView, - PermissionAssetView, - PermissionAgentView, - PermissionAgentTeamView, - PermissionAgentTeamScheduleView, - PermissionAIAgentView, - PermissionAIConfigView, - PermissionSkillDefinitionView, - }, -} - -func PermissionCodes() []string { - ret := make([]string, 0, len(Permissions)) - for _, permission := range Permissions { - ret = append(ret, permission.Code) - } - return ret -} diff --git a/internal/pkg/constants/auth_test.go b/internal/pkg/constants/auth_test.go deleted file mode 100644 index d31101b..0000000 --- a/internal/pkg/constants/auth_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package constants - -import "testing" - -func TestBuiltinAuthSeedNamesDefaultToEnglish(t *testing.T) { - t.Parallel() - - if BootstrapAdminNickname != "Super Admin" { - t.Fatalf("BootstrapAdminNickname = %q, want %q", BootstrapAdminNickname, "Super Admin") - } - - roles := map[string]string{} - for _, role := range Roles { - roles[role.Code] = role.Name - } - - tests := map[string]string{ - RoleCodeSuperAdmin: "Super Admin", - RoleCodeAdmin: "Admin", - RoleCodeCsTeamLeader: "Support Team Lead", - RoleCodeCsUser: "Support Agent", - } - for code, want := range tests { - if got := roles[code]; got != want { - t.Fatalf("role %s name = %q, want %q", code, got, want) - } - } - - permissions := map[string]string{} - for _, permission := range Permissions { - permissions[permission.Code] = permission.Name - } - - permissionTests := map[string]string{ - "user.view": "View users", - "ticket.create": "Create tickets", - "conversation.send": "Send conversation messages", - "channel.view": "View channels", - "wxworkOutbox.view": "View WeCom outbox records", - "agent.view": "View agents", - } - for code, want := range permissionTests { - if got := permissions[code]; got != want { - t.Fatalf("permission %s name = %q, want %q", code, got, want) - } - } -} diff --git a/internal/pkg/dto/dto.go b/internal/pkg/dto/dto.go index 7953ba1..6f3176e 100644 --- a/internal/pkg/dto/dto.go +++ b/internal/pkg/dto/dto.go @@ -1,8 +1,12 @@ package dto -import "agent-desk/internal/pkg/enums" +import ( + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" +) type AuthPrincipal struct { + SubjectType identity.SubjectType UserID int64 Username string Nickname string @@ -17,17 +21,15 @@ type WxWorkKFChannelConfig struct { } type WebChannelConfig struct { - Title string `json:"title"` - Subtitle string `json:"subtitle"` - ThemeColor string `json:"themeColor"` - Position string `json:"position"` - Width string `json:"width"` - UserTokenSecret string `json:"userTokenSecret,omitempty"` + Title string `json:"title"` + Subtitle string `json:"subtitle"` + ThemeColor string `json:"themeColor"` + Position string `json:"position"` + Width string `json:"width"` } type WechatMPChannelConfig struct { - Title string `json:"title"` - Subtitle string `json:"subtitle"` - ThemeColor string `json:"themeColor"` - UserTokenSecret string `json:"userTokenSecret,omitempty"` + Title string `json:"title"` + Subtitle string `json:"subtitle"` + ThemeColor string `json:"themeColor"` } diff --git a/internal/pkg/dto/request/admin_request.go b/internal/pkg/dto/request/admin_request.go deleted file mode 100644 index cfa88d3..0000000 --- a/internal/pkg/dto/request/admin_request.go +++ /dev/null @@ -1,96 +0,0 @@ -package request - -import "agent-desk/internal/pkg/enums" - -type RevokeSessionRequest struct { - ID int64 `json:"id"` -} - -type RevokeUserSessionsRequest struct { - UserID int64 `json:"userId"` -} - -type CreateUserRequest struct { - Username string `json:"username"` - Nickname string `json:"nickname"` - Avatar string `json:"avatar"` - Mobile *string `json:"mobile"` - Email *string `json:"email"` - Remark string `json:"remark"` - RoleIDs []int64 `json:"roleIds"` -} - -type UpdateUserRequest struct { - ID int64 `json:"id"` - Nickname string `json:"nickname"` - Avatar string `json:"avatar"` - Mobile *string `json:"mobile"` - Email *string `json:"email"` - Remark string `json:"remark"` -} - -type DeleteUserRequest struct { - ID int64 `json:"id"` -} - -type UpdateUserStatusRequest struct { - ID int64 `json:"id"` - Status int `json:"status"` -} - -type ChangePasswordRequest struct { - Password string `json:"password"` -} - -type AssignRoleRequest struct { - UserID int64 `json:"userId"` - RoleIDs []int64 `json:"roleIds"` -} - -type CreateRoleRequest struct { - Name string `json:"name"` - Code string `json:"code"` - Remark string `json:"remark"` -} - -type UpdateRoleRequest struct { - ID int64 `json:"id"` - Name string `json:"name"` - SortNo int `json:"sortNo"` - Remark string `json:"remark"` -} - -type DeleteRoleRequest struct { - ID int64 `json:"id"` -} - -type UpdateRoleStatusRequest struct { - ID int64 `json:"id"` - Status enums.Status `json:"status"` -} - -type AssignPermissionRequest struct { - RoleID int64 `json:"roleId"` - PermissionIDs []int64 `json:"permissionIds"` -} - -type CreateConversationTagRequest struct { - Name string `json:"name"` - Color string `json:"color"` - Status int `json:"status"` - SortNo int `json:"sortNo"` - Remark string `json:"remark"` -} - -type UpdateConversationTagRequest struct { - ID int64 `json:"id"` - Name string `json:"name"` - Color string `json:"color"` - Status int `json:"status"` - SortNo int `json:"sortNo"` - Remark string `json:"remark"` -} - -type DeleteConversationTagRequest struct { - ID int64 `json:"id"` -} diff --git a/internal/pkg/dto/request/agent_request.go b/internal/pkg/dto/request/agent_request.go index 93c1ce0..c262af4 100644 --- a/internal/pkg/dto/request/agent_request.go +++ b/internal/pkg/dto/request/agent_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type CreateAgentProfileRequest struct { UserID int64 `json:"userId"` diff --git a/internal/pkg/dto/request/agent_run_request.go b/internal/pkg/dto/request/agent_run_request.go index 8b3203c..100136b 100644 --- a/internal/pkg/dto/request/agent_run_request.go +++ b/internal/pkg/dto/request/agent_run_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type SaveAgentRunQualityFeedbackRequest struct { AgentRunID int64 `json:"agentRunId"` diff --git a/internal/pkg/dto/request/ai_request.go b/internal/pkg/dto/request/ai_request.go index 299547e..152acb6 100644 --- a/internal/pkg/dto/request/ai_request.go +++ b/internal/pkg/dto/request/ai_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type AIAgentMCPToolRequest struct { ToolCode string `json:"toolCode"` diff --git a/internal/pkg/dto/request/ai_workflow_request.go b/internal/pkg/dto/request/ai_workflow_request.go index ec9b82d..3744430 100644 --- a/internal/pkg/dto/request/ai_workflow_request.go +++ b/internal/pkg/dto/request/ai_workflow_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/ai/workflow/dsl" +import "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" type CreateAIWorkflowRequest struct { Name string `json:"name"` diff --git a/internal/pkg/dto/request/auth_request.go b/internal/pkg/dto/request/auth_request.go deleted file mode 100644 index 51f1ae5..0000000 --- a/internal/pkg/dto/request/auth_request.go +++ /dev/null @@ -1,14 +0,0 @@ -package request - -type LoginRequest struct { - Username string `json:"username"` - Password string `json:"password"` -} - -type WxWorkExchangeRequest struct { - Ticket string `json:"ticket"` -} - -type OIDCExchangeRequest struct { - Ticket string `json:"ticket"` -} diff --git a/internal/pkg/dto/request/channel_request.go b/internal/pkg/dto/request/channel_request.go index a5095cb..4479ad7 100644 --- a/internal/pkg/dto/request/channel_request.go +++ b/internal/pkg/dto/request/channel_request.go @@ -28,10 +28,6 @@ type DeleteChannelRequest struct { ID int64 `json:"id"` } -type ResetChannelUserTokenSecretRequest struct { - ID int64 `json:"id"` -} - type ChannelMessageOutboxActionRequest struct { ID int64 `json:"id"` } diff --git a/internal/pkg/dto/request/knowledge_request.go b/internal/pkg/dto/request/knowledge_request.go index f0d20b0..d4dbe93 100644 --- a/internal/pkg/dto/request/knowledge_request.go +++ b/internal/pkg/dto/request/knowledge_request.go @@ -3,7 +3,7 @@ package request import ( "io" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type CreateKnowledgeBaseRequest struct { diff --git a/internal/pkg/dto/request/message_request.go b/internal/pkg/dto/request/message_request.go index 983e71d..251ff12 100644 --- a/internal/pkg/dto/request/message_request.go +++ b/internal/pkg/dto/request/message_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type MessageListRequest struct { ConversationID int64 `json:"conversationId"` diff --git a/internal/pkg/dto/request/quick_reply_request.go b/internal/pkg/dto/request/quick_reply_request.go index 0478126..eafb8f3 100644 --- a/internal/pkg/dto/request/quick_reply_request.go +++ b/internal/pkg/dto/request/quick_reply_request.go @@ -1,6 +1,6 @@ package request -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type QuickReplyListRequest struct { GroupName string `json:"groupName"` diff --git a/internal/pkg/dto/response/admin_response.go b/internal/pkg/dto/response/admin_response.go deleted file mode 100644 index 4441451..0000000 --- a/internal/pkg/dto/response/admin_response.go +++ /dev/null @@ -1,63 +0,0 @@ -package response - -import "agent-desk/internal/pkg/enums" - -type PermissionResponse struct { - ID int64 `json:"id"` - Name string `json:"name"` - Code string `json:"code"` - Type string `json:"type"` - GroupName string `json:"groupName"` - Method string `json:"method"` - ApiPath string `json:"apiPath"` - Status enums.Status `json:"status"` - SortNo int `json:"sortNo"` -} - -type PermissionSyncResponse struct { - Created int `json:"created"` - Updated int `json:"updated"` - RolePermissionsAdded int `json:"rolePermissionsAdded"` -} - -type RoleResponse struct { - ID int64 `json:"id"` - Name string `json:"name"` - Code string `json:"code"` - Status enums.Status `json:"status"` - IsSystem bool `json:"isSystem"` - SortNo int `json:"sortNo"` - Permissions []string `json:"permissions,omitempty"` -} - -type UserResponse struct { - ID int64 `json:"id"` - Username string `json:"username"` - Nickname string `json:"nickname"` - Avatar string `json:"avatar"` - Mobile string `json:"mobile,omitempty"` - Email string `json:"email,omitempty"` - Status enums.Status `json:"status"` - LastLoginAt string `json:"lastLoginAt,omitempty"` - LastLoginIP string `json:"lastLoginIp,omitempty"` - Roles []RoleResponse `json:"roles,omitempty"` - Permissions []string `json:"permissions,omitempty"` -} - -// CreateUserResultResponse 创建用户成功响应;password 仅在本次响应中返回一次。 -type CreateUserResultResponse struct { - User *UserResponse `json:"user"` - Password string `json:"password"` -} - -type SessionResponse struct { - ID int64 `json:"id"` - UserID int64 `json:"userId"` - Username string `json:"username"` - ClientType string `json:"clientType"` - ClientIP string `json:"clientIp"` - UserAgent string `json:"userAgent"` - ExpiredAt string `json:"expiredAt"` - RevokedAt string `json:"revokedAt"` - LastSeenAt string `json:"lastSeenAt"` -} diff --git a/internal/pkg/dto/response/agent_response.go b/internal/pkg/dto/response/agent_response.go index b48f85b..bc0ca6b 100644 --- a/internal/pkg/dto/response/agent_response.go +++ b/internal/pkg/dto/response/agent_response.go @@ -1,6 +1,13 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + +type AgentUserOptionResponse struct { + ID int64 `json:"id"` + Username string `json:"username"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` +} type AgentProfileResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/agent_run_response.go b/internal/pkg/dto/response/agent_run_response.go index d9aaa3e..78dab79 100644 --- a/internal/pkg/dto/response/agent_run_response.go +++ b/internal/pkg/dto/response/agent_run_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type AgentRunResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/ai_response.go b/internal/pkg/dto/response/ai_response.go index 1c73be6..fde4703 100644 --- a/internal/pkg/dto/response/ai_response.go +++ b/internal/pkg/dto/response/ai_response.go @@ -1,8 +1,8 @@ package response import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type AIAgentTeamResponse struct { diff --git a/internal/pkg/dto/response/ai_response_test.go b/internal/pkg/dto/response/ai_response_test.go index 289e529..7ed121a 100644 --- a/internal/pkg/dto/response/ai_response_test.go +++ b/internal/pkg/dto/response/ai_response_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" ) func TestBuildAIConfigResponseOmitsAPIKey(t *testing.T) { diff --git a/internal/pkg/dto/response/ai_workflow_response.go b/internal/pkg/dto/response/ai_workflow_response.go index 9f6a127..922c92f 100644 --- a/internal/pkg/dto/response/ai_workflow_response.go +++ b/internal/pkg/dto/response/ai_workflow_response.go @@ -1,10 +1,10 @@ package response import ( - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - workflowvalidator "agent-desk/internal/ai/workflow/validator" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + workflowvalidator "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/validator" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type AIWorkflowResponse struct { diff --git a/internal/pkg/dto/response/asset_response.go b/internal/pkg/dto/response/asset_response.go index 65017ab..6639bf1 100644 --- a/internal/pkg/dto/response/asset_response.go +++ b/internal/pkg/dto/response/asset_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type AssetResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/auth_response.go b/internal/pkg/dto/response/auth_response.go index c2c6e29..caeec81 100644 --- a/internal/pkg/dto/response/auth_response.go +++ b/internal/pkg/dto/response/auth_response.go @@ -1,26 +1,5 @@ package response -import "agent-desk/internal/pkg/enums" - -type AuthUserResponse struct { - ID int64 `json:"id"` - Username string `json:"username"` - Nickname string `json:"nickname"` - Avatar string `json:"avatar"` - Status enums.Status `json:"status"` - Roles []string `json:"roles"` -} - -type LoginResponse struct { - AccessToken string `json:"accessToken"` - ExpiresAt string `json:"expiresAt"` - User *AuthUserResponse `json:"user"` - Permissions []string `json:"permissions"` - Roles []string `json:"roles"` -} - type PublicConfigResponse struct { - Language string `json:"language"` - WxWorkEnabled bool `json:"wxworkEnabled"` - OIDCEnabled bool `json:"oidcEnabled"` + Language string `json:"language"` } diff --git a/internal/pkg/dto/response/channel_response.go b/internal/pkg/dto/response/channel_response.go index e1c36f9..93f9efb 100644 --- a/internal/pkg/dto/response/channel_response.go +++ b/internal/pkg/dto/response/channel_response.go @@ -1,9 +1,9 @@ package response import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" ) type ChannelResponse struct { diff --git a/internal/pkg/dto/response/company_response.go b/internal/pkg/dto/response/company_response.go index 5b1ab17..6ec0487 100644 --- a/internal/pkg/dto/response/company_response.go +++ b/internal/pkg/dto/response/company_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type CompanyResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/conversation_response.go b/internal/pkg/dto/response/conversation_response.go index 697dbfd..e73deca 100644 --- a/internal/pkg/dto/response/conversation_response.go +++ b/internal/pkg/dto/response/conversation_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type ConversationTagResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/customer_contact_response.go b/internal/pkg/dto/response/customer_contact_response.go index a7d418e..93b0250 100644 --- a/internal/pkg/dto/response/customer_contact_response.go +++ b/internal/pkg/dto/response/customer_contact_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type CustomerContactResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/customer_response.go b/internal/pkg/dto/response/customer_response.go index 9988994..eb28b5a 100644 --- a/internal/pkg/dto/response/customer_response.go +++ b/internal/pkg/dto/response/customer_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type CustomerResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/customer_session_response.go b/internal/pkg/dto/response/customer_session_response.go deleted file mode 100644 index 814d9ee..0000000 --- a/internal/pkg/dto/response/customer_session_response.go +++ /dev/null @@ -1,13 +0,0 @@ -package response - -type CustomerSessionCustomerResponse struct { - ID int64 `json:"id"` - Name string `json:"name"` -} - -type CustomerSessionExchangeResponse struct { - CustomerSessionToken string `json:"customerSessionToken"` - ExpiresAt string `json:"expiresAt"` - IdentityKey string `json:"identityKey"` - Customer CustomerSessionCustomerResponse `json:"customer"` -} diff --git a/internal/pkg/dto/response/knowledge_response.go b/internal/pkg/dto/response/knowledge_response.go index 6f83aaf..d932239 100644 --- a/internal/pkg/dto/response/knowledge_response.go +++ b/internal/pkg/dto/response/knowledge_response.go @@ -1,7 +1,7 @@ package response import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "time" ) diff --git a/internal/pkg/dto/response/mcp_response.go b/internal/pkg/dto/response/mcp_response.go index 8ff54d8..352e9c8 100644 --- a/internal/pkg/dto/response/mcp_response.go +++ b/internal/pkg/dto/response/mcp_response.go @@ -1,8 +1,8 @@ package response import ( - "agent-desk/internal/ai/mcps" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type MCPConnectionResponse struct { diff --git a/internal/pkg/dto/response/message_response.go b/internal/pkg/dto/response/message_response.go index 748afc2..dba9c9f 100644 --- a/internal/pkg/dto/response/message_response.go +++ b/internal/pkg/dto/response/message_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type MessageResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/quick_reply_response.go b/internal/pkg/dto/response/quick_reply_response.go index a06670b..3f3bda9 100644 --- a/internal/pkg/dto/response/quick_reply_response.go +++ b/internal/pkg/dto/response/quick_reply_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type QuickReplyResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/tag_response.go b/internal/pkg/dto/response/tag_response.go index cb767e0..ae293ea 100644 --- a/internal/pkg/dto/response/tag_response.go +++ b/internal/pkg/dto/response/tag_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type TagResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/dto/response/ticket_response.go b/internal/pkg/dto/response/ticket_response.go index c3c1895..cc4c155 100644 --- a/internal/pkg/dto/response/ticket_response.go +++ b/internal/pkg/dto/response/ticket_response.go @@ -1,6 +1,6 @@ package response -import "agent-desk/internal/pkg/enums" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" type TicketProgressResponse struct { ID int64 `json:"id"` diff --git a/internal/pkg/enums/enums.go b/internal/pkg/enums/enums.go index 8a6e7f0..d685eaa 100644 --- a/internal/pkg/enums/enums.go +++ b/internal/pkg/enums/enums.go @@ -57,32 +57,3 @@ func IsValidGender(gender int) bool { } return false } - -type ThirdProvider string - -const ( - ThirdProviderWxWork ThirdProvider = "wxwork" - ThirdProviderDingtalk ThirdProvider = "dingtalk" - ThirdProviderOIDC ThirdProvider = "oidc" -) - -var ThirdProviderValues = []ThirdProvider{ThirdProviderWxWork, ThirdProviderDingtalk, ThirdProviderOIDC} - -var thirdProviderLabelMap = map[ThirdProvider]string{ - ThirdProviderWxWork: "企业微信", - ThirdProviderDingtalk: "钉钉", - ThirdProviderOIDC: "OIDC", -} - -func GetThirdProviderLabel(provider ThirdProvider) string { - return thirdProviderLabelMap[provider] -} - -func IsValidThirdProvider(provider string) bool { - for _, p := range ThirdProviderValues { - if string(p) == provider { - return true - } - } - return false -} diff --git a/internal/pkg/enums/im.go b/internal/pkg/enums/im.go index da23f4c..7dfb744 100644 --- a/internal/pkg/enums/im.go +++ b/internal/pkg/enums/im.go @@ -254,7 +254,6 @@ const ( IMRealtimeEventConversationClosed = "conversation.closed" IMRealtimeEventConversationRead = "conversation.read" IMRealtimeEventNotificationCreated = "notification.created" - IMRealtimeEventCustomerSessionRefresh = "customer_session.refresh" ) const ( diff --git a/internal/pkg/errorsx/errors.go b/internal/pkg/errorsx/errors.go index f957c33..5ebcb26 100644 --- a/internal/pkg/errorsx/errors.go +++ b/internal/pkg/errorsx/errors.go @@ -1,7 +1,7 @@ package errorsx import ( - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "github.com/mlogclub/simple/web" ) diff --git a/internal/pkg/httpx/context.go b/internal/pkg/httpx/context.go index 666cd82..42eef64 100644 --- a/internal/pkg/httpx/context.go +++ b/internal/pkg/httpx/context.go @@ -1,9 +1,9 @@ package httpx import ( - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/tracex" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/common/strs" diff --git a/internal/pkg/httpx/error.go b/internal/pkg/httpx/error.go index 2a6b2fa..f53580a 100644 --- a/internal/pkg/httpx/error.go +++ b/internal/pkg/httpx/error.go @@ -1,7 +1,7 @@ package httpx import ( - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/web" diff --git a/internal/pkg/httpx/params/params.go b/internal/pkg/httpx/params/params.go index 252f1fa..bf47021 100644 --- a/internal/pkg/httpx/params/params.go +++ b/internal/pkg/httpx/params/params.go @@ -1,7 +1,7 @@ package params import ( - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "errors" "fmt" "log/slog" diff --git a/internal/pkg/httpx/path.go b/internal/pkg/httpx/path.go index 8553002..ff87225 100644 --- a/internal/pkg/httpx/path.go +++ b/internal/pkg/httpx/path.go @@ -1,7 +1,7 @@ package httpx import ( - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "net/http" "strconv" diff --git a/internal/pkg/httpx/response.go b/internal/pkg/httpx/response.go index d6347b9..cda1f88 100644 --- a/internal/pkg/httpx/response.go +++ b/internal/pkg/httpx/response.go @@ -1,8 +1,8 @@ package httpx import ( - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "net/http" "github.com/gin-gonic/gin" diff --git a/internal/pkg/httpx/response_test.go b/internal/pkg/httpx/response_test.go index a02e50b..530fc6c 100644 --- a/internal/pkg/httpx/response_test.go +++ b/internal/pkg/httpx/response_test.go @@ -1,8 +1,8 @@ package httpx import ( - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "encoding/json" "errors" "net/http" diff --git a/internal/pkg/i18nx/locales/en-US.yml b/internal/pkg/i18nx/locales/en-US.yml index 515172f..fb900b2 100644 --- a/internal/pkg/i18nx/locales/en-US.yml +++ b/internal/pkg/i18nx/locales/en-US.yml @@ -32,18 +32,6 @@ error.e0032: "MCP endpoint is required." error.e0033: "MCP server is not enabled." error.e0034: "MCP server configuration not found." error.e0035: "MCP is not enabled." -error.e0036: "OIDC clientId is not configured." -error.e0037: "OIDC clientSecret is not configured." -error.e0038: "OIDC id_token is missing." -error.e0039: "OIDC issuer is not configured." -error.e0040: "OIDC redirectUrl is not configured." -error.e0041: "OIDC authorization code is required." -error.e0042: "OIDC user information not found." -error.e0043: "OIDC user identifier not found." -error.e0044: "OIDC sign-in secret is not configured." -error.e0045: "OIDC sign-in is not enabled." -error.e0046: "OIDC sign-in state is invalid or has expired." -error.e0047: "The system user linked to this OIDC account does not exist." error.e0048: "OSS accessKeyId is not configured." error.e0049: "OSS accessKeySecret is not configured." error.e0050: "OSS bucket is not configured." @@ -183,8 +171,6 @@ error.e0183: "Closed conversations cannot be linked to customers." error.e0184: "Restore this deleted Skill before changing its status." error.e0185: "This AI Agent is linked to channels and cannot be deleted." error.e0186: "Platform message not found." -error.e0187: "The current OIDC binding has been disabled." -error.e0188: "The current WeCom binding has been disabled." error.e0189: "This conversation is not currently handled by AI." error.e0190: "This conversation has already been assigned." error.e0191: "This conversation has been assigned to another agent." @@ -356,22 +342,11 @@ error.mcp.connectServerFailed: "Failed to connect to MCP Server: %v" error.wxwork.unsupportedOutboundMessageType: "Unsupported WeCom outbound message type: %s" error.wxwork.currentUnsupportedOutboundMessageType: "The current WeCom outbound message type is not supported yet: %s" error.param.required: "Parameter %s is required." -error.oidc.loginDisabled: "OIDC login is not enabled." -error.oidc.stateSecretMissing: "OIDC login secret is not configured." -error.oidc.profileMissing: "OIDC user information does not exist." -error.oidc.bindingDisabled: "The current OIDC binding has been disabled." -error.oidc.boundUserMissing: "The system user bound to this OIDC account does not exist." -error.wxwork.loginDisabled: "WeCom login is not enabled." -error.wxwork.loginSecretMissing: "WeCom login secret is not configured." -error.wxwork.profileMissing: "WeCom user information does not exist." -error.wxwork.bindingDisabled: "The current WeCom binding has been disabled." -error.wxwork.boundUserMissing: "The system user bound to this WeCom account does not exist." error.wxwork.userIDMissing: "Failed to get the WeCom user ID." error.wxwork.userIDTaken: "The WeCom user ID is already used as a system username." error.wxwork.mobileTaken: "The WeCom mobile number is already used by a system user." error.wxwork.emailTaken: "The WeCom email address is already used by a system user." error.wxwork.configIncomplete: "WeCom is not enabled or its configuration is incomplete." -error.customerSession.secretMissing: "Customer session secret is not configured." error.conversation.createFailed: "Failed to create conversation." error.conversation.tagNotFound: "Tag not found." error.aiConfig.noneEnabled: "No available AI configuration is configured." diff --git a/internal/pkg/i18nx/locales/zh-CN.yml b/internal/pkg/i18nx/locales/zh-CN.yml index 446f006..c6a89fd 100644 --- a/internal/pkg/i18nx/locales/zh-CN.yml +++ b/internal/pkg/i18nx/locales/zh-CN.yml @@ -32,18 +32,6 @@ error.e0032: "MCP endpoint不能为空" error.e0033: "MCP服务未启用" error.e0034: "MCP服务配置不存在" error.e0035: "MCP未启用" -error.e0036: "OIDC clientId 未配置" -error.e0037: "OIDC clientSecret 未配置" -error.e0038: "OIDC id_token 不存在" -error.e0039: "OIDC issuer 未配置" -error.e0040: "OIDC redirectUrl 未配置" -error.e0041: "OIDC 授权 code 不能为空" -error.e0042: "OIDC 用户信息不存在" -error.e0043: "OIDC 用户标识不存在" -error.e0044: "OIDC 登录密钥未配置" -error.e0045: "OIDC 登录未启用" -error.e0046: "OIDC 登录状态无效或已过期" -error.e0047: "OIDC 账号绑定的系统用户不存在" error.e0048: "OSS accessKeyId 未配置" error.e0049: "OSS accessKeySecret 未配置" error.e0050: "OSS bucket 未配置" @@ -183,8 +171,6 @@ error.e0183: "已关闭的会话无法关联客户" error.e0184: "已删除的 Skill 不能直接修改状态,请先恢复" error.e0185: "已有接入渠道绑定该 AI Agent,无法删除" error.e0186: "平台消息不存在" -error.e0187: "当前 OIDC 绑定已停用" -error.e0188: "当前企业微信绑定已停用" error.e0189: "当前会话不处于 AI 接待状态" error.e0190: "当前会话已分配客服" error.e0191: "当前会话已分配给其他客服" @@ -356,22 +342,11 @@ error.mcp.connectServerFailed: "连接 MCP Server 失败: %v" error.wxwork.unsupportedOutboundMessageType: "不支持的企业微信下行消息类型: %s" error.wxwork.currentUnsupportedOutboundMessageType: "当前暂不支持企业微信下行消息类型: %s" error.param.required: "参数:%s不能为空" -error.oidc.loginDisabled: "OIDC 登录未启用" -error.oidc.stateSecretMissing: "OIDC 登录密钥未配置" -error.oidc.profileMissing: "OIDC 用户信息不存在" -error.oidc.bindingDisabled: "当前 OIDC 绑定已停用" -error.oidc.boundUserMissing: "OIDC 账号绑定的系统用户不存在" -error.wxwork.loginDisabled: "企业微信登录未启用" -error.wxwork.loginSecretMissing: "企业微信登录密钥未配置" -error.wxwork.profileMissing: "企业微信用户信息不存在" -error.wxwork.bindingDisabled: "当前企业微信绑定已停用" -error.wxwork.boundUserMissing: "企业微信账号绑定的系统用户不存在" error.wxwork.userIDMissing: "企业微信用户ID获取失败" error.wxwork.userIDTaken: "企业微信用户ID已被系统用户名占用" error.wxwork.mobileTaken: "企业微信手机号已被系统用户占用" error.wxwork.emailTaken: "企业微信邮箱已被系统用户占用" error.wxwork.configIncomplete: "企业微信未启用或配置不完整" -error.customerSession.secretMissing: "客服会话密钥未配置" error.conversation.createFailed: "创建会话失败" error.conversation.tagNotFound: "标签不存在" error.aiConfig.noneEnabled: "未配置可用的 AI 配置" diff --git a/internal/pkg/openidentity/openidentity.go b/internal/pkg/openidentity/openidentity.go index cb6b365..bd7f5a9 100644 --- a/internal/pkg/openidentity/openidentity.go +++ b/internal/pkg/openidentity/openidentity.go @@ -1,139 +1,12 @@ package openidentity -import ( - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "errors" - "net/url" - "strings" +import "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" - "github.com/mlogclub/simple/common/strs" -) - -// ExternalUser 外部访客身份(IM 客户),与站内 AuthPrincipal 区分。 +// ExternalUser is a be-system user identity adapted for customer-service +// conversations. Authentication is completed by the host before this value is +// created; this package contains no token parsing or verification. type ExternalUser struct { ExternalSource enums.ExternalSource `json:"externalSource"` ExternalID string `json:"externalId"` ExternalName string `json:"externalName"` } - -type UserTokenClaims struct { - UserID string `json:"userId"` - Name string `json:"name"` - jwt.RegisteredClaims -} - -func GetExternalUser(ctx *gin.Context, secret string) (*ExternalUser, error) { - if userToken := getUserToken(ctx); strs.IsNotBlank(userToken) { - claims, err := verifyUserToken(userToken, secret) - if err != nil { - return nil, err - } - return &ExternalUser{ - ExternalSource: enums.ExternalSourceUser, - ExternalID: claims.UserID, - ExternalName: claims.Name, - }, nil - } - return getGuestUser(ctx) -} - -func verifyUserToken(userToken, secret string) (*UserTokenClaims, error) { - if strs.IsBlank(userToken) { - return nil, errorsx.UnauthorizedI18n("error.e0263") - } - if strs.IsBlank(secret) { - return nil, errorsx.UnauthorizedI18n("error.e0266") - } - - claims := &UserTokenClaims{} - token, err := jwt.ParseWithClaims(userToken, claims, func(token *jwt.Token) (any, error) { - if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { - return nil, errors.New("unsupported signing method") - } - return []byte(secret), nil - }, jwt.WithExpirationRequired(), jwt.WithValidMethods([]string{ - jwt.SigningMethodHS256.Alg(), - jwt.SigningMethodHS384.Alg(), - jwt.SigningMethodHS512.Alg(), - })) - if err != nil { - if errors.Is(err, jwt.ErrTokenExpired) { - return nil, errorsx.UnauthorizedI18n("error.e0264") - } - return nil, errorsx.UnauthorizedI18n("error.e0265") - } - if token == nil || !token.Valid { - return nil, errorsx.UnauthorizedI18n("error.e0265") - } - - if strs.IsBlank(claims.UserID) { - return nil, errorsx.UnauthorizedI18n("error.e0262") - } - if strs.IsBlank(claims.Name) { - return nil, errorsx.UnauthorizedI18n("error.e0261") - } - if claims.ExpiresAt == nil { - return nil, errorsx.UnauthorizedI18n("error.e0264") - } - - return claims, nil -} - -func getUserToken(ctx *gin.Context) string { - auth := strings.TrimSpace(ctx.GetHeader("Authorization")) - if len(auth) > 7 && strings.EqualFold(auth[:7], "Bearer ") { - if token := strings.TrimSpace(auth[7:]); token != "" { - return token - } - } - userToken, _ := params.Get(ctx, "userToken") - return strings.TrimSpace(userToken) -} - -func getGuestUser(ctx *gin.Context) (*ExternalUser, error) { - externalID := getExternalID(ctx) - if strs.IsBlank(externalID) { - return nil, errorsx.UnauthorizedI18n("error.e0262") - } - return &ExternalUser{ - ExternalSource: enums.ExternalSourceGuest, - ExternalID: externalID, - ExternalName: getExternalName(ctx), - }, nil -} - -func getExternalID(ctx *gin.Context) string { - externalID := ctx.GetHeader("X-External-Id") - if strs.IsBlank(externalID) { - externalID, _ = params.Get(ctx, "externalId") - } - return externalID -} - -func getExternalName(ctx *gin.Context) string { - externalName := ctx.GetHeader("X-External-Name") - if strs.IsBlank(externalName) { - externalName, _ = params.Get(ctx, "externalName") - } - if strs.IsNotBlank(externalName) { - externalName, _ = url.QueryUnescape(externalName) - } - return externalName -} - -func decodeExternalDisplayName(s string) string { - s = strings.TrimSpace(s) - if s == "" { - return "" - } - dec, err := url.QueryUnescape(s) - if err != nil { - return s - } - return strings.TrimSpace(dec) -} diff --git a/internal/pkg/openidentity/openidentity_test.go b/internal/pkg/openidentity/openidentity_test.go deleted file mode 100644 index d6e7417..0000000 --- a/internal/pkg/openidentity/openidentity_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package openidentity - -import ( - "testing" - "time" - - "github.com/golang-jwt/jwt/v5" -) - -func TestVerifyUserTokenOK(t *testing.T) { - token := signTestUserToken(t, jwt.SigningMethodHS256, map[string]any{ - "userId": "u_10001", - "name": "张三", - "exp": time.Now().Add(time.Hour).Unix(), - }, "secret") - - claims, err := verifyUserToken(token, "secret") - if err != nil { - t.Fatalf("expected token to verify: %v", err) - } - if claims.UserID != "u_10001" || claims.Name != "张三" { - t.Fatalf("unexpected claims: %#v", claims) - } -} - -func TestVerifyUserTokenUsesJWTHeaderAlgorithm(t *testing.T) { - token := signTestUserToken(t, jwt.SigningMethodHS384, map[string]any{ - "userId": "u_10001", - "name": "张三", - "exp": time.Now().Add(time.Hour).Unix(), - }, "secret") - - claims, err := verifyUserToken(token, "secret") - if err != nil { - t.Fatalf("expected HS384 token to verify from JWT header: %v", err) - } - if claims.UserID != "u_10001" || claims.Name != "张三" { - t.Fatalf("unexpected claims: %#v", claims) - } -} - -func TestVerifyUserTokenRejectsInvalidSignature(t *testing.T) { - token := signTestUserToken(t, jwt.SigningMethodHS256, map[string]any{ - "userId": "u_10001", - "name": "张三", - "exp": time.Now().Add(time.Hour).Unix(), - }, "secret") - - if _, err := verifyUserToken(token, "other-secret"); err == nil { - t.Fatalf("expected invalid signature to fail") - } -} - -func TestVerifyUserTokenRejectsExpiredToken(t *testing.T) { - token := signTestUserToken(t, jwt.SigningMethodHS256, map[string]any{ - "userId": "u_10001", - "name": "张三", - "exp": time.Now().Add(-time.Minute).Unix(), - }, "secret") - - if _, err := verifyUserToken(token, "secret"); err == nil { - t.Fatalf("expected expired token to fail") - } -} - -func TestVerifyUserTokenRequiresUserIDAndName(t *testing.T) { - tests := []map[string]any{ - {"name": "张三", "exp": time.Now().Add(time.Hour).Unix()}, - {"userId": "u_10001", "exp": time.Now().Add(time.Hour).Unix()}, - } - for _, payload := range tests { - token := signTestUserToken(t, jwt.SigningMethodHS256, payload, "secret") - if _, err := verifyUserToken(token, "secret"); err == nil { - t.Fatalf("expected payload %#v to fail", payload) - } - } -} - -func signTestUserToken(t *testing.T, method jwt.SigningMethod, payload map[string]any, secret string) string { - t.Helper() - token, err := jwt.NewWithClaims(method, jwt.MapClaims(payload)).SignedString([]byte(secret)) - if err != nil { - t.Fatal(err) - } - return token -} diff --git a/internal/pkg/toolx/builtin_tools.go b/internal/pkg/toolx/builtin_tools.go index 2ff4dd6..143f6c0 100644 --- a/internal/pkg/toolx/builtin_tools.go +++ b/internal/pkg/toolx/builtin_tools.go @@ -3,8 +3,8 @@ package toolx import ( "strings" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" ) type ToolSpec struct { diff --git a/internal/pkg/toolx/builtin_tools_test.go b/internal/pkg/toolx/builtin_tools_test.go index fd7d41e..6f5de90 100644 --- a/internal/pkg/toolx/builtin_tools_test.go +++ b/internal/pkg/toolx/builtin_tools_test.go @@ -3,7 +3,7 @@ package toolx import ( "testing" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" ) func TestResolveToolMetadata(t *testing.T) { diff --git a/internal/pkg/toolx/mcp_policy.go b/internal/pkg/toolx/mcp_policy.go index fd9c0e5..e531d98 100644 --- a/internal/pkg/toolx/mcp_policy.go +++ b/internal/pkg/toolx/mcp_policy.go @@ -3,7 +3,7 @@ package toolx import ( "strings" - "agent-desk/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" ) const ( diff --git a/internal/pkg/toolx/mcp_tool.go b/internal/pkg/toolx/mcp_tool.go index 858dbe3..e1db059 100644 --- a/internal/pkg/toolx/mcp_tool.go +++ b/internal/pkg/toolx/mcp_tool.go @@ -4,8 +4,8 @@ import ( "encoding/json" "strings" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) func BuildMCPToolCode(serverCode, toolName string) string { diff --git a/internal/pkg/utils/content_chunk.go b/internal/pkg/utils/content_chunk.go index 6d1fe77..4797592 100644 --- a/internal/pkg/utils/content_chunk.go +++ b/internal/pkg/utils/content_chunk.go @@ -1,7 +1,7 @@ package utils import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "strings" "golang.org/x/net/html" diff --git a/internal/pkg/utils/content_chunk_test.go b/internal/pkg/utils/content_chunk_test.go index d425df1..16caf19 100644 --- a/internal/pkg/utils/content_chunk_test.go +++ b/internal/pkg/utils/content_chunk_test.go @@ -1,7 +1,7 @@ package utils import ( - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "reflect" "testing" ) diff --git a/internal/pkg/utils/message.go b/internal/pkg/utils/message.go index 36497b3..7379798 100644 --- a/internal/pkg/utils/message.go +++ b/internal/pkg/utils/message.go @@ -1,10 +1,10 @@ package utils import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - "agent-desk/internal/services/storage" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/services/storage" "bytes" "encoding/json" "fmt" diff --git a/internal/pkg/utils/message_test.go b/internal/pkg/utils/message_test.go index e3dc7d1..cd56e90 100644 --- a/internal/pkg/utils/message_test.go +++ b/internal/pkg/utils/message_test.go @@ -1,9 +1,9 @@ package utils import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "strings" "testing" "time" diff --git a/internal/pkg/utils/utils.go b/internal/pkg/utils/utils.go index d258567..231849a 100644 --- a/internal/pkg/utils/utils.go +++ b/internal/pkg/utils/utils.go @@ -1,9 +1,9 @@ package utils import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "crypto/rand" "strconv" "strings" diff --git a/internal/repositories/agent_profile_repository.go b/internal/repositories/agent_profile_repository.go index ab2e28d..f785cf8 100644 --- a/internal/repositories/agent_profile_repository.go +++ b/internal/repositories/agent_profile_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_revision_repository.go b/internal/repositories/agent_revision_repository.go index 6296382..18dfb46 100644 --- a/internal/repositories/agent_revision_repository.go +++ b/internal/repositories/agent_revision_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "gorm.io/gorm" ) diff --git a/internal/repositories/agent_run_quality_feedback_repository.go b/internal/repositories/agent_run_quality_feedback_repository.go index 14fc697..03242b4 100644 --- a/internal/repositories/agent_run_quality_feedback_repository.go +++ b/internal/repositories/agent_run_quality_feedback_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "gorm.io/gorm" ) diff --git a/internal/repositories/agent_run_repository.go b/internal/repositories/agent_run_repository.go index 70c2d8b..7f13508 100644 --- a/internal/repositories/agent_run_repository.go +++ b/internal/repositories/agent_run_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_step_repository.go b/internal/repositories/agent_step_repository.go index 1e9d7c0..edb497b 100644 --- a/internal/repositories/agent_step_repository.go +++ b/internal/repositories/agent_step_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_team_repository.go b/internal/repositories/agent_team_repository.go index 29bcf74..fc37b9c 100644 --- a/internal/repositories/agent_team_repository.go +++ b/internal/repositories/agent_team_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_team_schedule_repository.go b/internal/repositories/agent_team_schedule_repository.go index 617f803..883631a 100644 --- a/internal/repositories/agent_team_schedule_repository.go +++ b/internal/repositories/agent_team_schedule_repository.go @@ -1,11 +1,11 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_tool_call_repository.go b/internal/repositories/agent_tool_call_repository.go index 243636f..64683d8 100644 --- a/internal/repositories/agent_tool_call_repository.go +++ b/internal/repositories/agent_tool_call_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/agent_tool_invocation_repository.go b/internal/repositories/agent_tool_invocation_repository.go index f0601b4..26df5a3 100644 --- a/internal/repositories/agent_tool_invocation_repository.go +++ b/internal/repositories/agent_tool_invocation_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "gorm.io/gorm" ) diff --git a/internal/repositories/ai_agent_repository.go b/internal/repositories/ai_agent_repository.go index f56992f..0dfce09 100644 --- a/internal/repositories/ai_agent_repository.go +++ b/internal/repositories/ai_agent_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ai_agent_workflow_binding_repository.go b/internal/repositories/ai_agent_workflow_binding_repository.go index d21679d..4fd894d 100644 --- a/internal/repositories/ai_agent_workflow_binding_repository.go +++ b/internal/repositories/ai_agent_workflow_binding_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "gorm.io/gorm" ) diff --git a/internal/repositories/ai_config_repository.go b/internal/repositories/ai_config_repository.go index ae32def..2e479d1 100644 --- a/internal/repositories/ai_config_repository.go +++ b/internal/repositories/ai_config_repository.go @@ -1,10 +1,10 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ai_workflow_node_run_repository.go b/internal/repositories/ai_workflow_node_run_repository.go index f63c4b5..02e6786 100644 --- a/internal/repositories/ai_workflow_node_run_repository.go +++ b/internal/repositories/ai_workflow_node_run_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ai_workflow_repository.go b/internal/repositories/ai_workflow_repository.go index 877a87c..5a2c574 100644 --- a/internal/repositories/ai_workflow_repository.go +++ b/internal/repositories/ai_workflow_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ai_workflow_run_repository.go b/internal/repositories/ai_workflow_run_repository.go index f4624f7..9a54a28 100644 --- a/internal/repositories/ai_workflow_run_repository.go +++ b/internal/repositories/ai_workflow_run_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ai_workflow_version_repository.go b/internal/repositories/ai_workflow_version_repository.go index a997e4e..1e4267d 100644 --- a/internal/repositories/ai_workflow_version_repository.go +++ b/internal/repositories/ai_workflow_version_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/asset_repository.go b/internal/repositories/asset_repository.go index 218eb58..afa5d9a 100644 --- a/internal/repositories/asset_repository.go +++ b/internal/repositories/asset_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/channel_message_outbox_repository.go b/internal/repositories/channel_message_outbox_repository.go index d6667bc..519808b 100644 --- a/internal/repositories/channel_message_outbox_repository.go +++ b/internal/repositories/channel_message_outbox_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/channel_repository.go b/internal/repositories/channel_repository.go index f8e0752..08a8dcc 100644 --- a/internal/repositories/channel_repository.go +++ b/internal/repositories/channel_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/repositories/company_repository.go b/internal/repositories/company_repository.go index 92552de..3f16279 100644 --- a/internal/repositories/company_repository.go +++ b/internal/repositories/company_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_assignment_repository.go b/internal/repositories/conversation_assignment_repository.go index aef1b95..ae58780 100644 --- a/internal/repositories/conversation_assignment_repository.go +++ b/internal/repositories/conversation_assignment_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_event_log_repository.go b/internal/repositories/conversation_event_log_repository.go index 875f276..318a4ff 100644 --- a/internal/repositories/conversation_event_log_repository.go +++ b/internal/repositories/conversation_event_log_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_interrupt_repository.go b/internal/repositories/conversation_interrupt_repository.go index 7d01b15..ac8ca2d 100644 --- a/internal/repositories/conversation_interrupt_repository.go +++ b/internal/repositories/conversation_interrupt_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_participant_repository.go b/internal/repositories/conversation_participant_repository.go index 467683a..a0004ff 100644 --- a/internal/repositories/conversation_participant_repository.go +++ b/internal/repositories/conversation_participant_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_read_state_repository.go b/internal/repositories/conversation_read_state_repository.go index 9483669..25274dc 100644 --- a/internal/repositories/conversation_read_state_repository.go +++ b/internal/repositories/conversation_read_state_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_repository.go b/internal/repositories/conversation_repository.go index da9596a..73c5331 100644 --- a/internal/repositories/conversation_repository.go +++ b/internal/repositories/conversation_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/conversation_tag_repository.go b/internal/repositories/conversation_tag_repository.go index 262f6c1..bffe245 100644 --- a/internal/repositories/conversation_tag_repository.go +++ b/internal/repositories/conversation_tag_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/customer_contact_repository.go b/internal/repositories/customer_contact_repository.go index 2308b05..973a49a 100644 --- a/internal/repositories/customer_contact_repository.go +++ b/internal/repositories/customer_contact_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/customer_identity_repository.go b/internal/repositories/customer_identity_repository.go index 1a032eb..0f3ee11 100644 --- a/internal/repositories/customer_identity_repository.go +++ b/internal/repositories/customer_identity_repository.go @@ -1,10 +1,10 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/repositories/customer_repository.go b/internal/repositories/customer_repository.go index 81381ab..6a668f6 100644 --- a/internal/repositories/customer_repository.go +++ b/internal/repositories/customer_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/dashboard_repository.go b/internal/repositories/dashboard_repository.go index 49dc6c9..22efc6b 100644 --- a/internal/repositories/dashboard_repository.go +++ b/internal/repositories/dashboard_repository.go @@ -1,8 +1,8 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "time" "gorm.io/gorm" diff --git a/internal/repositories/knowledge_base_repository.go b/internal/repositories/knowledge_base_repository.go index 82e9b73..a15dcc2 100644 --- a/internal/repositories/knowledge_base_repository.go +++ b/internal/repositories/knowledge_base_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/knowledge_chunk_repository.go b/internal/repositories/knowledge_chunk_repository.go index a19b7b7..1fddc1e 100644 --- a/internal/repositories/knowledge_chunk_repository.go +++ b/internal/repositories/knowledge_chunk_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/knowledge_directory_repository.go b/internal/repositories/knowledge_directory_repository.go index 73bea86..a268ee6 100644 --- a/internal/repositories/knowledge_directory_repository.go +++ b/internal/repositories/knowledge_directory_repository.go @@ -1,7 +1,7 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/knowledge_document_repository.go b/internal/repositories/knowledge_document_repository.go index 476e9d3..97efa64 100644 --- a/internal/repositories/knowledge_document_repository.go +++ b/internal/repositories/knowledge_document_repository.go @@ -1,10 +1,10 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/knowledge_document_repository_test.go b/internal/repositories/knowledge_document_repository_test.go index 409f1fc..9b2509a 100644 --- a/internal/repositories/knowledge_document_repository_test.go +++ b/internal/repositories/knowledge_document_repository_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/repositories/knowledge_faq_repository.go b/internal/repositories/knowledge_faq_repository.go index 600b148..069869e 100644 --- a/internal/repositories/knowledge_faq_repository.go +++ b/internal/repositories/knowledge_faq_repository.go @@ -1,10 +1,10 @@ package repositories import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/login_credential_log_repository.go b/internal/repositories/login_credential_log_repository.go deleted file mode 100644 index 58b901d..0000000 --- a/internal/repositories/login_credential_log_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var LoginCredentialLogRepository = newLoginCredentialLogRepository() - -func newLoginCredentialLogRepository() *loginCredentialLogRepository { - return &loginCredentialLogRepository{} -} - -type loginCredentialLogRepository struct { -} - -func (r *loginCredentialLogRepository) Get(db *gorm.DB, id int64) *models.LoginCredentialLog { - ret := &models.LoginCredentialLog{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *loginCredentialLogRepository) Take(db *gorm.DB, where ...interface{}) *models.LoginCredentialLog { - ret := &models.LoginCredentialLog{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *loginCredentialLogRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.LoginCredentialLog) { - cnd.Find(db, &list) - return -} - -func (r *loginCredentialLogRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.LoginCredentialLog { - ret := &models.LoginCredentialLog{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *loginCredentialLogRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.LoginCredentialLog, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *loginCredentialLogRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.LoginCredentialLog, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.LoginCredentialLog{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *loginCredentialLogRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.LoginCredentialLog) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *loginCredentialLogRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *loginCredentialLogRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.LoginCredentialLog{}) -} - -func (r *loginCredentialLogRepository) Create(db *gorm.DB, t *models.LoginCredentialLog) (err error) { - err = db.Create(t).Error - return -} - -func (r *loginCredentialLogRepository) Update(db *gorm.DB, t *models.LoginCredentialLog) (err error) { - err = db.Save(t).Error - return -} - -func (r *loginCredentialLogRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.LoginCredentialLog{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *loginCredentialLogRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.LoginCredentialLog{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *loginCredentialLogRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.LoginCredentialLog{}, "id = ?", id) -} diff --git a/internal/repositories/login_session_repository.go b/internal/repositories/login_session_repository.go deleted file mode 100644 index 6374a27..0000000 --- a/internal/repositories/login_session_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var LoginSessionRepository = newLoginSessionRepository() - -func newLoginSessionRepository() *loginSessionRepository { - return &loginSessionRepository{} -} - -type loginSessionRepository struct { -} - -func (r *loginSessionRepository) Get(db *gorm.DB, id int64) *models.LoginSession { - ret := &models.LoginSession{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *loginSessionRepository) Take(db *gorm.DB, where ...interface{}) *models.LoginSession { - ret := &models.LoginSession{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *loginSessionRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.LoginSession) { - cnd.Find(db, &list) - return -} - -func (r *loginSessionRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.LoginSession { - ret := &models.LoginSession{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *loginSessionRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.LoginSession, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *loginSessionRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.LoginSession, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.LoginSession{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *loginSessionRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.LoginSession) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *loginSessionRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *loginSessionRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.LoginSession{}) -} - -func (r *loginSessionRepository) Create(db *gorm.DB, t *models.LoginSession) (err error) { - err = db.Create(t).Error - return -} - -func (r *loginSessionRepository) Update(db *gorm.DB, t *models.LoginSession) (err error) { - err = db.Save(t).Error - return -} - -func (r *loginSessionRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.LoginSession{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *loginSessionRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.LoginSession{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *loginSessionRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.LoginSession{}, "id = ?", id) -} diff --git a/internal/repositories/message_repository.go b/internal/repositories/message_repository.go index 5f9d0a9..425acf7 100644 --- a/internal/repositories/message_repository.go +++ b/internal/repositories/message_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/migration_repository.go b/internal/repositories/migration_repository.go index c8d1f2b..7e517ab 100644 --- a/internal/repositories/migration_repository.go +++ b/internal/repositories/migration_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/notification_repository.go b/internal/repositories/notification_repository.go index a980c75..40017bf 100644 --- a/internal/repositories/notification_repository.go +++ b/internal/repositories/notification_repository.go @@ -3,9 +3,9 @@ package repositories import ( "time" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/permission_repository.go b/internal/repositories/permission_repository.go deleted file mode 100644 index 7107eab..0000000 --- a/internal/repositories/permission_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var PermissionRepository = newPermissionRepository() - -func newPermissionRepository() *permissionRepository { - return &permissionRepository{} -} - -type permissionRepository struct { -} - -func (r *permissionRepository) Get(db *gorm.DB, id int64) *models.Permission { - ret := &models.Permission{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *permissionRepository) Take(db *gorm.DB, where ...interface{}) *models.Permission { - ret := &models.Permission{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *permissionRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.Permission) { - cnd.Find(db, &list) - return -} - -func (r *permissionRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.Permission { - ret := &models.Permission{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *permissionRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.Permission, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *permissionRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.Permission, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.Permission{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *permissionRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.Permission) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *permissionRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *permissionRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.Permission{}) -} - -func (r *permissionRepository) Create(db *gorm.DB, t *models.Permission) (err error) { - err = db.Create(t).Error - return -} - -func (r *permissionRepository) Update(db *gorm.DB, t *models.Permission) (err error) { - err = db.Save(t).Error - return -} - -func (r *permissionRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.Permission{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *permissionRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.Permission{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *permissionRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.Permission{}, "id = ?", id) -} diff --git a/internal/repositories/quick_reply_repository.go b/internal/repositories/quick_reply_repository.go index 1574995..cf1ac34 100644 --- a/internal/repositories/quick_reply_repository.go +++ b/internal/repositories/quick_reply_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/role_permission_repository.go b/internal/repositories/role_permission_repository.go deleted file mode 100644 index 65c08c0..0000000 --- a/internal/repositories/role_permission_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var RolePermissionRepository = newRolePermissionRepository() - -func newRolePermissionRepository() *rolePermissionRepository { - return &rolePermissionRepository{} -} - -type rolePermissionRepository struct { -} - -func (r *rolePermissionRepository) Get(db *gorm.DB, id int64) *models.RolePermission { - ret := &models.RolePermission{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *rolePermissionRepository) Take(db *gorm.DB, where ...interface{}) *models.RolePermission { - ret := &models.RolePermission{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *rolePermissionRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.RolePermission) { - cnd.Find(db, &list) - return -} - -func (r *rolePermissionRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.RolePermission { - ret := &models.RolePermission{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *rolePermissionRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.RolePermission, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *rolePermissionRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.RolePermission, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.RolePermission{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *rolePermissionRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.RolePermission) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *rolePermissionRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *rolePermissionRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.RolePermission{}) -} - -func (r *rolePermissionRepository) Create(db *gorm.DB, t *models.RolePermission) (err error) { - err = db.Create(t).Error - return -} - -func (r *rolePermissionRepository) Update(db *gorm.DB, t *models.RolePermission) (err error) { - err = db.Save(t).Error - return -} - -func (r *rolePermissionRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.RolePermission{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *rolePermissionRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.RolePermission{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *rolePermissionRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.RolePermission{}, "id = ?", id) -} diff --git a/internal/repositories/role_repository.go b/internal/repositories/role_repository.go deleted file mode 100644 index 5825f81..0000000 --- a/internal/repositories/role_repository.go +++ /dev/null @@ -1,106 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var RoleRepository = newRoleRepository() - -func newRoleRepository() *roleRepository { - return &roleRepository{} -} - -type roleRepository struct { -} - -func (r *roleRepository) Get(db *gorm.DB, id int64) *models.Role { - ret := &models.Role{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *roleRepository) Take(db *gorm.DB, where ...interface{}) *models.Role { - ret := &models.Role{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *roleRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.Role) { - cnd.Find(db, &list) - return -} - -func (r *roleRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.Role { - ret := &models.Role{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *roleRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.Role, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *roleRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.Role, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.Role{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *roleRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.Role) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *roleRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *roleRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.Role{}) -} - -func (r *roleRepository) Create(db *gorm.DB, t *models.Role) (err error) { - err = db.Create(t).Error - return -} - -func (r *roleRepository) Update(db *gorm.DB, t *models.Role) (err error) { - err = db.Save(t).Error - return -} - -func (r *roleRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.Role{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *roleRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.Role{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *roleRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.Role{}, "id = ?", id) -} - -func (r *roleRepository) GetByCode(db *gorm.DB, code string) *models.Role { - return r.FindOne(db, sqls.NewCnd().Eq("code", code)) -} diff --git a/internal/repositories/skill_definition_repository.go b/internal/repositories/skill_definition_repository.go index ea292ce..a3b7dca 100644 --- a/internal/repositories/skill_definition_repository.go +++ b/internal/repositories/skill_definition_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/system_config_repository.go b/internal/repositories/system_config_repository.go index 64830e3..7d1bc50 100644 --- a/internal/repositories/system_config_repository.go +++ b/internal/repositories/system_config_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/tag_repository.go b/internal/repositories/tag_repository.go index cc162c2..233ad64 100644 --- a/internal/repositories/tag_repository.go +++ b/internal/repositories/tag_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ticket_no_sequence_repository.go b/internal/repositories/ticket_no_sequence_repository.go index cbab902..518634b 100644 --- a/internal/repositories/ticket_no_sequence_repository.go +++ b/internal/repositories/ticket_no_sequence_repository.go @@ -1,11 +1,11 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "errors" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ticket_progress_repository.go b/internal/repositories/ticket_progress_repository.go index cd6f9db..46d37e2 100644 --- a/internal/repositories/ticket_progress_repository.go +++ b/internal/repositories/ticket_progress_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ticket_repository.go b/internal/repositories/ticket_repository.go index c98ee14..d5292e5 100644 --- a/internal/repositories/ticket_repository.go +++ b/internal/repositories/ticket_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ticket_tag_repository.go b/internal/repositories/ticket_tag_repository.go index b3ff050..e978da8 100644 --- a/internal/repositories/ticket_tag_repository.go +++ b/internal/repositories/ticket_tag_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/ticket_view_repository.go b/internal/repositories/ticket_view_repository.go index 3c64c4f..fd5ef8c 100644 --- a/internal/repositories/ticket_view_repository.go +++ b/internal/repositories/ticket_view_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/user_identity_repository.go b/internal/repositories/user_identity_repository.go deleted file mode 100644 index 91a5503..0000000 --- a/internal/repositories/user_identity_repository.go +++ /dev/null @@ -1,111 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "strings" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var UserIdentityRepository = newUserIdentityRepository() - -func newUserIdentityRepository() *userIdentityRepository { - return &userIdentityRepository{} -} - -type userIdentityRepository struct { -} - -func (r *userIdentityRepository) Get(db *gorm.DB, id int64) *models.UserIdentity { - ret := &models.UserIdentity{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *userIdentityRepository) Take(db *gorm.DB, where ...interface{}) *models.UserIdentity { - ret := &models.UserIdentity{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *userIdentityRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserIdentity) { - cnd.Find(db, &list) - return -} - -func (r *userIdentityRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.UserIdentity { - ret := &models.UserIdentity{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *userIdentityRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.UserIdentity, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *userIdentityRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserIdentity, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.UserIdentity{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *userIdentityRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.UserIdentity) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *userIdentityRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *userIdentityRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.UserIdentity{}) -} - -func (r *userIdentityRepository) Create(db *gorm.DB, t *models.UserIdentity) (err error) { - err = db.Create(t).Error - return -} - -func (r *userIdentityRepository) Update(db *gorm.DB, t *models.UserIdentity) (err error) { - err = db.Save(t).Error - return -} - -func (r *userIdentityRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.UserIdentity{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *userIdentityRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.UserIdentity{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *userIdentityRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.UserIdentity{}, "id = ?", id) -} - -func (r *userIdentityRepository) GetBy(db *gorm.DB, provider enums.ThirdProvider, corpId, userId string) *models.UserIdentity { - return r.FindOne(db, sqls.NewCnd(). - Eq("provider", provider). - Eq("provider_corp_id", strings.TrimSpace(corpId)). - Eq("provider_user_id", strings.TrimSpace(userId))) -} diff --git a/internal/repositories/user_permission_repository.go b/internal/repositories/user_permission_repository.go deleted file mode 100644 index 7770fc2..0000000 --- a/internal/repositories/user_permission_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var UserPermissionRepository = newUserPermissionRepository() - -func newUserPermissionRepository() *userPermissionRepository { - return &userPermissionRepository{} -} - -type userPermissionRepository struct { -} - -func (r *userPermissionRepository) Get(db *gorm.DB, id int64) *models.UserPermission { - ret := &models.UserPermission{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *userPermissionRepository) Take(db *gorm.DB, where ...interface{}) *models.UserPermission { - ret := &models.UserPermission{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *userPermissionRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserPermission) { - cnd.Find(db, &list) - return -} - -func (r *userPermissionRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.UserPermission { - ret := &models.UserPermission{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *userPermissionRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.UserPermission, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *userPermissionRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserPermission, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.UserPermission{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *userPermissionRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.UserPermission) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *userPermissionRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *userPermissionRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.UserPermission{}) -} - -func (r *userPermissionRepository) Create(db *gorm.DB, t *models.UserPermission) (err error) { - err = db.Create(t).Error - return -} - -func (r *userPermissionRepository) Update(db *gorm.DB, t *models.UserPermission) (err error) { - err = db.Save(t).Error - return -} - -func (r *userPermissionRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.UserPermission{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *userPermissionRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.UserPermission{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *userPermissionRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.UserPermission{}, "id = ?", id) -} diff --git a/internal/repositories/user_repository.go b/internal/repositories/user_repository.go deleted file mode 100644 index ebbcb3c..0000000 --- a/internal/repositories/user_repository.go +++ /dev/null @@ -1,136 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - "strings" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var UserRepository = newUserRepository() - -func newUserRepository() *userRepository { - return &userRepository{} -} - -type userRepository struct { -} - -func (r *userRepository) Get(db *gorm.DB, id int64) *models.User { - ret := &models.User{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *userRepository) Take(db *gorm.DB, where ...interface{}) *models.User { - ret := &models.User{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *userRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.User) { - cnd.Find(db, &list) - return -} - -func (r *userRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.User { - ret := &models.User{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *userRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.User, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *userRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.User, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.User{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *userRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.User) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *userRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *userRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.User{}) -} - -func (r *userRepository) Create(db *gorm.DB, t *models.User) (err error) { - err = db.Create(t).Error - return -} - -func (r *userRepository) Update(db *gorm.DB, t *models.User) (err error) { - err = db.Save(t).Error - return -} - -func (r *userRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.User{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *userRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.User{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *userRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.User{}, "id = ?", id) -} - -func (r *userRepository) FindByIds(db *gorm.DB, ids []int64) []models.User { - if len(ids) == 0 { - return []models.User{} - } - var list []models.User - db.Where("id IN ?", ids).Find(&list) - return list -} - -func (r *userRepository) GetByUsername(db *gorm.DB, username string) *models.User { - username = strings.TrimSpace(username) - if username == "" { - return nil - } - return r.Take(db, "username = ?", username) -} - -func (r *userRepository) GetByMobile(db *gorm.DB, mobile string) *models.User { - mobile = strings.TrimSpace(mobile) - if mobile == "" { - return nil - } - return r.Take(db, "mobile = ?", mobile) -} - -func (r *userRepository) GetByEmail(db *gorm.DB, email string) *models.User { - email = strings.TrimSpace(email) - if email == "" { - return nil - } - return r.Take(db, "email = ?", email) -} diff --git a/internal/repositories/user_role_repository.go b/internal/repositories/user_role_repository.go deleted file mode 100644 index 6a927a7..0000000 --- a/internal/repositories/user_role_repository.go +++ /dev/null @@ -1,102 +0,0 @@ -package repositories - -import ( - "agent-desk/internal/models" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var UserRoleRepository = newUserRoleRepository() - -func newUserRoleRepository() *userRoleRepository { - return &userRoleRepository{} -} - -type userRoleRepository struct { -} - -func (r *userRoleRepository) Get(db *gorm.DB, id int64) *models.UserRole { - ret := &models.UserRole{} - if err := db.First(ret, "id = ?", id).Error; err != nil { - return nil - } - return ret -} - -func (r *userRoleRepository) Take(db *gorm.DB, where ...interface{}) *models.UserRole { - ret := &models.UserRole{} - if err := db.Take(ret, where...).Error; err != nil { - return nil - } - return ret -} - -func (r *userRoleRepository) Find(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserRole) { - cnd.Find(db, &list) - return -} - -func (r *userRoleRepository) FindOne(db *gorm.DB, cnd *sqls.Cnd) *models.UserRole { - ret := &models.UserRole{} - if err := cnd.FindOne(db, &ret); err != nil { - return nil - } - return ret -} - -func (r *userRoleRepository) FindPageByParams(db *gorm.DB, params *params.QueryParams) (list []models.UserRole, paging *sqls.Paging) { - return r.FindPageByCnd(db, ¶ms.Cnd) -} - -func (r *userRoleRepository) FindPageByCnd(db *gorm.DB, cnd *sqls.Cnd) (list []models.UserRole, paging *sqls.Paging) { - cnd.Find(db, &list) - count := cnd.Count(db, &models.UserRole{}) - - paging = &sqls.Paging{ - Page: cnd.Paging.Page, - Limit: cnd.Paging.Limit, - Total: count, - } - return -} - -func (r *userRoleRepository) FindBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (list []models.UserRole) { - db.Raw(sqlStr, paramArr...).Scan(&list) - return -} - -func (r *userRoleRepository) CountBySql(db *gorm.DB, sqlStr string, paramArr ...interface{}) (count int64) { - db.Raw(sqlStr, paramArr...).Count(&count) - return -} - -func (r *userRoleRepository) Count(db *gorm.DB, cnd *sqls.Cnd) int64 { - return cnd.Count(db, &models.UserRole{}) -} - -func (r *userRoleRepository) Create(db *gorm.DB, t *models.UserRole) (err error) { - err = db.Create(t).Error - return -} - -func (r *userRoleRepository) Update(db *gorm.DB, t *models.UserRole) (err error) { - err = db.Save(t).Error - return -} - -func (r *userRoleRepository) Updates(db *gorm.DB, id int64, columns map[string]interface{}) (err error) { - err = db.Model(&models.UserRole{}).Where("id = ?", id).Updates(columns).Error - return -} - -func (r *userRoleRepository) UpdateColumn(db *gorm.DB, id int64, name string, value interface{}) (err error) { - err = db.Model(&models.UserRole{}).Where("id = ?", id).UpdateColumn(name, value).Error - return -} - -func (r *userRoleRepository) Delete(db *gorm.DB, id int64) { - db.Delete(&models.UserRole{}, "id = ?", id) -} diff --git a/internal/repositories/wx_work_kf_conversation_repository.go b/internal/repositories/wx_work_kf_conversation_repository.go index 5d8a6f2..1479b01 100644 --- a/internal/repositories/wx_work_kf_conversation_repository.go +++ b/internal/repositories/wx_work_kf_conversation_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/wx_work_kf_message_ref_repository.go b/internal/repositories/wx_work_kf_message_ref_repository.go index 1fd5218..d08b103 100644 --- a/internal/repositories/wx_work_kf_message_ref_repository.go +++ b/internal/repositories/wx_work_kf_message_ref_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/repositories/wx_work_kf_sync_state_repository.go b/internal/repositories/wx_work_kf_sync_state_repository.go index 2ee8e07..4e20358 100644 --- a/internal/repositories/wx_work_kf_sync_state_repository.go +++ b/internal/repositories/wx_work_kf_sync_state_repository.go @@ -1,9 +1,9 @@ package repositories import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/agent_evaluation_service.go b/internal/services/agent_evaluation_service.go index d9adcf0..f5c5d2d 100644 --- a/internal/services/agent_evaluation_service.go +++ b/internal/services/agent_evaluation_service.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) var AgentEvaluationService = newAgentEvaluationService() diff --git a/internal/services/agent_evaluation_service_test.go b/internal/services/agent_evaluation_service_test.go index 548e30a..5fd8085 100644 --- a/internal/services/agent_evaluation_service_test.go +++ b/internal/services/agent_evaluation_service_test.go @@ -4,8 +4,8 @@ import ( "context" "testing" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" ) func TestAgentEvaluationServiceValidatesAndCallsRunner(t *testing.T) { diff --git a/internal/services/agent_profile_service.go b/internal/services/agent_profile_service.go index fedca57..e1893cd 100644 --- a/internal/services/agent_profile_service.go +++ b/internal/services/agent_profile_service.go @@ -1,17 +1,17 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/agent_revision_service.go b/internal/services/agent_revision_service.go index 91e5e99..fa8d9d3 100644 --- a/internal/services/agent_revision_service.go +++ b/internal/services/agent_revision_service.go @@ -7,12 +7,12 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/agent_revision_service_test.go b/internal/services/agent_revision_service_test.go index 0fe53b3..7b10254 100644 --- a/internal/services/agent_revision_service_test.go +++ b/internal/services/agent_revision_service_test.go @@ -5,8 +5,8 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/agent_run_service.go b/internal/services/agent_run_service.go index e7c6c1f..1fc27f8 100644 --- a/internal/services/agent_run_service.go +++ b/internal/services/agent_run_service.go @@ -7,14 +7,14 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/agent_run_service_test.go b/internal/services/agent_run_service_test.go index 43b7647..1aa8960 100644 --- a/internal/services/agent_run_service_test.go +++ b/internal/services/agent_run_service_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/agent_team_schedule_service.go b/internal/services/agent_team_schedule_service.go index 62d59af..4cfa7db 100644 --- a/internal/services/agent_team_schedule_service.go +++ b/internal/services/agent_team_schedule_service.go @@ -1,20 +1,20 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "slices" "strings" "sync" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/agent_team_schedule_service_test.go b/internal/services/agent_team_schedule_service_test.go index 5468561..5b72ec2 100644 --- a/internal/services/agent_team_schedule_service_test.go +++ b/internal/services/agent_team_schedule_service_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/agent_team_service.go b/internal/services/agent_team_service.go index 643214e..de6d8b8 100644 --- a/internal/services/agent_team_service.go +++ b/internal/services/agent_team_service.go @@ -1,17 +1,17 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/agent_tool_invocation_service.go b/internal/services/agent_tool_invocation_service.go index 35a632b..8e68e6c 100644 --- a/internal/services/agent_tool_invocation_service.go +++ b/internal/services/agent_tool_invocation_service.go @@ -4,8 +4,8 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/agent_tool_invocation_service_test.go b/internal/services/agent_tool_invocation_service_test.go index 5e0b1a2..ada219d 100644 --- a/internal/services/agent_tool_invocation_service_test.go +++ b/internal/services/agent_tool_invocation_service_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/ai_agent_mcp_policy_test.go b/internal/services/ai_agent_mcp_policy_test.go index aa45aa4..50625a7 100644 --- a/internal/services/ai_agent_mcp_policy_test.go +++ b/internal/services/ai_agent_mcp_policy_test.go @@ -3,7 +3,7 @@ package services import ( "testing" - "agent-desk/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" ) func TestValidateMCPToolRiskPolicyRejectsTrustedToolOverride(t *testing.T) { diff --git a/internal/services/ai_agent_service.go b/internal/services/ai_agent_service.go index a267755..6b11e5f 100644 --- a/internal/services/ai_agent_service.go +++ b/internal/services/ai_agent_service.go @@ -6,17 +6,17 @@ import ( "strings" "time" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/ai_agent_service_test.go b/internal/services/ai_agent_service_test.go index f34e6d4..03d3620 100644 --- a/internal/services/ai_agent_service_test.go +++ b/internal/services/ai_agent_service_test.go @@ -4,10 +4,10 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/ai_agent_workflow_binding_service.go b/internal/services/ai_agent_workflow_binding_service.go index 50a5024..b77c777 100644 --- a/internal/services/ai_agent_workflow_binding_service.go +++ b/internal/services/ai_agent_workflow_binding_service.go @@ -3,13 +3,13 @@ package services import ( "strings" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/ai_config_service.go b/internal/services/ai_config_service.go index 224ccf0..760f671 100644 --- a/internal/services/ai_config_service.go +++ b/internal/services/ai_config_service.go @@ -4,15 +4,15 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/ai_config_service_test.go b/internal/services/ai_config_service_test.go index 120430a..8fbfa14 100644 --- a/internal/services/ai_config_service_test.go +++ b/internal/services/ai_config_service_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/ai_reply_hook.go b/internal/services/ai_reply_hook.go index 125f5af..dbc12be 100644 --- a/internal/services/ai_reply_hook.go +++ b/internal/services/ai_reply_hook.go @@ -1,5 +1,5 @@ package services -import "agent-desk/internal/models" +import "code.tczkiot.com/wlw/ai-agent/internal/models" var TriggerAIReplyAsyncHook func(conversation models.Conversation, message models.Message) diff --git a/internal/services/ai_workflow_service.go b/internal/services/ai_workflow_service.go index ed20ff6..6c03a6b 100644 --- a/internal/services/ai_workflow_service.go +++ b/internal/services/ai_workflow_service.go @@ -7,17 +7,17 @@ import ( "strings" "time" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - workflowvalidator "agent-desk/internal/ai/workflow/validator" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx/params" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + workflowvalidator "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/validator" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/ai_workflow_service_test.go b/internal/services/ai_workflow_service_test.go index 3e8b648..55d3abc 100644 --- a/internal/services/ai_workflow_service_test.go +++ b/internal/services/ai_workflow_service_test.go @@ -6,12 +6,12 @@ import ( "testing" "time" - "agent-desk/internal/ai/workflow/dsl" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/asset_service.go b/internal/services/asset_service.go index b7596be..7ff911f 100644 --- a/internal/services/asset_service.go +++ b/internal/services/asset_service.go @@ -1,14 +1,14 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "agent-desk/internal/services/storage" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/services/storage" "bytes" "io" "mime/multipart" diff --git a/internal/services/auth_service.go b/internal/services/auth_service.go index de95725..c161870 100644 --- a/internal/services/auth_service.go +++ b/internal/services/auth_service.go @@ -1,436 +1,72 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" - "crypto/rand" - "encoding/hex" - "slices" - "sort" - "strings" - "time" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "github.com/gin-gonic/gin" - "github.com/mlogclub/simple/common/strs" - "github.com/mlogclub/simple/sqls" - "golang.org/x/crypto/bcrypt" - "gorm.io/gorm" ) -const ( - authPrincipalContextKey = "authPrincipal" -) +const authPrincipalContextKey = "externalAuthPrincipal" -var AuthService = newAuthService() +// AuthService adapts identity data authenticated by the host application and +// delegates every operation authorization back to that host. +var AuthService = &externalPrincipalService{} -func newAuthService() *authService { - return &authService{} -} +type externalPrincipalService struct{} -type authService struct { -} - -func (s *authService) GetAuthPrincipal(ctx *gin.Context) *dto.AuthPrincipal { +func (s *externalPrincipalService) GetAuthPrincipal(ctx *gin.Context) *dto.AuthPrincipal { if ctx == nil { return nil } - v, _ := ctx.Get(authPrincipalContextKey) - if principal, ok := v.(*dto.AuthPrincipal); ok { - return principal - } - return nil -} - -func (s *authService) setAuthPrincipal(ctx *gin.Context, user *models.User, roles, permissions []string) *dto.AuthPrincipal { - principal := &dto.AuthPrincipal{ - UserID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - Avatar: user.Avatar, - Status: user.Status, - Roles: roles, - Permissions: permissions, - } - ctx.Set(authPrincipalContextKey, principal) + value, _ := ctx.Get(authPrincipalContextKey) + principal, _ := value.(*dto.AuthPrincipal) return principal } -func (s *authService) RequirePermission(ctx *gin.Context, permission constants.Permission) (principal *dto.AuthPrincipal, err error) { - if principal = s.GetAuthPrincipal(ctx); principal == nil { - if principal, err = s.Authenticate(ctx); err != nil { - return nil, err - } - } - - if principal == nil { - return nil, errorsx.ForbiddenI18n("error.e0225") - } - - if !s.HasPermission(ctx, permission.Code) { - return principal, errorsx.ForbiddenI18n("error.e0225") - } - return principal, nil -} - -func (s *authService) Login(req request.LoginRequest, authCfg config.AuthConfig, clientIP, userAgent string) (*response.LoginResponse, error) { - username := strings.TrimSpace(req.Username) - principal := normalizeLoginPrincipal(username) - password := req.Password - if username == "" || strings.TrimSpace(password) == "" { - return nil, errorsx.InvalidParamI18n("error.e0258") - } - - if s.isCredentialLocked(principal, authCfg) { - _ = s.createLoginCredentialLog(principal, 0, false, clientIP, userAgent, "credential locked") - return nil, errorsx.CredentialLockedI18n("error.e0270") - } - - user := UserService.GetByUsername(username) - if user == nil || user.Status != enums.StatusOk { - _ = s.createLoginCredentialLog(principal, 0, false, clientIP, userAgent, "user not found") - return nil, errorsx.InvalidAccountI18n("error.e0260") - } - if strs.IsBlank(user.Password) || bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) != nil { - _ = s.createLoginCredentialLog(principal, user.ID, false, clientIP, userAgent, "password mismatch") - return nil, errorsx.InvalidAccountI18n("error.e0260") - } - - var ret *response.LoginResponse - if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - var dbErr error - ret, dbErr = s.issueTokens(ctx, user, clientIP, userAgent, authCfg) - if dbErr != nil { - return dbErr - } - if dbErr = repositories.UserRepository.Updates(ctx.Tx, user.ID, map[string]any{ - "last_login_at": time.Now(), - "last_login_ip": clientIP, - "update_user_id": user.ID, - "update_user_name": user.Username, - "updated_at": time.Now(), - }); dbErr != nil { - return dbErr - } - return nil - }); err != nil { - return nil, err - } - - _ = s.createLoginCredentialLog(principal, user.ID, true, clientIP, userAgent, "") - return ret, nil -} - -func (s *authService) Logout(accessToken string) error { - accessToken = s.extractBearerToken(accessToken) - now := time.Now() - if accessToken != "" { - if session := LoginSessionService.FindOne(sqls.NewCnd().Eq("token", accessToken)); session != nil && session.RevokedAt == nil { - if err := LoginSessionService.Updates(session.ID, map[string]any{ - "revoked_at": now, - "updated_at": now, - }); err != nil { - return err - } - } - } - return nil -} - -func (s *authService) Authenticate(ctx *gin.Context) (*dto.AuthPrincipal, error) { +func (s *externalPrincipalService) Authenticate(ctx *gin.Context) (*dto.AuthPrincipal, error) { if principal := s.GetAuthPrincipal(ctx); principal != nil { return principal, nil } - - token := s.extractBearerToken(ctx.GetHeader("Authorization")) - if token == "" { - token = strings.TrimSpace(ctx.Query("accessToken")) - } - if token == "" { + if ctx == nil || ctx.Request == nil { return nil, errorsx.UnauthorizedI18n("error.auth.expired") } - session, err := s.validateSessionToken(token) - if err != nil { - return nil, err + subject, err := SubjectService.Current(ctx.Request.Context()) + if err != nil || subject == nil || subject.Category != identity.CategorySystem || !subject.Enabled { + return nil, errorsx.UnauthorizedI18n("error.auth.expired") } - user := UserService.Get(session.UserID) - if user == nil || user.Status != enums.StatusOk { - return nil, errorsx.UnauthorizedI18n("error.e0256") + principal := &dto.AuthPrincipal{ + SubjectType: subject.Type, + UserID: subject.ID, + Username: subject.Username, + Nickname: subject.Name, + Avatar: subject.Avatar, + Status: enums.StatusOk, + Roles: []string{string(subject.Type)}, } - - roles, permissions, err := s.loadUserAuthScope(sqls.DB(), user.ID) - if err != nil { - return nil, err - } - principal := s.setAuthPrincipal(ctx, user, roles, permissions) - - now := time.Now() - _ = LoginSessionService.Updates(session.ID, map[string]any{ - "last_seen_at": now, - "updated_at": now, - }) - + ctx.Set(authPrincipalContextKey, principal) return principal, nil } -func (s *authService) HasPermission(ctx *gin.Context, permissionCode string) bool { - principal := s.GetAuthPrincipal(ctx) - if principal == nil { - return false - } - return slices.Contains(principal.Permissions, permissionCode) -} - -func (s *authService) CurrentProfile(ctx *gin.Context) (*response.LoginResponse, error) { +func (s *externalPrincipalService) RequirePermission(ctx *gin.Context, permission constants.Permission) (*dto.AuthPrincipal, error) { principal, err := s.Authenticate(ctx) if err != nil { return nil, err } - - return &response.LoginResponse{ - User: &response.AuthUserResponse{ - ID: principal.UserID, - Username: principal.Username, - Nickname: principal.Nickname, - Avatar: principal.Avatar, - Status: principal.Status, - Roles: principal.Roles, - }, - Permissions: principal.Permissions, - Roles: principal.Roles, - }, nil + if err := SubjectService.Authorize(ctx.Request.Context(), permission.Code); err != nil { + return nil, errorsx.ForbiddenI18n("error.auth.forbidden") + } + return principal, nil } -func (s *authService) GetUserRoles(userID int64) ([]models.Role, error) { - return s.loadUserRoles(sqls.DB(), userID) -} - -func (s *authService) GetUserPermissions(userID int64) ([]string, error) { - return s.loadUserPermissionCodes(sqls.DB(), userID) -} - -func (s *authService) issueTokens(ctx *sqls.TxContext, user *models.User, clientIP, userAgent string, authCfg config.AuthConfig) (*response.LoginResponse, error) { - roles, permissions, err := s.loadUserAuthScope(ctx.Tx, user.ID) - if err != nil { - return nil, err - } - - tokenTTL := s.resolveTokenTTL(authCfg) - accessToken, err := randomToken(constants.AuthTokenPrefix) - if err != nil { - return nil, err - } - - now := time.Now() - if err := repositories.LoginSessionRepository.Create(ctx.Tx, &models.LoginSession{ - UserID: user.ID, - Token: accessToken, - ClientType: constants.ClientTypeAdminWeb, - ClientIP: clientIP, - UserAgent: userAgent, - ExpiredAt: now.Add(tokenTTL), - LastSeenAt: &now, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: user.ID, - CreateUserName: user.Username, - UpdatedAt: now, - UpdateUserID: user.ID, - UpdateUserName: user.Username, - }, - }); err != nil { - return nil, err - } - - return &response.LoginResponse{ - AccessToken: accessToken, - ExpiresAt: now.Add(tokenTTL).Format(time.DateTime), - User: &response.AuthUserResponse{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - Avatar: user.Avatar, - Status: user.Status, - Roles: roles, - }, - Permissions: permissions, - Roles: roles, - }, nil -} - -func (s *authService) resolveTokenTTL(authCfg config.AuthConfig) time.Duration { - tokenTTL := 12 * time.Hour - if authCfg.TokenTTLHours > 0 { - tokenTTL = time.Duration(authCfg.TokenTTLHours) * time.Hour - } - return tokenTTL -} - -func (s *authService) validateSessionToken(token string) (*models.LoginSession, error) { - if strings.TrimSpace(token) == "" { - return nil, errorsx.UnauthorizedI18n("error.auth.expired") - } - session := LoginSessionService.FindOne(sqls.NewCnd().Eq("token", token)) - if session == nil { - return nil, errorsx.InvalidTokenI18n("error.e0269") - } - if session.RevokedAt != nil { - return nil, errorsx.InvalidTokenI18n("error.e0267") - } - if time.Now().After(session.ExpiredAt) { - return nil, errorsx.InvalidTokenI18n("error.e0268") - } - return session, nil -} - -func (s *authService) loadUserAuthScope(tx *gorm.DB, userID int64) ([]string, []string, error) { - roleCodes, err := s.loadUserRoleCodes(tx, userID) - if err != nil { - return nil, nil, err - } - permissionCodes, err := s.loadUserPermissionCodes(tx, userID) - if err != nil { - return nil, nil, err - } - return roleCodes, permissionCodes, nil -} - -func (s *authService) loadUserRoleCodes(tx *gorm.DB, userID int64) ([]string, error) { - roles, err := s.loadUserRoles(tx, userID) - if err != nil { - return nil, err - } - roleCodes := make([]string, 0, len(roles)) - for _, role := range roles { - roleCodes = append(roleCodes, role.Code) - } - return roleCodes, nil -} - -func (s *authService) loadUserRoles(tx *gorm.DB, userID int64) ([]models.Role, error) { - roles := make([]models.Role, 0) - if err := tx. - Table("t_role AS r"). - Select("r.*"). - Joins("JOIN t_user_role AS ur ON ur.role_id = r.id"). - Where("ur.user_id = ? AND r.status = ?", userID, enums.StatusOk). - Order("r.sort_no ASC, r.id ASC"). - Scan(&roles).Error; err != nil { - return nil, err - } - - return roles, nil -} - -func (s *authService) loadUserPermissionCodes(tx *gorm.DB, userID int64) ([]string, error) { - permissionRows := make([]struct { - Code string - }, 0) - db := tx.Table("t_permission AS p"). - Select("DISTINCT p.code"). - Joins("JOIN t_role_permission AS rp ON rp.permission_id = p.id"). - Joins("JOIN t_user_role AS ur ON ur.role_id = rp.role_id"). - Where("ur.user_id = ?", userID). - Where("p.status = ?", enums.StatusOk) - if err := db.Scan(&permissionRows).Error; err != nil { - return nil, err - } - - permissionCodes := make([]string, 0, len(permissionRows)) - for _, permission := range permissionRows { - permissionCodes = append(permissionCodes, permission.Code) - } - - overrideRows := make([]struct { - Code string - Effect int - }, 0) - if err := tx. - Table("t_user_permission AS up"). - Select("p.code, up.effect"). - Joins("JOIN t_permission AS p ON p.id = up.permission_id"). - Where("up.user_id = ? AND (up.expired_at IS NULL OR up.expired_at > ?)", userID, time.Now()). - Scan(&overrideRows).Error; err != nil { - return nil, err - } - - permissionSet := make(map[string]bool, len(permissionCodes)) - for _, code := range permissionCodes { - permissionSet[code] = true - } - for _, override := range overrideRows { - if override.Effect < 0 { - delete(permissionSet, override.Code) - continue - } - permissionSet[override.Code] = true - } - - permissionCodes = permissionCodes[:0] - for code := range permissionSet { - permissionCodes = append(permissionCodes, code) - } - sort.Strings(permissionCodes) - return permissionCodes, nil -} - -func (s *authService) extractBearerToken(header string) string { - header = strings.TrimSpace(header) - if header == "" { - return "" - } - parts := strings.SplitN(header, " ", 2) - if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") { - return "" - } - return strings.TrimSpace(parts[1]) -} - -func (s *authService) createLoginCredentialLog(principal string, userID int64, success bool, clientIP, userAgent, reason string) error { - return LoginCredentialLogService.Create(&models.LoginCredentialLog{ - Principal: principal, - UserID: userID, - Success: success, - ClientIP: clientIP, - UserAgent: userAgent, - Reason: reason, - CreatedAt: time.Now(), - }) -} - -func (s *authService) isCredentialLocked(principal string, authCfg config.AuthConfig) bool { - maxFailedAttempts := authCfg.MaxFailedAttempts - if maxFailedAttempts <= 0 { +func (s *externalPrincipalService) HasPermission(ctx *gin.Context, operation string) bool { + if _, err := s.Authenticate(ctx); err != nil { return false } - lockMinute := authCfg.CredentialLockMinute - if lockMinute <= 0 { - lockMinute = 15 - } - since := time.Now().Add(-time.Duration(lockMinute) * time.Minute) - return LoginCredentialLogService.Count(sqls.NewCnd(). - Eq("principal", normalizeLoginPrincipal(principal)). - Eq("success", false). - NotEq("reason", "credential locked"). - Where("created_at >= ?", since)) >= int64(maxFailedAttempts) -} - -func normalizeLoginPrincipal(principal string) string { - return strings.ToLower(strings.TrimSpace(principal)) -} - -func randomToken(prefix string) (string, error) { - buf := make([]byte, 24) - if _, err := rand.Read(buf); err != nil { - return "", err - } - return prefix + hex.EncodeToString(buf), nil + return SubjectService.Authorize(ctx.Request.Context(), operation) == nil } diff --git a/internal/services/auth_service_test.go b/internal/services/auth_service_test.go index 5b7d5e7..bad9968 100644 --- a/internal/services/auth_service_test.go +++ b/internal/services/auth_service_test.go @@ -1,488 +1,68 @@ package services import ( + "context" "errors" - "strings" + "net/http/httptest" "testing" - "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/constants" - "github.com/glebarez/sqlite" - "github.com/mlogclub/simple/sqls" - "github.com/mlogclub/simple/web" - "golang.org/x/crypto/bcrypt" - "gorm.io/gorm" - "gorm.io/gorm/schema" + "github.com/gin-gonic/gin" ) -func TestExtractBearerToken(t *testing.T) { - svc := newAuthService() - - if got := svc.extractBearerToken("Bearer token_123"); got != "token_123" { - t.Fatalf("expected bearer token to be extracted, got %q", got) - } - - if got := svc.extractBearerToken("token_123"); got != "" { - t.Fatalf("expected raw token to be rejected by bearer extractor, got %q", got) - } -} - -func TestAuthServiceLoginCreatesSingleAccessSession(t *testing.T) { - db := setupAuthServiceTestDB(t) - user := createAuthTestUser(t, db, "admin", "secret") - svc := newAuthService() - - ret, err := svc.Login(request.LoginRequest{ - Username: " admin ", - Password: "secret", - }, config.AuthConfig{TokenTTLHours: 2, MaxFailedAttempts: 5, CredentialLockMinute: 15}, "127.0.0.1", "go-test") - if err != nil { - t.Fatalf("login failed: %v", err) - } - - if ret.AccessToken == "" || !strings.HasPrefix(ret.AccessToken, "ak_") { - t.Fatalf("expected ak_ access token, got %q", ret.AccessToken) - } - if ret.ExpiresAt == "" { - t.Fatal("expected expiresAt to be returned") - } - - var sessions []models.LoginSession - if err := db.Find(&sessions).Error; err != nil { - t.Fatalf("query login sessions: %v", err) - } - if len(sessions) != 1 { - t.Fatalf("expected exactly one session, got %d", len(sessions)) - } - if sessions[0].Token != ret.AccessToken { - t.Fatalf("expected session token %q, got %q", ret.AccessToken, sessions[0].Token) - } - if sessions[0].UserID != user.ID { - t.Fatalf("expected session user %d, got %d", user.ID, sessions[0].UserID) - } - if sessions[0].ClientType != "admin_web" { - t.Fatalf("expected admin_web client type, got %q", sessions[0].ClientType) - } - - logs := findCredentialLogs(t, db) - if len(logs) != 1 { - t.Fatalf("expected one credential log, got %d", len(logs)) - } - if !logs[0].Success || logs[0].Principal != "admin" || logs[0].UserID != user.ID { - t.Fatalf("unexpected success credential log: %+v", logs[0]) - } -} - -func TestAuthServiceLoginFailureWritesCredentialLogs(t *testing.T) { - db := setupAuthServiceTestDB(t) - createAuthTestUser(t, db, "admin", "secret") - svc := newAuthService() - authCfg := config.AuthConfig{TokenTTLHours: 2, MaxFailedAttempts: 5, CredentialLockMinute: 15} - - if _, err := svc.Login(request.LoginRequest{Username: "missing", Password: "secret"}, authCfg, "127.0.0.1", "go-test"); !hasCode(err, errorsx.CodeAuthInvalidAccount) { - t.Fatalf("expected invalid account for missing user, got %v", err) - } - if _, err := svc.Login(request.LoginRequest{Username: "admin", Password: "wrong"}, authCfg, "127.0.0.1", "go-test"); !hasCode(err, errorsx.CodeAuthInvalidAccount) { - t.Fatalf("expected invalid account for password mismatch, got %v", err) - } - - logs := findCredentialLogs(t, db) - if len(logs) != 2 { - t.Fatalf("expected two credential logs, got %d", len(logs)) - } - if logs[0].Reason != "user not found" || logs[0].Success { - t.Fatalf("unexpected missing-user log: %+v", logs[0]) - } - if logs[1].Reason != "password mismatch" || logs[1].Success { - t.Fatalf("unexpected password-mismatch log: %+v", logs[1]) - } -} - -func TestAuthServiceLoginCredentialLockout(t *testing.T) { - db := setupAuthServiceTestDB(t) - user := createAuthTestUser(t, db, "admin", "secret") - now := time.Now() - for i := 0; i < 2; i++ { - if err := db.Create(&models.LoginCredentialLog{ - Principal: "admin", - UserID: user.ID, - Success: false, - Reason: "password mismatch", - CreatedAt: now.Add(-time.Duration(i+1) * time.Minute), - }).Error; err != nil { - t.Fatalf("seed credential log: %v", err) +func TestExternalAuthDelegatesOperationToHost(t *testing.T) { + SetQuerySubjects(func(_ context.Context, query identity.Query) ([]identity.Subject, error) { + if !query.Current { + return nil, nil } - } - if err := db.Create(&models.LoginCredentialLog{ - Principal: "admin", - UserID: user.ID, - Success: false, - Reason: "password mismatch", - CreatedAt: now.Add(-30 * time.Minute), - }).Error; err != nil { - t.Fatalf("seed old credential log: %v", err) - } - - svc := newAuthService() - _, err := svc.Login(request.LoginRequest{Username: "admin", Password: "secret"}, config.AuthConfig{ - TokenTTLHours: 2, - MaxFailedAttempts: 2, - CredentialLockMinute: 15, - }, "127.0.0.1", "go-test") - if !hasCode(err, errorsx.CodeAuthCredentialLocked) { - t.Fatalf("expected credential locked error, got %v", err) - } - - var lockedLog models.LoginCredentialLog - if err := db.Order("id DESC").Take(&lockedLog).Error; err != nil { - t.Fatalf("query latest credential log: %v", err) - } - if lockedLog.Reason != "credential locked" || lockedLog.Success { - t.Fatalf("unexpected locked credential log: %+v", lockedLog) - } - - var sessionCount int64 - if err := db.Model(&models.LoginSession{}).Count(&sessionCount).Error; err != nil { - t.Fatalf("count sessions: %v", err) - } - if sessionCount != 0 { - t.Fatalf("expected no session while credential locked, got %d", sessionCount) - } -} - -func TestAuthServiceCredentialLockoutDoesNotExtendWhileLocked(t *testing.T) { - db := setupAuthServiceTestDB(t) - createAuthTestUser(t, db, "admin", "secret") - now := time.Now() - entries := []models.LoginCredentialLog{ - { - Principal: "admin", - UserID: 1, - Success: false, - Reason: "password mismatch", - CreatedAt: now.Add(-2 * time.Minute), - }, - { - Principal: "admin", - UserID: 0, - Success: false, - Reason: "credential locked", - CreatedAt: now.Add(-1 * time.Minute), - }, - } - if err := db.Create(&entries).Error; err != nil { - t.Fatalf("seed credential logs: %v", err) - } - - ret, err := newAuthService().Login(request.LoginRequest{Username: "admin", Password: "secret"}, config.AuthConfig{ - TokenTTLHours: 2, - MaxFailedAttempts: 2, - CredentialLockMinute: 15, - }, "127.0.0.1", "go-test") - if err != nil { - t.Fatalf("expected locked attempt logs not to extend lockout, got %v", err) - } - if ret == nil || !strings.HasPrefix(ret.AccessToken, "ak_") { - t.Fatalf("expected login response with ak_ token, got %+v", ret) - } -} - -func TestAuthServiceCredentialLockoutNormalizesPrincipalCase(t *testing.T) { - db := setupAuthServiceTestDB(t) - createAuthTestUser(t, db, "admin", "secret") - if err := db.Create(&models.LoginCredentialLog{ - Principal: "admin", - UserID: 1, - Success: false, - Reason: "password mismatch", - CreatedAt: time.Now().Add(-time.Minute), - }).Error; err != nil { - t.Fatalf("seed credential log: %v", err) - } - - _, err := newAuthService().Login(request.LoginRequest{Username: "ADMIN", Password: "secret"}, config.AuthConfig{ - TokenTTLHours: 2, - MaxFailedAttempts: 1, - CredentialLockMinute: 15, - }, "127.0.0.1", "go-test") - if !hasCode(err, errorsx.CodeAuthCredentialLocked) { - t.Fatalf("expected normalized principal to be locked, got %v", err) - } - - var lockedLog models.LoginCredentialLog - if err := db.Order("id DESC").Take(&lockedLog).Error; err != nil { - t.Fatalf("query latest credential log: %v", err) - } - if lockedLog.Principal != "admin" || lockedLog.Reason != "credential locked" { - t.Fatalf("unexpected locked log: %+v", lockedLog) - } -} - -func TestAuthServiceCredentialLockoutDisabledWhenMaxAttemptsNonPositive(t *testing.T) { - db := setupAuthServiceTestDB(t) - user := createAuthTestUser(t, db, "admin", "secret") - now := time.Now() - for i := 0; i < 3; i++ { - if err := db.Create(&models.LoginCredentialLog{ - Principal: "admin", - UserID: user.ID, - Success: false, - Reason: "credential locked", - CreatedAt: now.Add(-time.Duration(i+1) * time.Minute), - }).Error; err != nil { - t.Fatalf("seed credential log: %v", err) - } - } - - ret, err := newAuthService().Login(request.LoginRequest{Username: "admin", Password: "secret"}, config.AuthConfig{ - TokenTTLHours: 2, - MaxFailedAttempts: 0, - CredentialLockMinute: 15, - }, "127.0.0.1", "go-test") - if err != nil { - t.Fatalf("expected lockout to be disabled, got %v", err) - } - if ret == nil || ret.AccessToken == "" { - t.Fatalf("expected login response with access token, got %+v", ret) - } -} - -func TestValidateSessionTokenStates(t *testing.T) { - db := setupAuthServiceTestDB(t) - svc := newAuthService() - now := time.Now() - - if _, err := svc.validateSessionToken(" "); !hasCode(err, errorsx.CodeAuthUnauthorized) { - t.Fatalf("expected unauthorized for empty token, got %v", err) - } - if _, err := svc.validateSessionToken("missing"); !hasCode(err, errorsx.CodeAuthInvalidToken) { - t.Fatalf("expected invalid token for missing session, got %v", err) - } - - revokedAt := now - if err := db.Create(&models.LoginSession{ - UserID: 1, - Token: "ak_revoked", - ClientType: "admin_web", - ExpiredAt: now.Add(time.Hour), - RevokedAt: &revokedAt, - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - }).Error; err != nil { - t.Fatalf("seed revoked session: %v", err) - } - if _, err := svc.validateSessionToken("ak_revoked"); !hasCode(err, errorsx.CodeAuthInvalidToken) { - t.Fatalf("expected invalid token for revoked session, got %v", err) - } - - if err := db.Create(&models.LoginSession{ - UserID: 1, - Token: "ak_expired", - ClientType: "admin_web", - ExpiredAt: now.Add(-time.Hour), - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - }).Error; err != nil { - t.Fatalf("seed expired session: %v", err) - } - if _, err := svc.validateSessionToken("ak_expired"); !hasCode(err, errorsx.CodeAuthInvalidToken) { - t.Fatalf("expected invalid token for expired session, got %v", err) - } - - if err := db.Create(&models.LoginSession{ - UserID: 1, - Token: "ak_valid", - ClientType: "admin_web", - ExpiredAt: now.Add(time.Hour), - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - }).Error; err != nil { - t.Fatalf("seed valid session: %v", err) - } - session, err := svc.validateSessionToken("ak_valid") - if err != nil { - t.Fatalf("expected valid session token, got %v", err) - } - if session.Token != "ak_valid" { - t.Fatalf("expected valid session token ak_valid, got %q", session.Token) - } -} - -func TestAuthServiceLogoutRevokesCurrentTokenOnly(t *testing.T) { - db := setupAuthServiceTestDB(t) - now := time.Now() - sessions := []models.LoginSession{ - { - UserID: 1, - Token: "ak_current", - ClientType: "admin_web", - ExpiredAt: now.Add(time.Hour), - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - }, - { - UserID: 1, - Token: "ak_other", - ClientType: "admin_web", - ExpiredAt: now.Add(time.Hour), - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - }, - } - if err := db.Create(&sessions).Error; err != nil { - t.Fatalf("seed sessions: %v", err) - } - - if err := newAuthService().Logout("Bearer ak_current"); err != nil { - t.Fatalf("logout failed: %v", err) - } - - var current models.LoginSession - if err := db.Take(¤t, "token = ?", "ak_current").Error; err != nil { - t.Fatalf("query current session: %v", err) - } - if current.RevokedAt == nil { - t.Fatal("expected current session to be revoked") - } - var other models.LoginSession - if err := db.Take(&other, "token = ?", "ak_other").Error; err != nil { - t.Fatalf("query other session: %v", err) - } - if other.RevokedAt != nil { - t.Fatal("expected other session to remain active") - } -} - -func TestLoadUserPermissionCodesReturnsSortedDistinctCodes(t *testing.T) { - db := setupAuthServiceTestDB(t) - user := createAuthTestUser(t, db, "admin", "secret") - now := time.Now() - auditFields := models.AuditFields{CreatedAt: now, UpdatedAt: now} - - permissions := []models.Permission{ - {Name: "Zulu", Code: "z.read", SortNo: 1, Status: enums.StatusOk, AuditFields: auditFields}, - {Name: "Alpha", Code: "a.read", SortNo: 2, Status: enums.StatusOk, AuditFields: auditFields}, - } - if err := db.Create(&permissions).Error; err != nil { - t.Fatalf("seed permissions: %v", err) - } - - roles := []models.Role{ - {Name: "Role One", Code: "role_one", Status: enums.StatusOk, AuditFields: auditFields}, - {Name: "Role Two", Code: "role_two", Status: enums.StatusOk, AuditFields: auditFields}, - } - if err := db.Create(&roles).Error; err != nil { - t.Fatalf("seed roles: %v", err) - } - - userRoles := []models.UserRole{ - {UserID: user.ID, RoleID: roles[0].ID, AuditFields: auditFields}, - {UserID: user.ID, RoleID: roles[1].ID, AuditFields: auditFields}, - } - if err := db.Create(&userRoles).Error; err != nil { - t.Fatalf("seed user roles: %v", err) - } - - rolePermissions := []models.RolePermission{ - {RoleID: roles[0].ID, PermissionID: permissions[0].ID, AuditFields: auditFields}, - {RoleID: roles[0].ID, PermissionID: permissions[1].ID, AuditFields: auditFields}, - {RoleID: roles[1].ID, PermissionID: permissions[0].ID, AuditFields: auditFields}, - } - if err := db.Create(&rolePermissions).Error; err != nil { - t.Fatalf("seed role permissions: %v", err) - } - - codes, err := newAuthService().loadUserPermissionCodes(db, user.ID) - if err != nil { - t.Fatalf("load user permission codes: %v", err) - } - if got, want := strings.Join(codes, ","), "a.read,z.read"; got != want { - t.Fatalf("permission codes = %q, want %q", got, want) - } -} - -func setupAuthServiceTestDB(t *testing.T) *gorm.DB { - t.Helper() - db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{ - NamingStrategy: schema.NamingStrategy{ - TablePrefix: "t_", - SingularTable: true, - }, + return []identity.Subject{{ + Type: identity.SubjectAdmin, + Category: identity.CategorySystem, + ID: 9, + Username: "admin", + Name: "Admin", + Enabled: true, + }}, nil }) + + var gotOperation string + SetAuthorize(func(_ context.Context, operation string) error { + gotOperation = operation + return nil + }) + + ctx, _ := gin.CreateTestContext(httptest.NewRecorder()) + ctx.Request = httptest.NewRequest("GET", "/api/dashboard/conversation/list", nil) + principal, err := AuthService.RequirePermission(ctx, constants.PermissionConversationView) if err != nil { - t.Fatalf("open sqlite db: %v", err) + t.Fatalf("RequirePermission() error = %v", err) } - if err := db.AutoMigrate( - &models.User{}, - &models.UserIdentity{}, - &models.Role{}, - &models.Permission{}, - &models.UserRole{}, - &models.RolePermission{}, - &models.UserPermission{}, - &models.LoginSession{}, - &models.LoginCredentialLog{}, - ); err != nil { - t.Fatalf("migrate auth tables: %v", err) + if principal.UserID != 9 || principal.SubjectType != identity.SubjectAdmin { + t.Fatalf("principal = %#v", principal) + } + if gotOperation != constants.PermissionConversationView.Code { + t.Fatalf("operation = %q, want %q", gotOperation, constants.PermissionConversationView.Code) } - sqls.SetDB(db) - return db } -func createAuthTestUser(t *testing.T, db *gorm.DB, username, password string) *models.User { - t.Helper() - passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) - if err != nil { - t.Fatalf("hash password: %v", err) - } - now := time.Now() - user := &models.User{ - Username: username, - Nickname: username, - Password: string(passwordHash), - Status: enums.StatusOk, - AuditFields: models.AuditFields{ - CreatedAt: now, - UpdatedAt: now, - }, - } - if err := db.Create(user).Error; err != nil { - t.Fatalf("create auth test user: %v", err) - } - return user -} +func TestExternalAuthRejectsHostDeniedOperation(t *testing.T) { + SetQuerySubjects(func(_ context.Context, query identity.Query) ([]identity.Subject, error) { + if !query.Current { + return nil, nil + } + return []identity.Subject{{ + Type: identity.SubjectAgent, Category: identity.CategorySystem, ID: 10, Enabled: true, + }}, nil + }) + SetAuthorize(func(_ context.Context, _ string) error { + return errors.New("denied by host") + }) -func findCredentialLogs(t *testing.T, db *gorm.DB) []models.LoginCredentialLog { - t.Helper() - var logs []models.LoginCredentialLog - if err := db.Order("id ASC").Find(&logs).Error; err != nil { - t.Fatalf("query credential logs: %v", err) + ctx, _ := gin.CreateTestContext(httptest.NewRecorder()) + ctx.Request = httptest.NewRequest("POST", "/api/dashboard/ai-config/delete", nil) + if _, err := AuthService.RequirePermission(ctx, constants.PermissionAIConfigDelete); err == nil { + t.Fatal("RequirePermission() error = nil, want forbidden") } - return logs -} - -func hasCode(err error, code int) bool { - if err == nil { - return false - } - var codeErr *web.CodeError - if errors.As(err, &codeErr) { - return codeErr.Code == code - } - return false } diff --git a/internal/services/business_tool_executor.go b/internal/services/business_tool_executor.go index 64e2897..b9d59c2 100644 --- a/internal/services/business_tool_executor.go +++ b/internal/services/business_tool_executor.go @@ -6,11 +6,11 @@ import ( "fmt" "strings" - aitooling "agent-desk/internal/ai/tooling" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/toolx" + aitooling "code.tczkiot.com/wlw/ai-agent/internal/ai/tooling" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) // BusinessToolExecutor is the write boundary for built-in business tools. diff --git a/internal/services/channel_message_outbox_service.go b/internal/services/channel_message_outbox_service.go index 49c7fc3..50dcb70 100644 --- a/internal/services/channel_message_outbox_service.go +++ b/internal/services/channel_message_outbox_service.go @@ -1,16 +1,16 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "encoding/json" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/channel_service.go b/internal/services/channel_service.go index 1d4676b..3e1cb34 100644 --- a/internal/services/channel_service.go +++ b/internal/services/channel_service.go @@ -1,23 +1,21 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/httpx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "agent-desk/internal/wxwork" - "crypto/rand" - "encoding/base64" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "encoding/json" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/gin-gonic/gin" "github.com/mlogclub/simple/common/strs" @@ -271,7 +269,6 @@ func (s *channelService) ParseWebChannelConfig(raw string) (*dto.WebChannelConfi if cfg.Width == "" { cfg.Width = "380px" } - cfg.UserTokenSecret = strings.TrimSpace(cfg.UserTokenSecret) return cfg, nil } @@ -296,91 +293,9 @@ func (s *channelService) ParseWechatMPChannelConfig(raw string) (*dto.WechatMPCh if cfg.ThemeColor == "" { cfg.ThemeColor = "#2563eb" } - cfg.UserTokenSecret = strings.TrimSpace(cfg.UserTokenSecret) return cfg, nil } -func (s *channelService) GetUserTokenSecret(channel *models.Channel) string { - if channel == nil { - return "" - } - switch channel.ChannelType { - case enums.ChannelTypeWeb: - cfg, err := s.ParseWebChannelConfig(channel.ConfigJSON) - if err != nil { - return "" - } - return strings.TrimSpace(cfg.UserTokenSecret) - case enums.ChannelTypeWechatMP: - cfg, err := s.ParseWechatMPChannelConfig(channel.ConfigJSON) - if err != nil { - return "" - } - return strings.TrimSpace(cfg.UserTokenSecret) - default: - return "" - } -} - -func (s *channelService) ResetUserTokenSecret(channelID int64, operator *dto.AuthPrincipal) (string, error) { - if operator == nil { - return "", errorsx.UnauthorizedI18n("error.auth.expired") - } - channel := s.Get(channelID) - if channel == nil || channel.Status == enums.StatusDeleted { - return "", errorsx.InvalidParamI18n("error.e0208") - } - if channel.ChannelType != enums.ChannelTypeWeb && channel.ChannelType != enums.ChannelTypeWechatMP { - return "", errorsx.InvalidParamI18n("error.e0196") - } - secret, err := generateUserTokenSecret() - if err != nil { - return "", err - } - var configJSON string - switch channel.ChannelType { - case enums.ChannelTypeWeb: - cfg, err := s.ParseWebChannelConfig(channel.ConfigJSON) - if err != nil { - return "", err - } - cfg.UserTokenSecret = secret - raw, err := json.Marshal(cfg) - if err != nil { - return "", err - } - configJSON = string(raw) - case enums.ChannelTypeWechatMP: - cfg, err := s.ParseWechatMPChannelConfig(channel.ConfigJSON) - if err != nil { - return "", err - } - cfg.UserTokenSecret = secret - raw, err := json.Marshal(cfg) - if err != nil { - return "", err - } - configJSON = string(raw) - } - if err := repositories.ChannelRepository.Updates(sqls.DB(), channelID, map[string]any{ - "config_json": configJSON, - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": time.Now(), - }); err != nil { - return "", err - } - return secret, nil -} - -func generateUserTokenSecret() (string, error) { - buf := make([]byte, 32) - if _, err := rand.Read(buf); err != nil { - return "", err - } - return base64.RawURLEncoding.EncodeToString(buf), nil -} - func (s *channelService) GetEnabledWxWorkKFChannelByOpenKfID(openKfID string) *models.Channel { openKfID = strings.TrimSpace(openKfID) if openKfID == "" { @@ -467,13 +382,6 @@ func (s *channelService) buildChannelModel(id int64, req request.CreateChannelRe if err != nil { return nil, errorsx.InvalidParamI18n("error.e0060") } - if strings.TrimSpace(cfg.UserTokenSecret) == "" { - secret, err := generateUserTokenSecret() - if err != nil { - return nil, err - } - cfg.UserTokenSecret = secret - } configBytes, err := json.Marshal(cfg) if err != nil { return nil, err @@ -490,13 +398,6 @@ func (s *channelService) buildChannelModel(id int64, req request.CreateChannelRe if err != nil { return nil, errorsx.InvalidParamI18n("error.e0201") } - if strings.TrimSpace(cfg.UserTokenSecret) == "" { - secret, err := generateUserTokenSecret() - if err != nil { - return nil, err - } - cfg.UserTokenSecret = secret - } configBytes, err := json.Marshal(cfg) if err != nil { return nil, err diff --git a/internal/services/channel_service_test.go b/internal/services/channel_service_test.go index 2c24266..71ddcd2 100644 --- a/internal/services/channel_service_test.go +++ b/internal/services/channel_service_test.go @@ -4,10 +4,10 @@ import ( "strings" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/company_service.go b/internal/services/company_service.go index 6783982..3265bcc 100644 --- a/internal/services/company_service.go +++ b/internal/services/company_service.go @@ -1,17 +1,17 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_assignment_service.go b/internal/services/conversation_assignment_service.go index 84533ef..ff26f83 100644 --- a/internal/services/conversation_assignment_service.go +++ b/internal/services/conversation_assignment_service.go @@ -1,14 +1,14 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_dispatch_service.go b/internal/services/conversation_dispatch_service.go index 984c650..6984533 100644 --- a/internal/services/conversation_dispatch_service.go +++ b/internal/services/conversation_dispatch_service.go @@ -10,13 +10,13 @@ import ( "sync/atomic" "time" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) @@ -310,9 +310,7 @@ func (s *conversationDispatchService) filterEnabledDispatchProfiles(profiles []m return nil, nil, "no_profile_with_capacity_config" } - enabledUsers := UserService.Find(sqls.NewCnd(). - In("id", userIDs). - Eq("status", enums.StatusOk)) + enabledUsers := UserService.FindByIds(userIDs) if len(enabledUsers) == 0 { return nil, nil, "no_enabled_user" } diff --git a/internal/services/conversation_event_log_service.go b/internal/services/conversation_event_log_service.go index 84a6aa4..345e26e 100644 --- a/internal/services/conversation_event_log_service.go +++ b/internal/services/conversation_event_log_service.go @@ -1,14 +1,14 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/tracex" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_human_dispatch_realtime_test.go b/internal/services/conversation_human_dispatch_realtime_test.go index ad01258..bc54080 100644 --- a/internal/services/conversation_human_dispatch_realtime_test.go +++ b/internal/services/conversation_human_dispatch_realtime_test.go @@ -1,13 +1,15 @@ package services import ( + "context" "encoding/json" "strings" "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" @@ -141,7 +143,6 @@ func setupHumanDispatchRealtimeTestDB(t *testing.T) *gorm.DB { } }) if err := db.AutoMigrate( - &models.User{}, &models.Notification{}, &models.Customer{}, &models.CustomerIdentity{}, @@ -200,14 +201,16 @@ func createHumanDispatchRealtimeActiveSchedule(t *testing.T, db *gorm.DB, teamID func createHumanDispatchRealtimeAgentProfile(t *testing.T, db *gorm.DB, userID, teamID int64) { t.Helper() - if err := db.Create(&models.User{ - ID: userID, - Username: "agent", - Nickname: "客服", - Status: enums.StatusOk, - }).Error; err != nil { - t.Fatalf("create user error = %v", err) - } + SetQuerySubjects(func(_ context.Context, query identity.Query) ([]identity.Subject, error) { + if len(query.IDs) > 0 && query.IDs[0] != userID { + return nil, nil + } + return []identity.Subject{{ + Type: identity.SubjectAgent, Category: identity.CategorySystem, + ID: userID, Username: "agent", Name: "客服", Enabled: true, + }}, nil + }) + SetAuthorize(func(_ context.Context, _ string) error { return nil }) if err := db.Create(&models.AgentProfile{ UserID: userID, TeamID: teamID, diff --git a/internal/services/conversation_human_dispatch_service.go b/internal/services/conversation_human_dispatch_service.go index 882d4a4..41c8bb6 100644 --- a/internal/services/conversation_human_dispatch_service.go +++ b/internal/services/conversation_human_dispatch_service.go @@ -6,13 +6,13 @@ import ( "strings" "time" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_human_dispatch_service_test.go b/internal/services/conversation_human_dispatch_service_test.go index ed5a505..8cf526d 100644 --- a/internal/services/conversation_human_dispatch_service_test.go +++ b/internal/services/conversation_human_dispatch_service_test.go @@ -5,11 +5,11 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" @@ -200,7 +200,6 @@ func setupConversationHumanDispatchTestDB(t *testing.T) *gorm.DB { } }) if err := db.AutoMigrate( - &models.User{}, &models.Customer{}, &models.CustomerIdentity{}, &models.AIAgent{}, @@ -257,14 +256,7 @@ func createHumanDispatchActiveSchedule(t *testing.T, db *gorm.DB, teamID int64) func createHumanDispatchAgentProfile(t *testing.T, db *gorm.DB, userID, teamID int64, serviceStatus enums.ServiceStatus, maxConcurrent int, autoAssign bool, status enums.Status) { t.Helper() - if err := db.Create(&models.User{ - ID: userID, - Username: "agent", - Nickname: "客服", - Status: enums.StatusOk, - }).Error; err != nil { - t.Fatalf("create user error = %v", err) - } + registerTestExternalSubject(userID, "agent", "客服", enums.StatusOk) if err := db.Create(&models.AgentProfile{ UserID: userID, TeamID: teamID, diff --git a/internal/services/conversation_interrupt_service.go b/internal/services/conversation_interrupt_service.go index 244f274..a8baacb 100644 --- a/internal/services/conversation_interrupt_service.go +++ b/internal/services/conversation_interrupt_service.go @@ -5,8 +5,8 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_participant_service.go b/internal/services/conversation_participant_service.go index d7a5c3a..981573f 100644 --- a/internal/services/conversation_participant_service.go +++ b/internal/services/conversation_participant_service.go @@ -1,14 +1,14 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/conversation_read_state_service.go b/internal/services/conversation_read_state_service.go index cd7bd7f..80c3792 100644 --- a/internal/services/conversation_read_state_service.go +++ b/internal/services/conversation_read_state_service.go @@ -1,16 +1,16 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/conversation_service.go b/internal/services/conversation_service.go index 75b1edf..3ec2206 100644 --- a/internal/services/conversation_service.go +++ b/internal/services/conversation_service.go @@ -5,18 +5,17 @@ import ( "encoding/json" "log/slog" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "slices" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" @@ -738,7 +737,7 @@ func (s *conversationService) isAdmin(operator *dto.AuthPrincipal) bool { if operator == nil { return false } - return slices.Contains(operator.Roles, constants.RoleCodeSuperAdmin) || slices.Contains(operator.Roles, constants.RoleCodeAdmin) + return operator.SubjectType == identity.SubjectAdmin } func (s *conversationService) buildEventPayload(payload map[string]any) string { diff --git a/internal/services/conversation_tag_service.go b/internal/services/conversation_tag_service.go index f77da19..58ff458 100644 --- a/internal/services/conversation_tag_service.go +++ b/internal/services/conversation_tag_service.go @@ -1,15 +1,15 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/cronx/cron.go b/internal/services/cronx/cron.go index 5b659df..8a0c77b 100644 --- a/internal/services/cronx/cron.go +++ b/internal/services/cronx/cron.go @@ -1,7 +1,7 @@ package cronx import ( - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/services" "fmt" "log/slog" diff --git a/internal/services/customer_contact_service.go b/internal/services/customer_contact_service.go index eb075b7..b8d60c2 100644 --- a/internal/services/customer_contact_service.go +++ b/internal/services/customer_contact_service.go @@ -5,15 +5,15 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" diff --git a/internal/services/customer_identity_service.go b/internal/services/customer_identity_service.go index 2cac659..6894fba 100644 --- a/internal/services/customer_identity_service.go +++ b/internal/services/customer_identity_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/customer_service.go b/internal/services/customer_service.go index 14d8fa4..5b81930 100644 --- a/internal/services/customer_service.go +++ b/internal/services/customer_service.go @@ -5,18 +5,18 @@ import ( "encoding/hex" "log/slog" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/customer_service_test.go b/internal/services/customer_service_test.go index b23349c..21beda8 100644 --- a/internal/services/customer_service_test.go +++ b/internal/services/customer_service_test.go @@ -4,10 +4,10 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/customer_session_service.go b/internal/services/customer_session_service.go deleted file mode 100644 index 1bd4dc9..0000000 --- a/internal/services/customer_session_service.go +++ /dev/null @@ -1,252 +0,0 @@ -package services - -import ( - "errors" - "strings" - "time" - - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" - "github.com/mlogclub/simple/sqls" -) - -const ( - customerSessionTokenType = "customer_session" - customerSessionHeader = "X-Customer-Session-Token" - customerSessionExpHeader = "X-Customer-Session-Expires-At" -) - -var CustomerSessionService = newCustomerSessionService() - -func newCustomerSessionService() *customerSessionService { - return &customerSessionService{} -} - -type customerSessionService struct { -} - -type customerSessionClaims struct { - TokenType string `json:"typ"` - ChannelID int64 `json:"channelId"` - ChannelCode string `json:"channelCode"` - CustomerID int64 `json:"customerId"` - CustomerName string `json:"customerName"` - IdentityKey string `json:"identityKey"` - jwt.RegisteredClaims -} - -type CustomerSessionVerifyResult struct { - ExternalUser *openidentity.ExternalUser - Token string - ExpiresAt time.Time - Refreshed bool -} - -func (s *customerSessionService) Exchange(channel *models.Channel, externalUser openidentity.ExternalUser) (*response.CustomerSessionExchangeResponse, error) { - if channel == nil || channel.Status != enums.StatusOk { - return nil, errorsx.InvalidParamI18n("error.e0209") - } - var customerID int64 - if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - id, err := CustomerService.EnsureExternalCustomer(ctx, externalUser) - if err != nil { - return err - } - customerID = id - return nil - }); err != nil { - return nil, err - } - customer := CustomerService.Get(customerID) - if customer == nil || customer.Status == enums.StatusDeleted { - return nil, errorsx.InvalidParamI18n("error.e0155") - } - token, expiresAt, err := s.Sign(channel, customer, externalUser) - if err != nil { - return nil, err - } - return &response.CustomerSessionExchangeResponse{ - CustomerSessionToken: token, - ExpiresAt: expiresAt.Format(time.DateTime), - IdentityKey: s.identityKey(externalUser), - Customer: response.CustomerSessionCustomerResponse{ - ID: customer.ID, - Name: strings.TrimSpace(customer.Name), - }, - }, nil -} - -func (s *customerSessionService) Sign(channel *models.Channel, customer *models.Customer, externalUser openidentity.ExternalUser) (string, time.Time, error) { - cfg := config.Current().CustomerSession - secret := strings.TrimSpace(cfg.Secret) - if secret == "" { - return "", time.Time{}, errorsx.BusinessErrorI18n(1, "error.customerSession.secretMissing") - } - if channel == nil || customer == nil { - return "", time.Time{}, errorsx.InvalidParamI18n("error.e0158") - } - now := time.Now() - expiresAt := now.Add(time.Duration(cfg.TTL()) * time.Minute) - claims := customerSessionClaims{ - TokenType: customerSessionTokenType, - ChannelID: channel.ID, - ChannelCode: strings.TrimSpace(channel.ChannelID), - CustomerID: customer.ID, - CustomerName: strings.TrimSpace(customer.Name), - IdentityKey: s.identityKey(externalUser), - RegisteredClaims: jwt.RegisteredClaims{ - IssuedAt: jwt.NewNumericDate(now), - ExpiresAt: jwt.NewNumericDate(expiresAt), - }, - } - token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte(secret)) - if err != nil { - return "", time.Time{}, err - } - return token, expiresAt, nil -} - -func (s *customerSessionService) VerifyRequest(ctx *gin.Context, channel *models.Channel) (*CustomerSessionVerifyResult, error) { - token := s.getCustomerSessionToken(ctx) - if token == "" { - return nil, errorsx.UnauthorizedI18n("error.e0157") - } - claims, err := s.verifyToken(token) - if err != nil { - return nil, err - } - if channel == nil || channel.Status != enums.StatusOk { - return nil, errorsx.InvalidParamI18n("error.e0209") - } - if claims.ChannelID != channel.ID || strings.TrimSpace(claims.ChannelCode) != strings.TrimSpace(channel.ChannelID) { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - customer := CustomerService.Get(claims.CustomerID) - if customer == nil || customer.Status == enums.StatusDeleted { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - external, err := s.externalUserFromClaims(claims, customer) - if err != nil { - return nil, err - } - result := &CustomerSessionVerifyResult{ - ExternalUser: external, - Token: token, - ExpiresAt: claims.ExpiresAt.Time, - } - if s.shouldRefresh(claims.ExpiresAt.Time) { - newToken, expiresAt, err := s.Sign(channel, customer, *external) - if err != nil { - return nil, err - } - result.Token = newToken - result.ExpiresAt = expiresAt - result.Refreshed = true - } - return result, nil -} - -func (s *customerSessionService) SetRefreshHeaders(ctx *gin.Context, result *CustomerSessionVerifyResult) { - if ctx == nil || result == nil || !result.Refreshed { - return - } - ctx.Header(customerSessionHeader, result.Token) - ctx.Header(customerSessionExpHeader, result.ExpiresAt.Format(time.DateTime)) -} - -func (s *customerSessionService) verifyToken(rawToken string) (*customerSessionClaims, error) { - cfg := config.Current().CustomerSession - secret := strings.TrimSpace(cfg.Secret) - if secret == "" { - return nil, errorsx.BusinessErrorI18n(1, "error.customerSession.secretMissing") - } - claims := &customerSessionClaims{} - token, err := jwt.ParseWithClaims(rawToken, claims, func(token *jwt.Token) (any, error) { - if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { - return nil, errors.New("unsupported signing method") - } - return []byte(secret), nil - }, jwt.WithExpirationRequired(), jwt.WithValidMethods([]string{ - jwt.SigningMethodHS256.Alg(), - jwt.SigningMethodHS384.Alg(), - jwt.SigningMethodHS512.Alg(), - })) - if err != nil { - if errors.Is(err, jwt.ErrTokenExpired) { - return nil, errorsx.UnauthorizedI18n("error.e0160") - } - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - if token == nil || !token.Valid || claims.TokenType != customerSessionTokenType || claims.ExpiresAt == nil { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - if claims.ChannelID <= 0 || strings.TrimSpace(claims.ChannelCode) == "" || claims.CustomerID <= 0 || strings.TrimSpace(claims.IdentityKey) == "" { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - return claims, nil -} - -func (s *customerSessionService) externalUserFromClaims(claims *customerSessionClaims, customer *models.Customer) (*openidentity.ExternalUser, error) { - identityKey := strings.TrimSpace(claims.IdentityKey) - parts := strings.SplitN(identityKey, ":", 2) - if len(parts) != 2 || strings.TrimSpace(parts[1]) == "" { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - var source enums.ExternalSource - switch parts[0] { - case "user": - source = enums.ExternalSourceUser - case "guest": - source = enums.ExternalSourceGuest - default: - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - identity := repositories.CustomerIdentityRepository.GetBy(sqls.DB(), source, parts[1]) - if identity == nil || identity.CustomerID != claims.CustomerID { - return nil, errorsx.UnauthorizedI18n("error.e0161") - } - name := strings.TrimSpace(claims.CustomerName) - if customer != nil && strings.TrimSpace(customer.Name) != "" { - name = strings.TrimSpace(customer.Name) - } - return &openidentity.ExternalUser{ - ExternalSource: source, - ExternalID: parts[1], - ExternalName: name, - }, nil -} - -func (s *customerSessionService) shouldRefresh(expiresAt time.Time) bool { - threshold := config.Current().CustomerSession.RefreshThreshold() - return time.Until(expiresAt) <= time.Duration(threshold)*time.Minute -} - -func (s *customerSessionService) identityKey(externalUser openidentity.ExternalUser) string { - switch externalUser.ExternalSource { - case enums.ExternalSourceUser: - return "user:" + strings.TrimSpace(externalUser.ExternalID) - default: - return "guest:" + strings.TrimSpace(externalUser.ExternalID) - } -} - -func (s *customerSessionService) getCustomerSessionToken(ctx *gin.Context) string { - auth := strings.TrimSpace(ctx.GetHeader("Authorization")) - if len(auth) > 7 && strings.EqualFold(auth[:7], "Bearer ") { - if token := strings.TrimSpace(auth[7:]); token != "" { - return token - } - } - token, _ := params.Get(ctx, "customerSessionToken") - return strings.TrimSpace(token) -} diff --git a/internal/services/dashboard_service.go b/internal/services/dashboard_service.go index 670302c..2e1b6b1 100644 --- a/internal/services/dashboard_service.go +++ b/internal/services/dashboard_service.go @@ -1,11 +1,11 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "fmt" "sort" "strings" diff --git a/internal/services/dashboard_service_test.go b/internal/services/dashboard_service_test.go index 73810a9..ba29b0d 100644 --- a/internal/services/dashboard_service_test.go +++ b/internal/services/dashboard_service_test.go @@ -1,8 +1,8 @@ package services import ( - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" "testing" ) diff --git a/internal/services/event_handlers/conversation_assigned_event_handler.go b/internal/services/event_handlers/conversation_assigned_event_handler.go index 0ebabe1..8b5511e 100644 --- a/internal/services/event_handlers/conversation_assigned_event_handler.go +++ b/internal/services/event_handlers/conversation_assigned_event_handler.go @@ -6,12 +6,12 @@ import ( "strings" "time" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/common/strs" ) diff --git a/internal/services/event_handlers/notification_event_handler.go b/internal/services/event_handlers/notification_event_handler.go index a35b210..09486ad 100644 --- a/internal/services/event_handlers/notification_event_handler.go +++ b/internal/services/event_handlers/notification_event_handler.go @@ -6,11 +6,11 @@ import ( "log/slog" "strings" - "agent-desk/internal/events" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/common/strs" ) diff --git a/internal/services/event_handlers/notification_event_handler_test.go b/internal/services/event_handlers/notification_event_handler_test.go index c905b09..14d3fdd 100644 --- a/internal/services/event_handlers/notification_event_handler_test.go +++ b/internal/services/event_handlers/notification_event_handler_test.go @@ -5,10 +5,10 @@ import ( "testing" "time" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/event_handlers/ticket_assigned_event_handler.go b/internal/services/event_handlers/ticket_assigned_event_handler.go index 6af4087..97b5403 100644 --- a/internal/services/event_handlers/ticket_assigned_event_handler.go +++ b/internal/services/event_handlers/ticket_assigned_event_handler.go @@ -1,12 +1,12 @@ package event_handlers import ( - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/services" "context" "fmt" "strings" diff --git a/internal/services/event_handlers/ticket_create_event_handler.go b/internal/services/event_handlers/ticket_create_event_handler.go index 8fb5a43..eb50da6 100644 --- a/internal/services/event_handlers/ticket_create_event_handler.go +++ b/internal/services/event_handlers/ticket_create_event_handler.go @@ -1,11 +1,11 @@ package event_handlers import ( - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/services" "context" "fmt" "strings" diff --git a/internal/services/external_subject_test.go b/internal/services/external_subject_test.go new file mode 100644 index 0000000..4b350cc --- /dev/null +++ b/internal/services/external_subject_test.go @@ -0,0 +1,41 @@ +package services_test + +import ( + "context" + "slices" + "sync" + + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/services" +) + +var testExternalSubjects sync.Map + +func registerTestExternalSubject(id int64, username, name string, status enums.Status) { + testExternalSubjects.Store(id, identity.Subject{ + Type: identity.SubjectAgent, + Category: identity.CategorySystem, + ID: id, + Username: username, + Name: name, + Identifier: username, + Enabled: status == enums.StatusOk, + }) + services.SetQuerySubjects(func(_ context.Context, query identity.Query) ([]identity.Subject, error) { + results := make([]identity.Subject, 0) + testExternalSubjects.Range(func(_, value any) bool { + subject := value.(identity.Subject) + if len(query.IDs) > 0 && !slices.Contains(query.IDs, subject.ID) { + return true + } + if query.EnabledOnly && !subject.Enabled { + return true + } + results = append(results, subject) + return true + }) + return results, nil + }) + services.SetAuthorize(func(_ context.Context, _ string) error { return nil }) +} diff --git a/internal/services/im_message_asset.go b/internal/services/im_message_asset.go index 13155bf..14d7ce8 100644 --- a/internal/services/im_message_asset.go +++ b/internal/services/im_message_asset.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/services/storage" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/services/storage" "encoding/json" "strings" ) diff --git a/internal/services/knowledge_base_service.go b/internal/services/knowledge_base_service.go index c6a3043..cc3d320 100644 --- a/internal/services/knowledge_base_service.go +++ b/internal/services/knowledge_base_service.go @@ -7,18 +7,18 @@ import ( "strings" "time" - "agent-desk/internal/ai/rag" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/knowledge_base_service_test.go b/internal/services/knowledge_base_service_test.go index 7e5410d..16f5106 100644 --- a/internal/services/knowledge_base_service_test.go +++ b/internal/services/knowledge_base_service_test.go @@ -5,12 +5,12 @@ import ( "strings" "testing" - "agent-desk/internal/ai/workflow/dsl" - workflowregistry "agent-desk/internal/ai/workflow/registry" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/dsl" + workflowregistry "code.tczkiot.com/wlw/ai-agent/internal/ai/workflow/registry" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/knowledge_directory_service.go b/internal/services/knowledge_directory_service.go index 488f5e5..813823e 100644 --- a/internal/services/knowledge_directory_service.go +++ b/internal/services/knowledge_directory_service.go @@ -4,13 +4,13 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/knowledge_directory_service_test.go b/internal/services/knowledge_directory_service_test.go index e12eee5..c3e8ed2 100644 --- a/internal/services/knowledge_directory_service_test.go +++ b/internal/services/knowledge_directory_service_test.go @@ -3,11 +3,11 @@ package services import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/knowledge_document_service.go b/internal/services/knowledge_document_service.go index 0e70047..9afc907 100644 --- a/internal/services/knowledge_document_service.go +++ b/internal/services/knowledge_document_service.go @@ -7,16 +7,16 @@ import ( "log/slog" "time" - "agent-desk/internal/ai/rag" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/knowledge_faq_excel.go b/internal/services/knowledge_faq_excel.go index cf376fe..0490c1c 100644 --- a/internal/services/knowledge_faq_excel.go +++ b/internal/services/knowledge_faq_excel.go @@ -11,16 +11,16 @@ import ( "strings" "time" - "agent-desk/internal/ai/rag" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" "github.com/xuri/excelize/v2" diff --git a/internal/services/knowledge_faq_excel_test.go b/internal/services/knowledge_faq_excel_test.go index 922d4eb..07b3093 100644 --- a/internal/services/knowledge_faq_excel_test.go +++ b/internal/services/knowledge_faq_excel_test.go @@ -5,11 +5,11 @@ import ( "encoding/json" "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/knowledge_faq_service.go b/internal/services/knowledge_faq_service.go index 76d8edb..e869783 100644 --- a/internal/services/knowledge_faq_service.go +++ b/internal/services/knowledge_faq_service.go @@ -6,16 +6,16 @@ import ( "log/slog" "time" - "agent-desk/internal/ai/rag" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/ai/rag" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/knowledge_retrieve_log_service.go b/internal/services/knowledge_retrieve_log_service.go index 5a92c1e..cff58f4 100644 --- a/internal/services/knowledge_retrieve_log_service.go +++ b/internal/services/knowledge_retrieve_log_service.go @@ -1,9 +1,9 @@ package services import ( - "agent-desk/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/models" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/login_credential_log_service.go b/internal/services/login_credential_log_service.go deleted file mode 100644 index a4fae5d..0000000 --- a/internal/services/login_credential_log_service.go +++ /dev/null @@ -1,67 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var LoginCredentialLogService = newLoginCredentialLogService() - -func newLoginCredentialLogService() *loginCredentialLogService { - return &loginCredentialLogService{} -} - -type loginCredentialLogService struct { -} - -func (s *loginCredentialLogService) Get(id int64) *models.LoginCredentialLog { - return repositories.LoginCredentialLogRepository.Get(sqls.DB(), id) -} - -func (s *loginCredentialLogService) Take(where ...interface{}) *models.LoginCredentialLog { - return repositories.LoginCredentialLogRepository.Take(sqls.DB(), where...) -} - -func (s *loginCredentialLogService) Find(cnd *sqls.Cnd) []models.LoginCredentialLog { - return repositories.LoginCredentialLogRepository.Find(sqls.DB(), cnd) -} - -func (s *loginCredentialLogService) FindOne(cnd *sqls.Cnd) *models.LoginCredentialLog { - return repositories.LoginCredentialLogRepository.FindOne(sqls.DB(), cnd) -} - -func (s *loginCredentialLogService) FindPageByParams(params *params.QueryParams) (list []models.LoginCredentialLog, paging *sqls.Paging) { - return repositories.LoginCredentialLogRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *loginCredentialLogService) FindPageByCnd(cnd *sqls.Cnd) (list []models.LoginCredentialLog, paging *sqls.Paging) { - return repositories.LoginCredentialLogRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *loginCredentialLogService) Count(cnd *sqls.Cnd) int64 { - return repositories.LoginCredentialLogRepository.Count(sqls.DB(), cnd) -} - -func (s *loginCredentialLogService) Create(t *models.LoginCredentialLog) error { - return repositories.LoginCredentialLogRepository.Create(sqls.DB(), t) -} - -func (s *loginCredentialLogService) Update(t *models.LoginCredentialLog) error { - return repositories.LoginCredentialLogRepository.Update(sqls.DB(), t) -} - -func (s *loginCredentialLogService) Updates(id int64, columns map[string]interface{}) error { - return repositories.LoginCredentialLogRepository.Updates(sqls.DB(), id, columns) -} - -func (s *loginCredentialLogService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.LoginCredentialLogRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *loginCredentialLogService) Delete(id int64) { - repositories.LoginCredentialLogRepository.Delete(sqls.DB(), id) -} diff --git a/internal/services/login_session_service.go b/internal/services/login_session_service.go deleted file mode 100644 index 498ac15..0000000 --- a/internal/services/login_session_service.go +++ /dev/null @@ -1,95 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" - "time" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var LoginSessionService = newLoginSessionService() - -func newLoginSessionService() *loginSessionService { - return &loginSessionService{} -} - -type loginSessionService struct { -} - -func (s *loginSessionService) Get(id int64) *models.LoginSession { - return repositories.LoginSessionRepository.Get(sqls.DB(), id) -} - -func (s *loginSessionService) Take(where ...interface{}) *models.LoginSession { - return repositories.LoginSessionRepository.Take(sqls.DB(), where...) -} - -func (s *loginSessionService) Find(cnd *sqls.Cnd) []models.LoginSession { - return repositories.LoginSessionRepository.Find(sqls.DB(), cnd) -} - -func (s *loginSessionService) FindOne(cnd *sqls.Cnd) *models.LoginSession { - return repositories.LoginSessionRepository.FindOne(sqls.DB(), cnd) -} - -func (s *loginSessionService) FindPageByParams(params *params.QueryParams) (list []models.LoginSession, paging *sqls.Paging) { - return repositories.LoginSessionRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *loginSessionService) FindPageByCnd(cnd *sqls.Cnd) (list []models.LoginSession, paging *sqls.Paging) { - return repositories.LoginSessionRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *loginSessionService) Count(cnd *sqls.Cnd) int64 { - return repositories.LoginSessionRepository.Count(sqls.DB(), cnd) -} - -func (s *loginSessionService) Create(t *models.LoginSession) error { - return repositories.LoginSessionRepository.Create(sqls.DB(), t) -} - -func (s *loginSessionService) Update(t *models.LoginSession) error { - return repositories.LoginSessionRepository.Update(sqls.DB(), t) -} - -func (s *loginSessionService) Updates(id int64, columns map[string]interface{}) error { - return repositories.LoginSessionRepository.Updates(sqls.DB(), id, columns) -} - -func (s *loginSessionService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.LoginSessionRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *loginSessionService) Delete(id int64) { - repositories.LoginSessionRepository.Delete(sqls.DB(), id) -} - -func (s *loginSessionService) Revoke(id int64, operatorID int64, operatorName string) error { - session := s.Get(id) - if session == nil { - return errorsx.InvalidParamI18n("error.e0116") - } - now := time.Now() - return s.Updates(id, map[string]any{ - "revoked_at": now, - "update_user_id": operatorID, - "update_user_name": operatorName, - "updated_at": now, - }) -} - -func (s *loginSessionService) RevokeByUser(userID int64, operatorID int64, operatorName string) error { - now := time.Now() - return sqls.DB().Model(&models.LoginSession{}). - Where("user_id = ? AND revoked_at IS NULL", userID). - Updates(map[string]any{ - "revoked_at": now, - "update_user_id": operatorID, - "update_user_name": operatorName, - "updated_at": now, - }).Error -} diff --git a/internal/services/mcp_debug_service.go b/internal/services/mcp_debug_service.go index 9b3deab..052ca7f 100644 --- a/internal/services/mcp_debug_service.go +++ b/internal/services/mcp_debug_service.go @@ -9,9 +9,9 @@ import ( "strings" "time" - "agent-desk/internal/ai/mcps" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) var MCPDebugService = newMCPDebugService() diff --git a/internal/services/message_service.go b/internal/services/message_service.go index 94c9e7a..129264a 100644 --- a/internal/services/message_service.go +++ b/internal/services/message_service.go @@ -1,20 +1,20 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/tracex" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/tracex" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "log/slog" "slices" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/message_service_test.go b/internal/services/message_service_test.go index 58ee46b..97bf536 100644 --- a/internal/services/message_service_test.go +++ b/internal/services/message_service_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/migration_service.go b/internal/services/migration_service.go index 7d8aa9a..8bdce1c 100644 --- a/internal/services/migration_service.go +++ b/internal/services/migration_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/notification_service.go b/internal/services/notification_service.go index 804c534..5aa46c6 100644 --- a/internal/services/notification_service.go +++ b/internal/services/notification_service.go @@ -4,13 +4,13 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/notification_service_test.go b/internal/services/notification_service_test.go index 18ca459..f074000 100644 --- a/internal/services/notification_service_test.go +++ b/internal/services/notification_service_test.go @@ -3,9 +3,9 @@ package services_test import ( "testing" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/glebarez/sqlite" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/oidc_login_service.go b/internal/services/oidc_login_service.go deleted file mode 100644 index 9fc25d2..0000000 --- a/internal/services/oidc_login_service.go +++ /dev/null @@ -1,245 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/oidcclient" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" - "context" - "crypto/sha256" - "encoding/hex" - "strconv" - "strings" - "time" - "unicode" - - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var OIDCLoginService = newOIDCLoginService() - -type oidcLoginService struct { -} - -type oidcLoginProfile = oidcclient.Profile - -func newOIDCLoginService() *oidcLoginService { - return &oidcLoginService{} -} - -func (s *oidcLoginService) BuildOIDCLoginURL(next string) (string, error) { - return oidcclient.BuildAuthCodeURL(next) -} - -func (s *oidcLoginService) LoginByOIDC(ctx context.Context, code, state string, authCfg config.AuthConfig, clientIP, userAgent string) (string, string, error) { - next, err := oidcclient.ParseState(state) - if err != nil { - return "", "", err - } - profile, err := oidcclient.ExchangeCode(ctx, code) - if err != nil { - return "", "", err - } - loginResp, err := s.loginWithOIDCProfile(profile, authCfg, clientIP, userAgent) - if err != nil { - return "", "", err - } - ticket, err := oidcclient.IssueLoginTicket(loginResp) - if err != nil { - return "", "", err - } - return ticket, next, nil -} - -func (s *oidcLoginService) ExchangeOIDCLoginTicket(ticket string) (*response.LoginResponse, error) { - return oidcclient.ConsumeLoginTicket(ticket) -} - -func (s *oidcLoginService) loginWithOIDCProfile(profile *oidcLoginProfile, authCfg config.AuthConfig, clientIP, userAgent string) (*response.LoginResponse, error) { - if profile == nil || strings.TrimSpace(profile.Subject) == "" { - return nil, errorsx.BusinessErrorI18n(2, "error.oidc.profileMissing") - } - - var ret *response.LoginResponse - err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - var ( - identity = repositories.UserIdentityRepository.GetBy(ctx.Tx, enums.ThirdProviderOIDC, "", profile.Subject) - user *models.User - err error - ) - if identity == nil { - user, identity, err = s.createOIDCUser(ctx, profile) - if err != nil { - return err - } - } else { - if identity.Status != enums.StatusOk { - return errorsx.BusinessErrorI18n(3, "error.oidc.bindingDisabled") - } - user = repositories.UserRepository.Get(ctx.Tx, identity.UserID) - if user == nil { - return errorsx.BusinessErrorI18n(4, "error.oidc.boundUserMissing") - } - } - - if user.Status != enums.StatusOk { - return errorsx.UnauthorizedI18n("error.e0200") - } - - if err = repositories.UserRepository.Updates(ctx.Tx, user.ID, map[string]any{ - "nickname": s.resolveOIDCNickname(user.Nickname, profile), - "avatar": s.resolveOIDCAvatar(user.Avatar, profile), - "last_login_at": time.Now(), - "last_login_ip": clientIP, - "update_user_id": user.ID, - "update_user_name": user.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - - if err = repositories.UserIdentityRepository.Updates(ctx.Tx, identity.ID, map[string]any{ - "provider_name": enums.GetThirdProviderLabel(enums.ThirdProviderOIDC), - "raw_profile": profile.RawProfile, - "last_auth_at": time.Now(), - "status": enums.StatusOk, - "update_user_id": user.ID, - "update_user_name": user.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - - ret, err = AuthService.issueTokens(ctx, user, clientIP, userAgent, authCfg) - return err - }) - if err != nil { - return nil, err - } - return ret, nil -} - -func (s *oidcLoginService) createOIDCUser(ctx *sqls.TxContext, profile *oidcLoginProfile) (*models.User, *models.UserIdentity, error) { - now := time.Now() - email := s.availableEmail(ctx.Tx, profile.Email) - username := s.availableUsername(ctx.Tx, profile) - - user := &models.User{ - Username: username, - Nickname: s.resolveOIDCNickname("", profile), - Avatar: s.resolveOIDCAvatar("", profile), - Email: email, - Password: "", - PasswordSalt: "", - Status: enums.StatusOk, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: 0, - CreateUserName: enums.GetThirdProviderLabel(enums.ThirdProviderOIDC), - UpdatedAt: now, - UpdateUserID: 0, - UpdateUserName: enums.GetThirdProviderLabel(enums.ThirdProviderOIDC), - }, - } - if err := repositories.UserRepository.Create(ctx.Tx, user); err != nil { - return nil, nil, err - } - - identity := &models.UserIdentity{ - UserID: user.ID, - Provider: enums.ThirdProviderOIDC, - ProviderUserID: strings.TrimSpace(profile.Subject), - ProviderCorpID: "", - ProviderName: enums.GetThirdProviderLabel(enums.ThirdProviderOIDC), - RawProfile: profile.RawProfile, - Status: enums.StatusOk, - LastAuthAt: &now, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: user.ID, - CreateUserName: user.Username, - UpdatedAt: now, - UpdateUserID: user.ID, - UpdateUserName: user.Username, - }, - } - if err := repositories.UserIdentityRepository.Create(ctx.Tx, identity); err != nil { - return nil, nil, err - } - return user, identity, nil -} - -func (s *oidcLoginService) availableEmail(tx *gorm.DB, email string) *string { - email = strings.TrimSpace(strings.ToLower(email)) - if email == "" || repositories.UserRepository.GetByEmail(tx, email) != nil { - return nil - } - return &email -} - -func (s *oidcLoginService) availableUsername(tx *gorm.DB, profile *oidcLoginProfile) string { - for _, candidate := range []string{ - profile.PreferredUsername, - strings.Split(strings.TrimSpace(profile.Email), "@")[0], - } { - username := normalizeOIDCUsername(candidate) - if username != "" && repositories.UserRepository.GetByUsername(tx, username) == nil { - return username - } - } - base := "oidc_" + shortSubjectHash(profile.Subject) - if repositories.UserRepository.GetByUsername(tx, base) == nil { - return base - } - for i := 1; i < 100; i++ { - username := base + "_" + strconv.Itoa(i) - if repositories.UserRepository.GetByUsername(tx, username) == nil { - return username - } - } - return base + "_" + shortSubjectHash(time.Now().String()) -} - -func (s *oidcLoginService) resolveOIDCNickname(current string, profile *oidcLoginProfile) string { - if profile != nil { - for _, candidate := range []string{profile.Name, profile.PreferredUsername, profile.Email, profile.Subject} { - if candidate = strings.TrimSpace(candidate); candidate != "" { - return candidate - } - } - } - return strings.TrimSpace(current) -} - -func (s *oidcLoginService) resolveOIDCAvatar(current string, profile *oidcLoginProfile) string { - if profile != nil { - if picture := strings.TrimSpace(profile.Picture); picture != "" { - return picture - } - } - return strings.TrimSpace(current) -} - -func normalizeOIDCUsername(value string) string { - value = strings.TrimSpace(strings.ToLower(value)) - var b strings.Builder - for _, r := range value { - if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' || r == '-' || r == '.' { - b.WriteRune(r) - } - } - ret := strings.Trim(b.String(), "._-") - if len(ret) > 100 { - ret = ret[:100] - } - return ret -} - -func shortSubjectHash(subject string) string { - sum := sha256.Sum256([]byte(strings.TrimSpace(subject))) - return hex.EncodeToString(sum[:])[:16] -} diff --git a/internal/services/oidc_login_service_test.go b/internal/services/oidc_login_service_test.go deleted file mode 100644 index 4e0749d..0000000 --- a/internal/services/oidc_login_service_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package services - -import ( - "strings" - "testing" - - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" -) - -func TestOIDCLoginAutoCreatesSystemUser(t *testing.T) { - db := setupAuthServiceTestDB(t) - svc := newOIDCLoginService() - - ret, err := svc.loginWithOIDCProfile(&oidcLoginProfile{ - Subject: "sub-123", - Email: "ada@example.com", - PreferredUsername: "ada", - Name: "Ada Lovelace", - Picture: "https://example.com/ada.png", - RawProfile: `{"sub":"sub-123"}`, - }, config.AuthConfig{TokenTTLHours: 2}, "127.0.0.1", "go-test") - if err != nil { - t.Fatalf("loginWithOIDCProfile() error = %v", err) - } - if ret == nil || !strings.HasPrefix(ret.AccessToken, "ak_") { - t.Fatalf("expected ak_ access token, got %+v", ret) - } - - var user models.User - if err := db.Take(&user, "username = ?", "ada").Error; err != nil { - t.Fatalf("expected OIDC user to be created: %v", err) - } - if user.Nickname != "Ada Lovelace" || user.Avatar != "https://example.com/ada.png" { - t.Fatalf("unexpected created user profile: %+v", user) - } - if user.Email == nil || *user.Email != "ada@example.com" { - t.Fatalf("expected email to be stored, got %+v", user.Email) - } - if user.Password != "" { - t.Fatalf("expected OIDC-created user password to be empty, got %q", user.Password) - } - - var identity models.UserIdentity - if err := db.Take(&identity, "provider = ? AND provider_user_id = ?", enums.ThirdProviderOIDC, "sub-123").Error; err != nil { - t.Fatalf("expected OIDC identity to be created: %v", err) - } - if identity.UserID != user.ID || identity.ProviderName != "OIDC" || identity.Status != enums.StatusOk { - t.Fatalf("unexpected OIDC identity: %+v", identity) - } - - var sessions []models.LoginSession - if err := db.Find(&sessions).Error; err != nil { - t.Fatalf("query login sessions: %v", err) - } - if len(sessions) != 1 || sessions[0].UserID != user.ID || sessions[0].Token != ret.AccessToken { - t.Fatalf("unexpected login sessions: %+v", sessions) - } -} - -func TestOIDCLoginReusesExistingIdentity(t *testing.T) { - db := setupAuthServiceTestDB(t) - user := createAuthTestUser(t, db, "existing", "secret") - if err := db.Create(&models.UserIdentity{ - UserID: user.ID, - Provider: enums.ThirdProviderOIDC, - ProviderUserID: "sub-123", - ProviderName: "OIDC", - Status: enums.StatusOk, - }).Error; err != nil { - t.Fatalf("seed OIDC identity: %v", err) - } - - ret, err := newOIDCLoginService().loginWithOIDCProfile(&oidcLoginProfile{ - Subject: "sub-123", - PreferredUsername: "ignored", - Name: "Updated Name", - Picture: "https://example.com/updated.png", - RawProfile: `{"sub":"sub-123"}`, - }, config.AuthConfig{TokenTTLHours: 2}, "127.0.0.1", "go-test") - if err != nil { - t.Fatalf("loginWithOIDCProfile() error = %v", err) - } - if ret == nil || ret.User == nil || ret.User.ID != user.ID { - t.Fatalf("expected existing user login response, got %+v", ret) - } - - var count int64 - if err := db.Model(&models.User{}).Count(&count).Error; err != nil { - t.Fatalf("count users: %v", err) - } - if count != 1 { - t.Fatalf("expected existing identity to reuse user, got %d users", count) - } -} diff --git a/internal/services/permission_service.go b/internal/services/permission_service.go deleted file mode 100644 index 330c930..0000000 --- a/internal/services/permission_service.go +++ /dev/null @@ -1,144 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - "fmt" - "time" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var PermissionService = newPermissionService() - -func newPermissionService() *permissionService { - return &permissionService{} -} - -type permissionService struct { -} - -func (s *permissionService) Get(id int64) *models.Permission { - return repositories.PermissionRepository.Get(sqls.DB(), id) -} - -func (s *permissionService) Take(where ...interface{}) *models.Permission { - return repositories.PermissionRepository.Take(sqls.DB(), where...) -} - -func (s *permissionService) Find(cnd *sqls.Cnd) []models.Permission { - return repositories.PermissionRepository.Find(sqls.DB(), cnd) -} - -func (s *permissionService) FindOne(cnd *sqls.Cnd) *models.Permission { - return repositories.PermissionRepository.FindOne(sqls.DB(), cnd) -} - -func (s *permissionService) FindPageByParams(params *params.QueryParams) (list []models.Permission, paging *sqls.Paging) { - return repositories.PermissionRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *permissionService) FindPageByCnd(cnd *sqls.Cnd) (list []models.Permission, paging *sqls.Paging) { - return repositories.PermissionRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *permissionService) Count(cnd *sqls.Cnd) int64 { - return repositories.PermissionRepository.Count(sqls.DB(), cnd) -} - -func (s *permissionService) Create(t *models.Permission) error { - return repositories.PermissionRepository.Create(sqls.DB(), t) -} - -func (s *permissionService) Update(t *models.Permission) error { - return repositories.PermissionRepository.Update(sqls.DB(), t) -} - -func (s *permissionService) Updates(id int64, columns map[string]interface{}) error { - return repositories.PermissionRepository.Updates(sqls.DB(), id, columns) -} - -func (s *permissionService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.PermissionRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *permissionService) Delete(id int64) { - repositories.PermissionRepository.Delete(sqls.DB(), id) -} - -func (s *permissionService) SyncBuiltinPermissions() (*response.PermissionSyncResponse, error) { - result := &response.PermissionSyncResponse{} - err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - permissions := make(map[string]*models.Permission, len(constants.Permissions)) - now := time.Now() - - for _, spec := range constants.Permissions { - permission := repositories.PermissionRepository.FindOne(ctx.Tx, sqls.NewCnd().Eq("code", spec.Code)) - if permission == nil { - permission = &models.Permission{ - Name: spec.Name, Code: spec.Code, Type: spec.Type, GroupName: spec.GroupName, - Method: spec.Method, APIPath: spec.APIPath, SortNo: spec.SortNo, - Status: enums.StatusOk, IsBuiltin: true, - AuditFields: systemPermissionAuditFields(now), - } - if err := repositories.PermissionRepository.Create(ctx.Tx, permission); err != nil { - return err - } - result.Created++ - } else { - if err := repositories.PermissionRepository.Updates(ctx.Tx, permission.ID, map[string]any{ - "name": spec.Name, "type": spec.Type, "group_name": spec.GroupName, - "method": spec.Method, "api_path": spec.APIPath, "sort_no": spec.SortNo, - "status": enums.StatusOk, "is_builtin": true, - "update_user_id": constants.SystemAuditUserID, - "update_user_name": constants.SystemAuditUserName, "updated_at": now, - }); err != nil { - return err - } - permission = repositories.PermissionRepository.Get(ctx.Tx, permission.ID) - result.Updated++ - } - permissions[spec.Code] = permission - } - - for roleCode, specs := range constants.RolePermissions { - role := repositories.RoleRepository.GetByCode(ctx.Tx, roleCode) - if role == nil { - return fmt.Errorf("builtin role not found: %s", roleCode) - } - for _, spec := range specs { - permission := permissions[spec.Code] - if permission == nil { - return fmt.Errorf("builtin permission not found: %s", spec.Code) - } - if repositories.RolePermissionRepository.FindOne(ctx.Tx, sqls.NewCnd().Eq("role_id", role.ID).Eq("permission_id", permission.ID)) != nil { - continue - } - if err := repositories.RolePermissionRepository.Create(ctx.Tx, &models.RolePermission{ - RoleID: role.ID, PermissionID: permission.ID, - AuditFields: systemPermissionAuditFields(now), - }); err != nil { - return err - } - result.RolePermissionsAdded++ - } - } - return nil - }) - if err != nil { - return nil, err - } - return result, nil -} - -func systemPermissionAuditFields(now time.Time) models.AuditFields { - return models.AuditFields{ - CreatedAt: now, CreateUserID: constants.SystemAuditUserID, CreateUserName: constants.SystemAuditUserName, - UpdatedAt: now, UpdateUserID: constants.SystemAuditUserID, UpdateUserName: constants.SystemAuditUserName, - } -} diff --git a/internal/services/permission_service_test.go b/internal/services/permission_service_test.go deleted file mode 100644 index 7752332..0000000 --- a/internal/services/permission_service_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/constants" - "agent-desk/internal/pkg/enums" - "testing" - "time" - - "github.com/glebarez/sqlite" - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" - "gorm.io/gorm/schema" -) - -func TestPermissionServiceSyncBuiltinPermissions(t *testing.T) { - db := setupPermissionServiceTestDB(t) - now := time.Now() - for _, spec := range constants.Roles { - if err := db.Create(&models.Role{ - Name: spec.Name, Code: spec.Code, Status: enums.StatusOk, IsSystem: true, SortNo: spec.SortNo, - AuditFields: models.AuditFields{CreatedAt: now, UpdatedAt: now}, - }).Error; err != nil { - t.Fatalf("create role %s: %v", spec.Code, err) - } - } - customPermission := &models.Permission{ - Name: "Custom permission", Code: "custom.keep", Type: "api", GroupName: "custom", - Status: enums.StatusOk, AuditFields: models.AuditFields{CreatedAt: now, UpdatedAt: now}, - } - if err := db.Create(customPermission).Error; err != nil { - t.Fatalf("create custom permission: %v", err) - } - superAdmin := &models.Role{} - if err := db.First(superAdmin, "code = ?", constants.RoleCodeSuperAdmin).Error; err != nil { - t.Fatalf("find super admin role: %v", err) - } - if err := db.Create(&models.RolePermission{ - RoleID: superAdmin.ID, PermissionID: customPermission.ID, - AuditFields: models.AuditFields{CreatedAt: now, UpdatedAt: now}, - }).Error; err != nil { - t.Fatalf("create custom role permission: %v", err) - } - - first, err := PermissionService.SyncBuiltinPermissions() - if err != nil { - t.Fatalf("first sync: %v", err) - } - if first.Created != len(constants.Permissions) || first.Updated != 0 { - t.Fatalf("unexpected first sync result: %+v", first) - } - - wantRolePermissions := 0 - for _, permissions := range constants.RolePermissions { - wantRolePermissions += len(permissions) - } - if first.RolePermissionsAdded != wantRolePermissions { - t.Fatalf("role permissions added=%d want=%d", first.RolePermissionsAdded, wantRolePermissions) - } - - second, err := PermissionService.SyncBuiltinPermissions() - if err != nil { - t.Fatalf("second sync: %v", err) - } - if second.Created != 0 || second.Updated != len(constants.Permissions) || second.RolePermissionsAdded != 0 { - t.Fatalf("sync is not idempotent: %+v", second) - } - - var permissionCount int64 - if err := db.Model(&models.Permission{}).Count(&permissionCount).Error; err != nil { - t.Fatalf("count permissions: %v", err) - } - if permissionCount != int64(len(constants.Permissions)+1) { - t.Fatalf("permission count=%d want=%d", permissionCount, len(constants.Permissions)+1) - } - var customRolePermissionCount int64 - if err := db.Model(&models.RolePermission{}). - Where("role_id = ? AND permission_id = ?", superAdmin.ID, customPermission.ID). - Count(&customRolePermissionCount).Error; err != nil { - t.Fatalf("count custom role permission: %v", err) - } - if customRolePermissionCount != 1 { - t.Fatalf("custom role permission was removed") - } -} - -func setupPermissionServiceTestDB(t *testing.T) *gorm.DB { - t.Helper() - db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{ - NamingStrategy: schema.NamingStrategy{TablePrefix: "t_", SingularTable: true}, - }) - if err != nil { - t.Fatalf("open sqlite db: %v", err) - } - if err := db.AutoMigrate(&models.Role{}, &models.Permission{}, &models.RolePermission{}); err != nil { - t.Fatalf("migrate permission tables: %v", err) - } - sqls.SetDB(db) - return db -} diff --git a/internal/services/quick_reply_service.go b/internal/services/quick_reply_service.go index 460056d..c08b056 100644 --- a/internal/services/quick_reply_service.go +++ b/internal/services/quick_reply_service.go @@ -1,16 +1,16 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/role_permission_service.go b/internal/services/role_permission_service.go deleted file mode 100644 index 9dc4e86..0000000 --- a/internal/services/role_permission_service.go +++ /dev/null @@ -1,67 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var RolePermissionService = newRolePermissionService() - -func newRolePermissionService() *rolePermissionService { - return &rolePermissionService{} -} - -type rolePermissionService struct { -} - -func (s *rolePermissionService) Get(id int64) *models.RolePermission { - return repositories.RolePermissionRepository.Get(sqls.DB(), id) -} - -func (s *rolePermissionService) Take(where ...interface{}) *models.RolePermission { - return repositories.RolePermissionRepository.Take(sqls.DB(), where...) -} - -func (s *rolePermissionService) Find(cnd *sqls.Cnd) []models.RolePermission { - return repositories.RolePermissionRepository.Find(sqls.DB(), cnd) -} - -func (s *rolePermissionService) FindOne(cnd *sqls.Cnd) *models.RolePermission { - return repositories.RolePermissionRepository.FindOne(sqls.DB(), cnd) -} - -func (s *rolePermissionService) FindPageByParams(params *params.QueryParams) (list []models.RolePermission, paging *sqls.Paging) { - return repositories.RolePermissionRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *rolePermissionService) FindPageByCnd(cnd *sqls.Cnd) (list []models.RolePermission, paging *sqls.Paging) { - return repositories.RolePermissionRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *rolePermissionService) Count(cnd *sqls.Cnd) int64 { - return repositories.RolePermissionRepository.Count(sqls.DB(), cnd) -} - -func (s *rolePermissionService) Create(t *models.RolePermission) error { - return repositories.RolePermissionRepository.Create(sqls.DB(), t) -} - -func (s *rolePermissionService) Update(t *models.RolePermission) error { - return repositories.RolePermissionRepository.Update(sqls.DB(), t) -} - -func (s *rolePermissionService) Updates(id int64, columns map[string]interface{}) error { - return repositories.RolePermissionRepository.Updates(sqls.DB(), id, columns) -} - -func (s *rolePermissionService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.RolePermissionRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *rolePermissionService) Delete(id int64) { - repositories.RolePermissionRepository.Delete(sqls.DB(), id) -} diff --git a/internal/services/role_service.go b/internal/services/role_service.go deleted file mode 100644 index cf1046b..0000000 --- a/internal/services/role_service.go +++ /dev/null @@ -1,200 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "slices" - "strings" - "time" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var RoleService = newRoleService() - -func newRoleService() *roleService { - return &roleService{} -} - -type roleService struct { -} - -func (s *roleService) Get(id int64) *models.Role { - return repositories.RoleRepository.Get(sqls.DB(), id) -} - -func (s *roleService) Take(where ...interface{}) *models.Role { - return repositories.RoleRepository.Take(sqls.DB(), where...) -} - -func (s *roleService) Find(cnd *sqls.Cnd) []models.Role { - return repositories.RoleRepository.Find(sqls.DB(), cnd) -} - -func (s *roleService) FindOne(cnd *sqls.Cnd) *models.Role { - return repositories.RoleRepository.FindOne(sqls.DB(), cnd) -} - -func (s *roleService) FindPageByParams(params *params.QueryParams) (list []models.Role, paging *sqls.Paging) { - return repositories.RoleRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *roleService) FindPageByCnd(cnd *sqls.Cnd) (list []models.Role, paging *sqls.Paging) { - return repositories.RoleRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *roleService) Count(cnd *sqls.Cnd) int64 { - return repositories.RoleRepository.Count(sqls.DB(), cnd) -} - -func (s *roleService) Create(t *models.Role) error { - return repositories.RoleRepository.Create(sqls.DB(), t) -} - -func (s *roleService) Update(t *models.Role) error { - return repositories.RoleRepository.Update(sqls.DB(), t) -} - -func (s *roleService) Updates(id int64, columns map[string]interface{}) error { - return repositories.RoleRepository.Updates(sqls.DB(), id, columns) -} - -func (s *roleService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.RoleRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *roleService) Delete(id int64) { - repositories.RoleRepository.Delete(sqls.DB(), id) -} - -func (s *roleService) CreateRole(req request.CreateRoleRequest, operator *dto.AuthPrincipal) (*models.Role, error) { - name := strings.TrimSpace(req.Name) - code := strings.TrimSpace(req.Code) - if name == "" || code == "" { - return nil, errorsx.InvalidParamI18n("error.e0306") - } - if s.Take("code = ?", code) != nil { - return nil, errorsx.InvalidParamI18n("error.e0308") - } - - role := &models.Role{ - Name: name, - Code: code, - Status: enums.StatusOk, - IsSystem: false, - SortNo: s.NextSortNo(), - Remark: strings.TrimSpace(req.Remark), - AuditFields: utils.BuildAuditFields(operator), - } - if err := s.Create(role); err != nil { - return nil, err - } - return role, nil -} - -func (s *roleService) UpdateRole(req request.UpdateRoleRequest, operator *dto.AuthPrincipal) error { - role := s.Get(req.ID) - if role == nil { - return errorsx.InvalidParamI18n("error.e0305") - } - now := time.Now() - return s.Updates(req.ID, map[string]any{ - "name": strings.TrimSpace(req.Name), - "sort_no": req.SortNo, - "remark": strings.TrimSpace(req.Remark), - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": now, - }) -} - -func (s *roleService) NextSortNo() int { - if latest := s.FindOne(sqls.NewCnd().Desc("sort_no").Desc("id")); latest != nil { - return latest.SortNo + 1 - } - return 0 -} - -func (s *roleService) UpdateSort(ids []int64) error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - for i, id := range ids { - if err := repositories.RoleRepository.UpdateColumn(ctx.Tx, id, "sort_no", i); err != nil { - return err - } - } - return nil - }) -} - -func (s *roleService) DeleteRole(id int64) error { - role := s.Get(id) - if role == nil { - return errorsx.InvalidParamI18n("error.e0305") - } - if role.IsSystem { - return errorsx.ForbiddenI18n("error.e0293") - } - if UserRoleService.Take("role_id = ?", id) != nil { - return errorsx.ForbiddenI18n("error.e0307") - } - s.Delete(id) - return nil -} - -func (s *roleService) UpdateStatus(id int64, status enums.Status, operator *dto.AuthPrincipal) error { - role := s.Get(id) - if role == nil { - return errorsx.InvalidParamI18n("error.e0305") - } - if !slices.Contains(enums.StatusValues, status) { - return errorsx.InvalidParamI18n("error.e0254") - } - if err := s.Updates(id, map[string]any{ - "status": status, - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - return nil -} - -func (s *roleService) AssignPermissions(roleID int64, permissionIDs []int64, operator *dto.AuthPrincipal) error { - role := s.Get(roleID) - if role == nil { - return errorsx.InvalidParamI18n("error.e0305") - } - - return s.replaceRolePermissions(roleID, permissionIDs, operator) -} - -func (s *roleService) replaceRolePermissions(roleID int64, permissionIDs []int64, operator *dto.AuthPrincipal) error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - if err := ctx.Tx.Where("role_id = ?", roleID).Delete(&models.RolePermission{}).Error; err != nil { - return err - } - for _, permissionID := range permissionIDs { - permission := PermissionService.Get(permissionID) - if permission == nil { - return errorsx.InvalidParamI18n("error.e0236") - } - relation := &models.RolePermission{ - RoleID: roleID, - PermissionID: permissionID, - AuditFields: utils.BuildAuditFields(operator), - } - if err := ctx.Tx.Create(relation).Error; err != nil { - return err - } - } - return nil - }) -} diff --git a/internal/services/skill_definition_service.go b/internal/services/skill_definition_service.go index e0b1299..36bf782 100644 --- a/internal/services/skill_definition_service.go +++ b/internal/services/skill_definition_service.go @@ -5,16 +5,16 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/toolx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/skill_runtime_service.go b/internal/services/skill_runtime_service.go index 8c914ac..c7f6110 100644 --- a/internal/services/skill_runtime_service.go +++ b/internal/services/skill_runtime_service.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" ) var SkillRuntimeService = newSkillRuntimeService() diff --git a/internal/services/storage/dto.go b/internal/services/storage/dto.go index 9269ffc..b1b65f7 100644 --- a/internal/services/storage/dto.go +++ b/internal/services/storage/dto.go @@ -1,8 +1,8 @@ package storage import ( - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) type UploadInfo struct { diff --git a/internal/services/storage/local.go b/internal/services/storage/local.go index d9f3cbd..6587ecc 100644 --- a/internal/services/storage/local.go +++ b/internal/services/storage/local.go @@ -1,8 +1,8 @@ package storage import ( - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" "io" "os" "path/filepath" diff --git a/internal/services/storage/oss.go b/internal/services/storage/oss.go index e8daff9..185c29b 100644 --- a/internal/services/storage/oss.go +++ b/internal/services/storage/oss.go @@ -1,9 +1,9 @@ package storage import ( - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "fmt" "io" "net/url" diff --git a/internal/services/storage/provider.go b/internal/services/storage/provider.go index b52907c..c1865ca 100644 --- a/internal/services/storage/provider.go +++ b/internal/services/storage/provider.go @@ -1,9 +1,9 @@ package storage import ( - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" "io" ) diff --git a/internal/services/subject_service.go b/internal/services/subject_service.go new file mode 100644 index 0000000..d231379 --- /dev/null +++ b/internal/services/subject_service.go @@ -0,0 +1,111 @@ +package services + +import ( + "context" + "errors" + "fmt" + "log/slog" + "sync" + + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" +) + +var SubjectService = &subjectService{} + +type subjectService struct { + mu sync.RWMutex + query identity.QuerySubjectsFunc + authorize identity.AuthorizeFunc +} + +func SetQuerySubjects(query identity.QuerySubjectsFunc) { + SubjectService.mu.Lock() + defer SubjectService.mu.Unlock() + SubjectService.query = query +} + +func SetAuthorize(authorize identity.AuthorizeFunc) { + SubjectService.mu.Lock() + defer SubjectService.mu.Unlock() + SubjectService.authorize = authorize +} + +func (s *subjectService) Authorize(ctx context.Context, operation string) error { + s.mu.RLock() + fn := s.authorize + s.mu.RUnlock() + if fn == nil { + return errors.New("agent-desk: Authorize is not initialized") + } + return fn(ctx, operation) +} + +func (s *subjectService) Query(ctx context.Context, query identity.Query) ([]identity.Subject, error) { + s.mu.RLock() + fn := s.query + s.mu.RUnlock() + if fn == nil { + return nil, errors.New("agent-desk: QuerySubjects is not initialized") + } + return fn(ctx, query) +} + +func (s *subjectService) Current(ctx context.Context) (*identity.Subject, error) { + items, err := s.Query(ctx, identity.Query{Current: true, EnabledOnly: true}) + if err != nil { + return nil, err + } + if len(items) == 0 { + return nil, errors.New("agent-desk: current subject not found") + } + return &items[0], nil +} + +func (s *subjectService) CurrentExternal(ctx context.Context) (*openidentity.ExternalUser, error) { + subject, err := s.Current(ctx) + if err != nil { + return nil, err + } + if subject.Category != identity.CategoryUser || !subject.Enabled { + return nil, errors.New("agent-desk: current subject is not a customer identity") + } + return &openidentity.ExternalUser{ + ExternalSource: enums.ExternalSourceUser, + ExternalID: fmt.Sprintf("%s:%d", subject.Type, subject.ID), + ExternalName: subject.Name, + }, nil +} + +func (s *subjectService) Get(id int64) *identity.Subject { + items, err := s.Query(context.Background(), identity.Query{ + Types: []identity.SubjectType{identity.SubjectAgent}, + IDs: []int64{id}, + EnabledOnly: true, + }) + if err != nil { + slog.Warn("query external subject failed", "id", id, "error", err) + return nil + } + if len(items) == 0 { + return nil + } + return &items[0] +} + +func (s *subjectService) FindByIDs(ids []int64) []identity.Subject { + if len(ids) == 0 { + return nil + } + items, err := s.Query(context.Background(), identity.Query{ + Types: []identity.SubjectType{identity.SubjectAgent}, + IDs: ids, + EnabledOnly: true, + }) + if err != nil { + slog.Warn("query external subjects failed", "error", err) + return nil + } + return items +} diff --git a/internal/services/system_config_service.go b/internal/services/system_config_service.go index ba88527..0cff9b6 100644 --- a/internal/services/system_config_service.go +++ b/internal/services/system_config_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/tag_service.go b/internal/services/tag_service.go index f0beda7..8d5249f 100644 --- a/internal/services/tag_service.go +++ b/internal/services/tag_service.go @@ -1,17 +1,17 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "strings" "time" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/ticket_no_service.go b/internal/services/ticket_no_service.go index 55a0a88..415b056 100644 --- a/internal/services/ticket_no_service.go +++ b/internal/services/ticket_no_service.go @@ -1,8 +1,8 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "fmt" "strings" "sync" diff --git a/internal/services/ticket_progress_service.go b/internal/services/ticket_progress_service.go index 26e4a65..511db97 100644 --- a/internal/services/ticket_progress_service.go +++ b/internal/services/ticket_progress_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/ticket_service.go b/internal/services/ticket_service.go index 7b6a397..a5abfde 100644 --- a/internal/services/ticket_service.go +++ b/internal/services/ticket_service.go @@ -5,18 +5,18 @@ import ( "strings" "time" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" "gorm.io/gorm" @@ -33,7 +33,7 @@ type TicketDetailAggregate struct { Tags []models.Tag Customer *models.Customer Progresses []models.TicketProgress - Users map[int64]*models.User + Users map[int64]*ExternalUser } type TicketSummaryAggregate struct { @@ -50,7 +50,7 @@ type TicketListAggregate struct { List []models.Ticket Paging *sqls.Paging TagsByTicketID map[int64][]models.Tag - Users map[int64]*models.User + Users map[int64]*ExternalUser Customers map[int64]*models.Customer } @@ -66,7 +66,7 @@ func normalizeTicketStaleHours(staleHours int) int { } } -func buildTicketAssignmentProgressContent(fromUser *models.User, toUser *models.User, reason string) string { +func buildTicketAssignmentProgressContent(fromUser *ExternalUser, toUser *ExternalUser, reason string) string { fromName := ticketAssignmentUserDisplayName(fromUser) if fromName == "" { fromName = "未分配" @@ -82,7 +82,7 @@ func buildTicketAssignmentProgressContent(fromUser *models.User, toUser *models. return content } -func ticketAssignmentUserDisplayName(user *models.User) string { +func ticketAssignmentUserDisplayName(user *ExternalUser) string { if user == nil { return "" } @@ -445,7 +445,7 @@ func (s *ticketService) GetDetail(id int64) (*TicketDetailAggregate, error) { Ticket: ticket, Tags: s.GetTags(id), Progresses: repositories.TicketProgressRepository.Find(sqls.DB(), sqls.NewCnd().Eq("ticket_id", id).Asc("id")), - Users: make(map[int64]*models.User), + Users: make(map[int64]*ExternalUser), } if ticket.CustomerID > 0 { aggregate.Customer = CustomerService.Get(ticket.CustomerID) @@ -467,7 +467,7 @@ func (s *ticketService) GetDetail(id int64) (*TicketDetailAggregate, error) { addUserID(aggregate.Progresses[i].AuthorID) } if len(userIDs) > 0 { - users := repositories.UserRepository.FindByIds(sqls.DB(), userIDs) + users := UserService.FindByIds(userIDs) for i := range users { item := users[i] aggregate.Users[item.ID] = &item @@ -503,13 +503,13 @@ func (s *ticketService) assignTicketTx(tx *gorm.DB, req request.AssignTicketRequ if err := s.validateRequiredAssignee(req.ToUserID); err != nil { return nil, err } - toUser := repositories.UserRepository.Get(tx, req.ToUserID) + toUser := UserService.Get(req.ToUserID) if toUser == nil || toUser.Status != enums.StatusOk { return nil, errorsx.InvalidParamI18n("error.e0334") } - var fromUser *models.User + var fromUser *ExternalUser if ticket.CurrentAssigneeID > 0 { - fromUser = repositories.UserRepository.Get(tx, ticket.CurrentAssigneeID) + fromUser = UserService.Get(ticket.CurrentAssigneeID) } now := time.Now() if err := repositories.TicketRepository.Updates(tx, ticket.ID, map[string]any{ @@ -542,7 +542,7 @@ func (s *ticketService) buildTicketListAggregate(db *gorm.DB, list []models.Tick List: list, Paging: paging, TagsByTicketID: make(map[int64][]models.Tag), - Users: make(map[int64]*models.User), + Users: make(map[int64]*ExternalUser), Customers: make(map[int64]*models.Customer), } if len(list) == 0 { @@ -575,7 +575,7 @@ func (s *ticketService) buildTicketListAggregate(db *gorm.DB, list []models.Tick } s.enrichTicketTags(db, aggregate, ticketIDs) if len(userIDs) > 0 { - users := repositories.UserRepository.FindByIds(db, userIDs) + users := UserService.FindByIds(userIDs) for i := range users { item := users[i] aggregate.Users[item.ID] = &item diff --git a/internal/services/ticket_service_test.go b/internal/services/ticket_service_test.go index 7333139..f00bc43 100644 --- a/internal/services/ticket_service_test.go +++ b/internal/services/ticket_service_test.go @@ -9,16 +9,16 @@ import ( "testing" "time" - "agent-desk/internal/bootstrap" - "agent-desk/internal/events" - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/eventbus" - "agent-desk/internal/repositories" - "agent-desk/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/bootstrap" + "code.tczkiot.com/wlw/ai-agent/internal/events" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/eventbus" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/services" "github.com/mlogclub/simple/sqls" ) @@ -632,25 +632,10 @@ func createTestUser(t *testing.T, prefix string) int64 { func createTestUserWithStatus(t *testing.T, prefix string, status enums.Status) int64 { t.Helper() - now := time.Now() - username := fmt.Sprintf("%s_%d", prefix, now.UnixNano()) - user := &models.User{ - Username: username, - Nickname: prefix, - Status: status, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: 1, - CreateUserName: "admin", - UpdatedAt: now, - UpdateUserID: 1, - UpdateUserName: "admin", - }, - } - if err := repositories.UserRepository.Create(sqls.DB(), user); err != nil { - t.Fatalf("create user error = %v", err) - } - return user.ID + id := time.Now().UnixNano() + username := fmt.Sprintf("%s_%d", prefix, id) + registerTestExternalSubject(id, username, prefix, status) + return id } func createTestConversation(t *testing.T, customerID int64, prefix string) int64 { diff --git a/internal/services/ticket_tag_service.go b/internal/services/ticket_tag_service.go index d597601..bee368d 100644 --- a/internal/services/ticket_tag_service.go +++ b/internal/services/ticket_tag_service.go @@ -1,11 +1,11 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "time" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/ticket_view_service.go b/internal/services/ticket_view_service.go index 6e616ea..9cbaa7e 100644 --- a/internal/services/ticket_view_service.go +++ b/internal/services/ticket_view_service.go @@ -5,12 +5,12 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/request" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/tool_catalog_service.go b/internal/services/tool_catalog_service.go index 04368f8..24f207a 100644 --- a/internal/services/tool_catalog_service.go +++ b/internal/services/tool_catalog_service.go @@ -5,12 +5,12 @@ import ( "slices" "strings" - "agent-desk/internal/ai/mcps" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/toolx" + "code.tczkiot.com/wlw/ai-agent/internal/ai/mcps" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx" ) var ToolCatalogService = newToolCatalogService() diff --git a/internal/services/user_identity_service.go b/internal/services/user_identity_service.go deleted file mode 100644 index 556eea5..0000000 --- a/internal/services/user_identity_service.go +++ /dev/null @@ -1,67 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var UserIdentityService = newUserIdentityService() - -func newUserIdentityService() *userIdentityService { - return &userIdentityService{} -} - -type userIdentityService struct { -} - -func (s *userIdentityService) Get(id int64) *models.UserIdentity { - return repositories.UserIdentityRepository.Get(sqls.DB(), id) -} - -func (s *userIdentityService) Take(where ...interface{}) *models.UserIdentity { - return repositories.UserIdentityRepository.Take(sqls.DB(), where...) -} - -func (s *userIdentityService) Find(cnd *sqls.Cnd) []models.UserIdentity { - return repositories.UserIdentityRepository.Find(sqls.DB(), cnd) -} - -func (s *userIdentityService) FindOne(cnd *sqls.Cnd) *models.UserIdentity { - return repositories.UserIdentityRepository.FindOne(sqls.DB(), cnd) -} - -func (s *userIdentityService) FindPageByParams(params *params.QueryParams) (list []models.UserIdentity, paging *sqls.Paging) { - return repositories.UserIdentityRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *userIdentityService) FindPageByCnd(cnd *sqls.Cnd) (list []models.UserIdentity, paging *sqls.Paging) { - return repositories.UserIdentityRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *userIdentityService) Count(cnd *sqls.Cnd) int64 { - return repositories.UserIdentityRepository.Count(sqls.DB(), cnd) -} - -func (s *userIdentityService) Create(t *models.UserIdentity) error { - return repositories.UserIdentityRepository.Create(sqls.DB(), t) -} - -func (s *userIdentityService) Update(t *models.UserIdentity) error { - return repositories.UserIdentityRepository.Update(sqls.DB(), t) -} - -func (s *userIdentityService) Updates(id int64, columns map[string]interface{}) error { - return repositories.UserIdentityRepository.Updates(sqls.DB(), id, columns) -} - -func (s *userIdentityService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.UserIdentityRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *userIdentityService) Delete(id int64) { - repositories.UserIdentityRepository.Delete(sqls.DB(), id) -} diff --git a/internal/services/user_permission_service.go b/internal/services/user_permission_service.go deleted file mode 100644 index f49edd6..0000000 --- a/internal/services/user_permission_service.go +++ /dev/null @@ -1,67 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var UserPermissionService = newUserPermissionService() - -func newUserPermissionService() *userPermissionService { - return &userPermissionService{} -} - -type userPermissionService struct { -} - -func (s *userPermissionService) Get(id int64) *models.UserPermission { - return repositories.UserPermissionRepository.Get(sqls.DB(), id) -} - -func (s *userPermissionService) Take(where ...interface{}) *models.UserPermission { - return repositories.UserPermissionRepository.Take(sqls.DB(), where...) -} - -func (s *userPermissionService) Find(cnd *sqls.Cnd) []models.UserPermission { - return repositories.UserPermissionRepository.Find(sqls.DB(), cnd) -} - -func (s *userPermissionService) FindOne(cnd *sqls.Cnd) *models.UserPermission { - return repositories.UserPermissionRepository.FindOne(sqls.DB(), cnd) -} - -func (s *userPermissionService) FindPageByParams(params *params.QueryParams) (list []models.UserPermission, paging *sqls.Paging) { - return repositories.UserPermissionRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *userPermissionService) FindPageByCnd(cnd *sqls.Cnd) (list []models.UserPermission, paging *sqls.Paging) { - return repositories.UserPermissionRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *userPermissionService) Count(cnd *sqls.Cnd) int64 { - return repositories.UserPermissionRepository.Count(sqls.DB(), cnd) -} - -func (s *userPermissionService) Create(t *models.UserPermission) error { - return repositories.UserPermissionRepository.Create(sqls.DB(), t) -} - -func (s *userPermissionService) Update(t *models.UserPermission) error { - return repositories.UserPermissionRepository.Update(sqls.DB(), t) -} - -func (s *userPermissionService) Updates(id int64, columns map[string]interface{}) error { - return repositories.UserPermissionRepository.Updates(sqls.DB(), id, columns) -} - -func (s *userPermissionService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.UserPermissionRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *userPermissionService) Delete(id int64) { - repositories.UserPermissionRepository.Delete(sqls.DB(), id) -} diff --git a/internal/services/user_role_service.go b/internal/services/user_role_service.go deleted file mode 100644 index 164f93e..0000000 --- a/internal/services/user_role_service.go +++ /dev/null @@ -1,67 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" - - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" -) - -var UserRoleService = newUserRoleService() - -func newUserRoleService() *userRoleService { - return &userRoleService{} -} - -type userRoleService struct { -} - -func (s *userRoleService) Get(id int64) *models.UserRole { - return repositories.UserRoleRepository.Get(sqls.DB(), id) -} - -func (s *userRoleService) Take(where ...interface{}) *models.UserRole { - return repositories.UserRoleRepository.Take(sqls.DB(), where...) -} - -func (s *userRoleService) Find(cnd *sqls.Cnd) []models.UserRole { - return repositories.UserRoleRepository.Find(sqls.DB(), cnd) -} - -func (s *userRoleService) FindOne(cnd *sqls.Cnd) *models.UserRole { - return repositories.UserRoleRepository.FindOne(sqls.DB(), cnd) -} - -func (s *userRoleService) FindPageByParams(params *params.QueryParams) (list []models.UserRole, paging *sqls.Paging) { - return repositories.UserRoleRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *userRoleService) FindPageByCnd(cnd *sqls.Cnd) (list []models.UserRole, paging *sqls.Paging) { - return repositories.UserRoleRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *userRoleService) Count(cnd *sqls.Cnd) int64 { - return repositories.UserRoleRepository.Count(sqls.DB(), cnd) -} - -func (s *userRoleService) Create(t *models.UserRole) error { - return repositories.UserRoleRepository.Create(sqls.DB(), t) -} - -func (s *userRoleService) Update(t *models.UserRole) error { - return repositories.UserRoleRepository.Update(sqls.DB(), t) -} - -func (s *userRoleService) Updates(id int64, columns map[string]interface{}) error { - return repositories.UserRoleRepository.Updates(sqls.DB(), id, columns) -} - -func (s *userRoleService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.UserRoleRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *userRoleService) Delete(id int64) { - repositories.UserRoleRepository.Delete(sqls.DB(), id) -} diff --git a/internal/services/user_service.go b/internal/services/user_service.go index e62285b..009aae1 100644 --- a/internal/services/user_service.go +++ b/internal/services/user_service.go @@ -1,299 +1,80 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/request" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "slices" - "strings" - "time" + "context" - "agent-desk/internal/pkg/httpx/params" - - "github.com/mlogclub/simple/sqls" - "golang.org/x/crypto/bcrypt" - "gorm.io/gorm" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" ) -var UserService = newUserService() - -func newUserService() *userService { - return &userService{} +// ExternalUser is a non-persistent display adapter for a system identity owned +// by be-system. +type ExternalUser struct { + ID int64 + SubjectType identity.SubjectType + Username string + Nickname string + Avatar string + Status enums.Status } -type userService struct { -} +var UserService = &externalUserService{} -func (s *userService) Get(id int64) *models.User { - return repositories.UserRepository.Get(sqls.DB(), id) -} +type externalUserService struct{} -func (s *userService) Take(where ...interface{}) *models.User { - return repositories.UserRepository.Take(sqls.DB(), where...) -} - -func (s *userService) Find(cnd *sqls.Cnd) []models.User { - return repositories.UserRepository.Find(sqls.DB(), cnd) -} - -func (s *userService) FindOne(cnd *sqls.Cnd) *models.User { - return repositories.UserRepository.FindOne(sqls.DB(), cnd) -} - -func (s *userService) FindPageByParams(params *params.QueryParams) (list []models.User, paging *sqls.Paging) { - return repositories.UserRepository.FindPageByParams(sqls.DB(), params) -} - -func (s *userService) FindPageByCnd(cnd *sqls.Cnd) (list []models.User, paging *sqls.Paging) { - return repositories.UserRepository.FindPageByCnd(sqls.DB(), cnd) -} - -func (s *userService) Count(cnd *sqls.Cnd) int64 { - return repositories.UserRepository.Count(sqls.DB(), cnd) -} - -func (s *userService) FindByIds(ids []int64) []models.User { - return repositories.UserRepository.FindByIds(sqls.DB(), ids) -} - -func (s *userService) Create(t *models.User) error { - return repositories.UserRepository.Create(sqls.DB(), t) -} - -func (s *userService) Update(t *models.User) error { - return repositories.UserRepository.Update(sqls.DB(), t) -} - -func (s *userService) Updates(id int64, columns map[string]interface{}) error { - return repositories.UserRepository.Updates(sqls.DB(), id, columns) -} - -func (s *userService) UpdateColumn(id int64, name string, value interface{}) error { - return repositories.UserRepository.UpdateColumn(sqls.DB(), id, name, value) -} - -func (s *userService) GetByUsername(username string) *models.User { - return repositories.UserRepository.GetByUsername(sqls.DB(), username) -} - -func (s *userService) GetByMobile(mobile string) *models.User { - return repositories.UserRepository.GetByMobile(sqls.DB(), mobile) -} - -func (s *userService) GetByEmail(email string) *models.User { - return repositories.UserRepository.GetByEmail(sqls.DB(), email) -} - -func (s *userService) CreateUser(req request.CreateUserRequest, operator *dto.AuthPrincipal) (*models.User, string, error) { - username := strings.TrimSpace(req.Username) - if username == "" { - return nil, "", errorsx.InvalidParamI18n("error.e0257") - } - if s.GetByUsername(username) != nil { - return nil, "", errorsx.InvalidParamI18n("error.e0259") +func (s *externalUserService) Get(id int64) *ExternalUser { + items := s.FindByIds([]int64{id}) + if len(items) == 0 { + return nil } + return &items[0] +} - mobile := utils.NormalizeNullableString(req.Mobile) - email := utils.NormalizeNullableString(req.Email) - if mobile != nil && s.GetByMobile(*mobile) != nil { - return nil, "", errorsx.InvalidParamI18n("error.e0206") +func (s *externalUserService) FindByIds(ids []int64) []ExternalUser { + if len(ids) == 0 { + return nil } - if email != nil && s.GetByEmail(*email) != nil { - return nil, "", errorsx.InvalidParamI18n("error.e0338") - } - - plain, err := utils.GenerateRandomPassword(12) - if err != nil { - return nil, "", err - } - passwordHash, err := bcrypt.GenerateFromPassword([]byte(plain), bcrypt.DefaultCost) - if err != nil { - return nil, "", err - } - - user := &models.User{ - Username: username, - Nickname: strings.TrimSpace(req.Nickname), - Password: string(passwordHash), - Avatar: strings.TrimSpace(req.Avatar), - Mobile: mobile, - Email: email, - Status: enums.StatusOk, - Remark: strings.TrimSpace(req.Remark), - PasswordSalt: "", - AuditFields: utils.BuildAuditFields(operator), - } - if user.Nickname == "" { - user.Nickname = username - } - - err = sqls.WithTransaction(func(ctx *sqls.TxContext) error { - if err := repositories.UserRepository.Create(ctx.Tx, user); err != nil { - return err - } - return s.replaceUserRolesDB(ctx.Tx, user.ID, req.RoleIDs, operator) + subjects, err := SubjectService.Query(context.Background(), identity.Query{ + Types: []identity.SubjectType{identity.SubjectAgent}, + IDs: ids, + EnabledOnly: true, }) if err != nil { - return nil, "", err + return nil } - return user, plain, nil + users := make([]ExternalUser, 0, len(subjects)) + for _, subject := range subjects { + status := enums.StatusDisabled + if subject.Enabled { + status = enums.StatusOk + } + users = append(users, ExternalUser{ + ID: subject.ID, + SubjectType: subject.Type, + Username: subject.Username, + Nickname: subject.Name, + Avatar: subject.Avatar, + Status: status, + }) + } + return users } -func (s *userService) UpdateUser(req request.UpdateUserRequest, operator *dto.AuthPrincipal) error { - user := s.Get(req.ID) - if user == nil || user.DeletedAt != nil { - return errorsx.InvalidParamI18n("error.e0255") - } - - mobile := utils.NormalizeNullableString(req.Mobile) - email := utils.NormalizeNullableString(req.Email) - if mobile != nil { - if existed := s.GetByMobile(*mobile); existed != nil && existed.ID != req.ID { - return errorsx.InvalidParamI18n("error.e0206") - } - } - if email != nil { - if existed := s.GetByEmail(*email); existed != nil && existed.ID != req.ID { - return errorsx.InvalidParamI18n("error.e0338") - } - } - - return s.Updates(req.ID, map[string]any{ - "nickname": strings.TrimSpace(req.Nickname), - "avatar": strings.TrimSpace(req.Avatar), - "mobile": mobile, - "email": email, - "remark": strings.TrimSpace(req.Remark), - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": time.Now(), +func (s *externalUserService) Find(keyword string) []ExternalUser { + subjects, err := SubjectService.Query(context.Background(), identity.Query{ + Types: []identity.SubjectType{identity.SubjectAgent}, + Keyword: keyword, + EnabledOnly: true, }) -} - -func (s *userService) DeleteUser(id int64, operator *dto.AuthPrincipal) error { - user := s.Get(id) - if user == nil { - return errorsx.InvalidParamI18n("error.e0255") - } - - if err := s.Updates(id, map[string]any{ - "status": enums.StatusDisabled, - "deleted_at": time.Now(), - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - return LoginSessionService.RevokeByUser(id, operator.UserID, operator.Username) -} - -func (s *userService) UpdateStatus(id int64, status int, operator *dto.AuthPrincipal) error { - user := s.Get(id) - if user == nil { - return errorsx.InvalidParamI18n("error.e0255") - } - if !slices.Contains(enums.StatusValues, enums.Status(status)) { - return errorsx.InvalidParamI18n("error.e0254") - } - if err := s.Updates(id, map[string]any{ - "status": status, - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - if status == int(enums.StatusDisabled) || status == int(enums.StatusDeleted) { - return LoginSessionService.RevokeByUser(id, operator.UserID, operator.Username) - } - return nil -} - -func (s *userService) ResetPassword(userID int64, operator *dto.AuthPrincipal) (string, error) { - password, err := utils.GenerateRandomPassword(12) if err != nil { - return "", err + return nil } - if err = s.changePassword(userID, password, operator); err != nil { - return "", err + users := make([]ExternalUser, 0, len(subjects)) + for _, subject := range subjects { + users = append(users, ExternalUser{ + ID: subject.ID, SubjectType: subject.Type, Username: subject.Username, + Nickname: subject.Name, Avatar: subject.Avatar, Status: enums.StatusOk, + }) } - return password, nil -} - -func (s *userService) ChangeOwnPassword(password string, operator *dto.AuthPrincipal) error { - if operator == nil || operator.UserID <= 0 { - return errorsx.UnauthorizedI18n("error.auth.expired") - } - return s.changePassword(operator.UserID, password, operator) -} - -func (s *userService) AssignRoles(userID int64, roleIDs []int64, operator *dto.AuthPrincipal) error { - user := s.Get(userID) - if user == nil || user.DeletedAt != nil { - return errorsx.InvalidParamI18n("error.e0255") - } - if err := s.replaceUserRoles(userID, roleIDs, operator); err != nil { - return err - } - return LoginSessionService.RevokeByUser(userID, operator.UserID, operator.Username) -} - -func (s *userService) replaceUserRoles(userID int64, roleIDs []int64, operator *dto.AuthPrincipal) error { - return sqls.WithTransaction(func(ctx *sqls.TxContext) error { - return s.replaceUserRolesDB(ctx.Tx, userID, roleIDs, operator) - }) -} - -func (s *userService) replaceUserRolesDB(db *gorm.DB, userID int64, roleIDs []int64, operator *dto.AuthPrincipal) error { - if err := db.Where("user_id = ?", userID).Delete(&models.UserRole{}).Error; err != nil { - return err - } - for _, roleID := range roleIDs { - role := RoleService.Get(roleID) - if role == nil { - return errorsx.InvalidParamI18n("error.e0305") - } - if role.Status != enums.StatusOk { - return errorsx.InvalidParamI18n("error.e0291") - } - relation := &models.UserRole{ - UserID: userID, - RoleID: roleID, - AuditFields: utils.BuildAuditFields(operator), - } - if err := db.Create(relation).Error; err != nil { - return err - } - } - return nil -} - -func (s *userService) changePassword(userID int64, password string, operator *dto.AuthPrincipal) error { - user := s.Get(userID) - if user == nil || user.DeletedAt != nil { - return errorsx.InvalidParamI18n("error.e0255") - } - if strings.TrimSpace(password) == "" { - return errorsx.InvalidParamI18n("error.e0220") - } - - passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) - if err != nil { - return err - } - now := time.Now() - if err = s.Updates(userID, map[string]any{ - "password": string(passwordHash), - "update_user_id": operator.UserID, - "update_user_name": operator.Username, - "updated_at": now, - }); err != nil { - return err - } - return LoginSessionService.RevokeByUser(userID, operator.UserID, operator.Username) + return users } diff --git a/internal/services/ws_realtime_types.go b/internal/services/ws_realtime_types.go index 1481384..a9c00c1 100644 --- a/internal/services/ws_realtime_types.go +++ b/internal/services/ws_realtime_types.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" "encoding/json" "sync" "sync/atomic" @@ -238,25 +238,6 @@ func (e RealtimeNotificationCreatedEvent) EventPayload() RealtimeEventPayload { return e.Payload } -type RealtimeCustomerSessionRefreshPayload struct { - CustomerSessionToken string `json:"customerSessionToken"` - ExpiresAt string `json:"expiresAt"` -} - -func (RealtimeCustomerSessionRefreshPayload) realtimeEventPayload() {} - -type RealtimeCustomerSessionRefreshEvent struct { - Payload RealtimeCustomerSessionRefreshPayload -} - -func (e RealtimeCustomerSessionRefreshEvent) EventType() string { - return enums.IMRealtimeEventCustomerSessionRefresh -} - -func (e RealtimeCustomerSessionRefreshEvent) EventPayload() RealtimeEventPayload { - return e.Payload -} - type realtimeClientMessage struct { Type string `json:"type"` Topics []string `json:"topics,omitempty"` diff --git a/internal/services/ws_service.go b/internal/services/ws_service.go index 2f37acc..d7606a0 100644 --- a/internal/services/ws_service.go +++ b/internal/services/ws_service.go @@ -1,14 +1,14 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/dto" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" "encoding/json" "fmt" "log/slog" @@ -76,27 +76,25 @@ func (s *wsService) HandleOpenWS(ctx *gin.Context) { } var ( - principal = AuthService.GetAuthPrincipal(ctx) - external *openidentity.ExternalUser - customerSessionInfo *CustomerSessionVerifyResult + principal = AuthService.GetAuthPrincipal(ctx) + external *openidentity.ExternalUser ) if principal == nil { - result, err := CustomerSessionService.VerifyRequest(ctx, channel) + var err error + external, err = SubjectService.CurrentExternal(ctx.Request.Context()) if err != nil { ctx.AbortWithStatusJSON(http.StatusUnauthorized, web.JsonError(err)) return } - external = result.ExternalUser - customerSessionInfo = result } - if err := s.upgradeConnection(ctx, principal, external, realtimeRoleUser, customerSessionInfo); err != nil { + if err := s.upgradeConnection(ctx, principal, external, realtimeRoleUser); err != nil { slog.Error("upgrade open im websocket failed", "error", err, "path", ctx.Request.URL.Path, "channelId", channel.ChannelID, "channel_id", channel.ID) ctx.Abort() return } } -func (s *wsService) upgradeConnection(ctx *gin.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalUser, role string, customerSessionInfo ...*CustomerSessionVerifyResult) error { +func (s *wsService) upgradeConnection(ctx *gin.Context, principal *dto.AuthPrincipal, external *openidentity.ExternalUser, role string) error { conn, err := s.upgrader.Upgrade(ctx.Writer, ctx.Request, nil) if err != nil { return err @@ -154,14 +152,6 @@ func (s *wsService) upgradeConnection(ctx *gin.Context, principal *dto.AuthPrinc Topics: session.topicList(), }, })) - if len(customerSessionInfo) > 0 && customerSessionInfo[0] != nil && customerSessionInfo[0].Refreshed { - session.enqueueEvent(s.newEvent("", RealtimeCustomerSessionRefreshEvent{ - Payload: RealtimeCustomerSessionRefreshPayload{ - CustomerSessionToken: customerSessionInfo[0].Token, - ExpiresAt: customerSessionInfo[0].ExpiresAt.Format(time.DateTime), - }, - })) - } return nil } diff --git a/internal/services/ws_service_test.go b/internal/services/ws_service_test.go index d65f817..36cbcf5 100644 --- a/internal/services/ws_service_test.go +++ b/internal/services/ws_service_test.go @@ -3,7 +3,7 @@ package services import ( "testing" - "agent-desk/internal/pkg/dto/response" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response" ) func TestWsNotificationTopic(t *testing.T) { diff --git a/internal/services/wx_callback_handlers/kf_msg_or_event_handler.go b/internal/services/wx_callback_handlers/kf_msg_or_event_handler.go index b465aee..9af4ec3 100644 --- a/internal/services/wx_callback_handlers/kf_msg_or_event_handler.go +++ b/internal/services/wx_callback_handlers/kf_msg_or_event_handler.go @@ -1,8 +1,8 @@ package wx_callback_handlers import ( - "agent-desk/internal/services" - "agent-desk/internal/wxwork" + "code.tczkiot.com/wlw/ai-agent/internal/services" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "log/slog" "github.com/silenceper/wechat/v2/work/kf" diff --git a/internal/services/wx_work_kf_conversation_service.go b/internal/services/wx_work_kf_conversation_service.go index 707d763..03eae20 100644 --- a/internal/services/wx_work_kf_conversation_service.go +++ b/internal/services/wx_work_kf_conversation_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/wx_work_kf_message_ref_service.go b/internal/services/wx_work_kf_message_ref_service.go index 30735c8..b2a7ac9 100644 --- a/internal/services/wx_work_kf_message_ref_service.go +++ b/internal/services/wx_work_kf_message_ref_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/wx_work_kf_sync_state_service.go b/internal/services/wx_work_kf_sync_state_service.go index d6d554b..3090aab 100644 --- a/internal/services/wx_work_kf_sync_state_service.go +++ b/internal/services/wx_work_kf_sync_state_service.go @@ -1,10 +1,10 @@ package services import ( - "agent-desk/internal/models" - "agent-desk/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" - "agent-desk/internal/pkg/httpx/params" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx/params" "github.com/mlogclub/simple/sqls" ) diff --git a/internal/services/wxwork_kf_inbound_service.go b/internal/services/wxwork_kf_inbound_service.go index 79d085f..a55084a 100644 --- a/internal/services/wxwork_kf_inbound_service.go +++ b/internal/services/wxwork_kf_inbound_service.go @@ -6,11 +6,11 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/openidentity" - "agent-desk/internal/wxwork" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/errorsx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/openidentity" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "github.com/mlogclub/simple/common/strs" "github.com/silenceper/wechat/v2/work/kf" diff --git a/internal/services/wxwork_kf_outbound_service.go b/internal/services/wxwork_kf_outbound_service.go index e2f428a..5e7e7a8 100644 --- a/internal/services/wxwork_kf_outbound_service.go +++ b/internal/services/wxwork_kf_outbound_service.go @@ -7,12 +7,12 @@ import ( "strings" "time" - "agent-desk/internal/models" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/i18nx" - "agent-desk/internal/pkg/utils" - "agent-desk/internal/repositories" - "agent-desk/internal/wxwork" + "code.tczkiot.com/wlw/ai-agent/internal/models" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/enums" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/utils" + "code.tczkiot.com/wlw/ai-agent/internal/repositories" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "github.com/mlogclub/simple/common/strs" "github.com/mlogclub/simple/sqls" diff --git a/internal/services/wxwork_login_service.go b/internal/services/wxwork_login_service.go deleted file mode 100644 index bb3cee9..0000000 --- a/internal/services/wxwork_login_service.go +++ /dev/null @@ -1,246 +0,0 @@ -package services - -import ( - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/repositories" - "agent-desk/internal/wxwork" - "strings" - "time" - - "github.com/mlogclub/simple/common/jsons" - "github.com/mlogclub/simple/common/strs" - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" -) - -var WxWorkLoginService = &wxWorkLoginService{} - -type wxWorkLoginService struct { -} - -func (s *wxWorkLoginService) BuildWxWorkLoginURL(next string) (string, error) { - if !wxwork.Enabled() { - return "", errorsx.BusinessErrorI18n(1, "error.wxwork.loginDisabled") - } - state, err := wxwork.CreateState(next) - if err != nil { - return "", err - } - return wxwork.BuildLoginURL(state) -} - -func (s *wxWorkLoginService) BuildWxWorkQRCodeLoginURL(next string) (string, error) { - if !wxwork.Enabled() { - return "", errorsx.BusinessErrorI18n(1, "error.wxwork.loginDisabled") - } - state, err := wxwork.CreateState(next) - if err != nil { - return "", err - } - return wxwork.BuildQRCodeLoginURL(state) -} - -func (s *wxWorkLoginService) LoginByWxWork(code, state string, authCfg config.AuthConfig, clientIP, userAgent string) (string, string, error) { - next, err := wxwork.ParseState(state) - if err != nil { - return "", "", errorsx.UnauthorizedI18n("error.e0111") - } - profile, err := wxwork.GetUserDetail(code) - if err != nil { - return "", "", err - } - loginResp, err := s.loginWithWxWorkProfile(profile, authCfg, clientIP, userAgent) - if err != nil { - return "", "", err - } - ticket, err := wxwork.IssueLoginTicket(loginResp) - if err != nil { - return "", "", err - } - return ticket, next, nil -} - -func (s *wxWorkLoginService) ExchangeWxWorkLoginTicket(ticket string) (*response.LoginResponse, error) { - return wxwork.ConsumeLoginTicket(ticket) -} - -func (s *wxWorkLoginService) loginWithWxWorkProfile(profile *wxwork.LoginUser, authCfg config.AuthConfig, clientIP, userAgent string) (*response.LoginResponse, error) { - if profile == nil || strings.TrimSpace(profile.UserID) == "" { - return nil, errorsx.BusinessErrorI18n(2, "error.wxwork.profileMissing") - } - - var ret *response.LoginResponse - err := sqls.WithTransaction(func(ctx *sqls.TxContext) error { - var ( - identity = repositories.UserIdentityRepository.GetBy(ctx.Tx, enums.ThirdProviderWxWork, profile.CorpID, profile.UserID) - user *models.User - err error - ) - if identity == nil { - user, identity, err = s.createWxWorkUser(ctx, profile) - if err != nil { - return err - } - } else { - if identity.Status != enums.StatusOk { - return errorsx.BusinessErrorI18n(3, "error.wxwork.bindingDisabled") - } - user = repositories.UserRepository.Get(ctx.Tx, identity.UserID) - if user == nil { - return errorsx.BusinessErrorI18n(4, "error.wxwork.boundUserMissing") - } - } - - if user.Status != enums.StatusOk { - return errorsx.UnauthorizedI18n("error.e0200") - } - - if err = repositories.UserRepository.Updates(ctx.Tx, user.ID, map[string]any{ - "nickname": s.resolveWxWorkNickname(user.Nickname, profile), - "avatar": s.resolveWxWorkAvatar(user.Avatar, profile), - "last_login_at": time.Now(), - "last_login_ip": clientIP, - "update_user_id": user.ID, - "update_user_name": user.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - - if err = repositories.UserIdentityRepository.Updates(ctx.Tx, identity.ID, map[string]any{ - "raw_profile": jsons.ToJsonStr(profile), - "last_auth_at": time.Now(), - "status": enums.StatusOk, - "update_user_id": user.ID, - "update_user_name": user.Username, - "updated_at": time.Now(), - }); err != nil { - return err - } - - ret, err = AuthService.issueTokens(ctx, user, clientIP, userAgent, authCfg) - if err != nil { - return err - } - return nil - }) - - if err != nil { - return nil, err - } - return ret, nil -} - -func (s *wxWorkLoginService) createWxWorkUser(ctx *sqls.TxContext, profile *wxwork.LoginUser) (*models.User, *models.UserIdentity, error) { - username := strings.TrimSpace(profile.UserID) - mobile := strings.TrimSpace(profile.Mobile) - email := strings.TrimSpace(s.firstNonEmpty(profile.Email, profile.BizMail)) - now := time.Now() - - if err := s.checkWxWorkProfile(ctx.Tx, username, mobile, email); err != nil { - return nil, nil, err - } - - user := &models.User{ - Username: username, - Nickname: s.resolveWxWorkNickname("", profile), - Avatar: s.resolveWxWorkAvatar("", profile), - Password: "", - PasswordSalt: "", - Status: enums.StatusOk, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: 0, - CreateUserName: enums.GetThirdProviderLabel(enums.ThirdProviderWxWork), - UpdatedAt: now, - UpdateUserID: 0, - UpdateUserName: enums.GetThirdProviderLabel(enums.ThirdProviderWxWork), - }, - } - if err := repositories.UserRepository.Create(ctx.Tx, user); err != nil { - return nil, nil, err - } - - identity := &models.UserIdentity{ - UserID: user.ID, - Provider: enums.ThirdProviderWxWork, - ProviderUserID: strings.TrimSpace(profile.UserID), - ProviderCorpID: strings.TrimSpace(profile.CorpID), - ProviderName: enums.GetThirdProviderLabel(enums.ThirdProviderWxWork), - RawProfile: jsons.ToJsonStr(profile), - Status: enums.StatusOk, - LastAuthAt: &now, - AuditFields: models.AuditFields{ - CreatedAt: now, - CreateUserID: user.ID, - CreateUserName: user.Username, - UpdatedAt: now, - UpdateUserID: user.ID, - UpdateUserName: user.Username, - }, - } - if unionID := strings.TrimSpace(profile.OpenID); unionID != "" { - identity.ProviderUnionID = &unionID - } - if err := repositories.UserIdentityRepository.Create(ctx.Tx, identity); err != nil { - return nil, nil, err - } - return user, identity, nil -} - -func (s *wxWorkLoginService) resolveWxWorkNickname(current string, profile *wxwork.LoginUser) string { - if profile != nil { - if name := strings.TrimSpace(profile.Name); name != "" { - return name - } - } - if current = strings.TrimSpace(current); current != "" { - return current - } - if profile != nil { - return strings.TrimSpace(profile.UserID) - } - return "" -} - -func (s *wxWorkLoginService) resolveWxWorkAvatar(current string, profile *wxwork.LoginUser) string { - if profile != nil { - if avatar := strings.TrimSpace(profile.Avatar); avatar != "" { - return avatar - } - } - return strings.TrimSpace(current) -} - -func (s *wxWorkLoginService) checkWxWorkProfile(tx *gorm.DB, username, mobile string, email string) error { - if strs.IsBlank(username) { - return errorsx.BusinessErrorI18n(5, "error.wxwork.userIDMissing") - } - if existing := repositories.UserRepository.GetByUsername(tx, username); existing != nil { - return errorsx.BusinessErrorI18n(5, "error.wxwork.userIDTaken") - } - if strs.IsNotBlank(mobile) { - if repositories.UserRepository.GetByMobile(tx, mobile) != nil { - return errorsx.BusinessErrorI18n(6, "error.wxwork.mobileTaken") - } - } - if strs.IsNotBlank(email) { - if repositories.UserRepository.GetByEmail(tx, email) != nil { - return errorsx.BusinessErrorI18n(7, "error.wxwork.emailTaken") - } - } - return nil -} - -func (s *wxWorkLoginService) firstNonEmpty(values ...string) string { - for _, value := range values { - if value = strings.TrimSpace(value); value != "" { - return value - } - } - return "" -} diff --git a/internal/services/wxwork_notify_service.go b/internal/services/wxwork_notify_service.go index 46355d0..29e1bd5 100644 --- a/internal/services/wxwork_notify_service.go +++ b/internal/services/wxwork_notify_service.go @@ -1,16 +1,15 @@ package services import ( + "context" "fmt" "strings" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - "agent-desk/internal/wxwork" + "code.tczkiot.com/wlw/ai-agent/identity" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/wxwork" "github.com/mlogclub/simple/common/arrs" - "github.com/mlogclub/simple/sqls" wxmessage "github.com/silenceper/wechat/v2/work/message" "github.com/spf13/cast" ) @@ -89,16 +88,17 @@ func (s *wxWorkNotifyService) resolveToUsersByUserIDs(userIDs []int64) []string if len(userIDs) == 0 { return nil } - cfg := config.Current().WxWork - identities := repositories.UserIdentityRepository.Find(sqls.DB(), sqls.NewCnd(). - Eq("provider", enums.ThirdProviderWxWork). - Eq("provider_corp_id", strings.TrimSpace(cfg.CorpID)). - Eq("status", enums.StatusOk). - In("user_id", userIDs). - Asc("id")) - toUsers := make([]string, 0, len(identities)) - for i := range identities { - if receiver := strings.TrimSpace(identities[i].ProviderUserID); receiver != "" { + subjects, err := SubjectService.Query(context.Background(), identity.Query{ + Types: []identity.SubjectType{identity.SubjectAdmin, identity.SubjectAgent}, + IDs: userIDs, + EnabledOnly: true, + }) + if err != nil { + return nil + } + toUsers := make([]string, 0, len(subjects)) + for i := range subjects { + if receiver := strings.TrimSpace(subjects[i].Bindings["wxwork"]); receiver != "" { toUsers = append(toUsers, receiver) } } diff --git a/internal/services/wxwork_notify_service_test.go b/internal/services/wxwork_notify_service_test.go deleted file mode 100644 index d2df3d6..0000000 --- a/internal/services/wxwork_notify_service_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package services - -import ( - "testing" - "time" - - "agent-desk/internal/models" - "agent-desk/internal/pkg/config" - "agent-desk/internal/pkg/enums" - "agent-desk/internal/repositories" - - "github.com/glebarez/sqlite" - "github.com/mlogclub/simple/sqls" - "gorm.io/gorm" - "gorm.io/gorm/schema" -) - -func TestWxWorkNotifyBuildTextContent(t *testing.T) { - svc := newWxWorkNotifyService() - got := svc.buildTextContent("工单提醒", "这是一条测试消息") - if got != "工单提醒\n\n这是一条测试消息" { - t.Fatalf("unexpected content: %q", got) - } -} - -func TestWxWorkNotifyDefaultRecipients(t *testing.T) { - db := setupWxWorkNotifyTestDB(t) - config.SetCurrent(&config.Config{ - WxWork: config.WxWorkConfig{ - CorpID: "corp-1", - Notify: config.WxWorkNotifyConfig{ - Enabled: true, - ToUsers: []int64{11, 11, 12}, - }, - }, - }) - now := time.Now() - for _, identity := range []*models.UserIdentity{ - { - UserID: 11, - Provider: enums.ThirdProviderWxWork, - ProviderUserID: "wx_user_a", - ProviderCorpID: "corp-1", - Status: enums.StatusOk, - LastAuthAt: &now, - }, - { - UserID: 12, - Provider: enums.ThirdProviderWxWork, - ProviderUserID: "wx_user_b", - ProviderCorpID: "corp-1", - Status: enums.StatusOk, - LastAuthAt: &now, - }, - } { - if err := repositories.UserIdentityRepository.Create(db, identity); err != nil { - t.Fatalf("create user identity error = %v", err) - } - } - - svc := newWxWorkNotifyService() - toUsers := svc.defaultToUsers() - if len(toUsers) != 2 || toUsers[0] != "wx_user_a" || toUsers[1] != "wx_user_b" { - t.Fatalf("unexpected users: %#v", toUsers) - } -} - -func TestWxWorkNotifyNormalizeDuplicateCheckInterval(t *testing.T) { - svc := newWxWorkNotifyService() - if got := svc.normalizeDuplicateCheckInterval(0); got != 1800 { - t.Fatalf("expected default interval 1800, got %d", got) - } - if got := svc.normalizeDuplicateCheckInterval(20000); got != 14400 { - t.Fatalf("expected capped interval 14400, got %d", got) - } - if got := svc.normalizeDuplicateCheckInterval(600); got != 600 { - t.Fatalf("expected interval 600, got %d", got) - } -} - -func setupWxWorkNotifyTestDB(t *testing.T) *gorm.DB { - t.Helper() - - db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{ - NamingStrategy: schema.NamingStrategy{ - TablePrefix: "t_", - SingularTable: true, - }, - }) - if err != nil { - t.Fatalf("open sqlite error = %v", err) - } - t.Cleanup(func() { - sqlDB, err := db.DB() - if err == nil { - _ = sqlDB.Close() - } - }) - if err := db.AutoMigrate(&models.UserIdentity{}); err != nil { - t.Fatalf("auto migrate error = %v", err) - } - sqls.SetDB(db) - return db -} diff --git a/internal/wxwork/login.go b/internal/wxwork/login.go deleted file mode 100644 index d7044f2..0000000 --- a/internal/wxwork/login.go +++ /dev/null @@ -1,256 +0,0 @@ -package wxwork - -import ( - "agent-desk/internal/pkg/dto/response" - "agent-desk/internal/pkg/errorsx" - "agent-desk/internal/pkg/i18nx" - "crypto/hmac" - "crypto/rand" - "crypto/sha256" - "encoding/base64" - "encoding/hex" - "encoding/json" - "fmt" - "net/url" - "strings" - "sync" - "time" - - "github.com/silenceper/wechat/v2/work/oauth" -) - -const ( - StateTTL = 5 * time.Minute - LoginTicketTTL = 1 * time.Minute - defaultLoginNextPath = "/dashboard" -) - -var ( - errStateInvalid = i18nx.Errorf("error.e0110") - loginTicketStore sync.Map -) - -type statePayload struct { - Next string `json:"next"` - Nonce string `json:"nonce"` - ExpiredAt int64 `json:"expiredAt"` -} - -type loginTicket struct { - Response *response.LoginResponse - ExpiredAt time.Time -} - -func BuildLoginURL(state string) (string, error) { - if !Enabled() { - return "", i18nx.Errorf("error.e0109") - } - if strings.TrimSpace(wxCfg.OAuthRedirect) == "" { - return "", i18nx.Errorf("error.e0107") - } - if strings.TrimSpace(wxCfg.AgentID) == "" { - return "", i18nx.Errorf("error.e0093") - } - return fmt.Sprintf( - "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_privateinfo&agentid=%s&state=%s#wechat_redirect", - url.QueryEscape(strings.TrimSpace(wxCfg.CorpID)), - url.QueryEscape(strings.TrimSpace(wxCfg.OAuthRedirect)), - url.QueryEscape(strings.TrimSpace(wxCfg.AgentID)), - url.QueryEscape(strings.TrimSpace(state)), - ), nil -} - -func BuildQRCodeLoginURL(state string) (string, error) { - if !Enabled() { - return "", i18nx.Errorf("error.e0109") - } - if strings.TrimSpace(wxCfg.OAuthRedirect) == "" { - return "", i18nx.Errorf("error.e0107") - } - if strings.TrimSpace(wxCfg.AgentID) == "" { - return "", i18nx.Errorf("error.e0093") - } - return fmt.Sprintf( - "https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%s&redirect_uri=%s&state=%s", - url.QueryEscape(strings.TrimSpace(wxCfg.CorpID)), - url.QueryEscape(strings.TrimSpace(wxCfg.AgentID)), - url.QueryEscape(strings.TrimSpace(wxCfg.OAuthRedirect)), - url.QueryEscape(strings.TrimSpace(state)), - ), nil -} - -func CreateState(next string) (string, error) { - secret := strings.TrimSpace(StateSecret()) - if secret == "" { - return "", errorsx.BusinessErrorI18n(1, "error.wxwork.loginSecretMissing") - } - payload := statePayload{ - Next: sanitizeNextPath(next), - ExpiredAt: time.Now().Add(StateTTL).Unix(), - } - nonce, err := randomToken("ws_") - if err != nil { - return "", err - } - payload.Nonce = nonce - - body, err := json.Marshal(payload) - if err != nil { - return "", err - } - encoded := base64.RawURLEncoding.EncodeToString(body) - return encoded + "." + signState(encoded, secret), nil -} - -func ParseState(state string) (string, error) { - secret := strings.TrimSpace(StateSecret()) - if secret == "" { - return "", errStateInvalid - } - parts := strings.Split(strings.TrimSpace(state), ".") - if len(parts) != 2 { - return "", errStateInvalid - } - if !hmac.Equal([]byte(parts[1]), []byte(signState(parts[0], secret))) { - return "", errStateInvalid - } - body, err := base64.RawURLEncoding.DecodeString(parts[0]) - if err != nil { - return "", errStateInvalid - } - payload := statePayload{} - if err = json.Unmarshal(body, &payload); err != nil { - return "", errStateInvalid - } - if payload.ExpiredAt <= time.Now().Unix() { - return "", errStateInvalid - } - return sanitizeNextPath(payload.Next), nil -} - -func IssueLoginTicket(loginResp *response.LoginResponse) (string, error) { - if loginResp == nil { - return "", i18nx.Errorf("error.e0272") - } - ticket, err := randomToken("wlt_") - if err != nil { - return "", err - } - cleanupExpiredLoginTickets() - loginTicketStore.Store(ticket, loginTicket{ - Response: loginResp, - ExpiredAt: time.Now().Add(LoginTicketTTL), - }) - return ticket, nil -} - -func ConsumeLoginTicket(ticket string) (*response.LoginResponse, error) { - ticket = strings.TrimSpace(ticket) - if ticket == "" { - return nil, errorsx.InvalidParamI18n("error.e0072") - } - value, ok := loginTicketStore.LoadAndDelete(ticket) - if !ok { - return nil, errorsx.UnauthorizedI18n("error.e0271") - } - record, ok := value.(loginTicket) - if !ok || record.Response == nil || time.Now().After(record.ExpiredAt) { - return nil, errorsx.UnauthorizedI18n("error.e0271") - } - return record.Response, nil -} - -func signState(content, secret string) string { - mac := hmac.New(sha256.New, []byte(secret)) - _, _ = mac.Write([]byte(content)) - return hex.EncodeToString(mac.Sum(nil)) -} - -func cleanupExpiredLoginTickets() { - now := time.Now() - loginTicketStore.Range(func(key, value any) bool { - record, ok := value.(loginTicket) - if !ok || now.After(record.ExpiredAt) { - loginTicketStore.Delete(key) - } - return true - }) -} - -func sanitizeNextPath(next string) string { - next = strings.TrimSpace(next) - if next == "" || !strings.HasPrefix(next, "/") || strings.HasPrefix(next, "//") { - return defaultLoginNextPath - } - return next -} - -func randomToken(prefix string) (string, error) { - buf := make([]byte, 24) - if _, err := rand.Read(buf); err != nil { - return "", err - } - return prefix + hex.EncodeToString(buf), nil -} - -func GetUserDetail(code string) (*LoginUser, error) { - if !Enabled() { - return nil, i18nx.Errorf("error.e0109") - } - code = strings.TrimSpace(code) - if code == "" { - return nil, i18nx.Errorf("error.e0202") - } - - oauthClient := w.GetOauth() - userInfo, err := oauthClient.GetUserInfo(code) - if err != nil { - return nil, err - } - if strings.TrimSpace(userInfo.UserID) == "" { - return nil, i18nx.Errorf("error.e0198") - } - - ret := &LoginUser{ - CorpID: wxCfg.CorpID, - UserID: strings.TrimSpace(userInfo.UserID), - OpenID: strings.TrimSpace(userInfo.OpenID), - ExternalUserID: strings.TrimSpace(userInfo.ExternalUserID), - UserTicket: strings.TrimSpace(userInfo.UserTicket), - UserInfo: userInfo, - } - - if ret.UserTicket != "" { - if detail, detailErr := oauthClient.GetUserDetail(&oauth.GetUserDetailRequest{UserTicket: ret.UserTicket}); detailErr == nil { - ret.UserDetail = detail - ret.Avatar = strings.TrimSpace(detail.Avatar) - ret.Mobile = strings.TrimSpace(detail.Mobile) - ret.Email = strings.TrimSpace(detail.Email) - ret.BizMail = strings.TrimSpace(detail.BizMail) - } - } - - if profile, profileErr := w.GetAddressList().UserGet(ret.UserID); profileErr == nil { - ret.UserProfile = profile - if strings.TrimSpace(profile.Name) != "" { - ret.Name = strings.TrimSpace(profile.Name) - } - if strings.TrimSpace(profile.Avatar) != "" { - ret.Avatar = strings.TrimSpace(profile.Avatar) - } - if ret.Mobile == "" && strings.TrimSpace(profile.Mobile) != "" { - ret.Mobile = strings.TrimSpace(profile.Mobile) - } - if ret.Email == "" && strings.TrimSpace(profile.Email) != "" { - ret.Email = strings.TrimSpace(profile.Email) - } - if ret.BizMail == "" && strings.TrimSpace(profile.BizMail) != "" { - ret.BizMail = strings.TrimSpace(profile.BizMail) - } - } - - if ret.Name == "" { - ret.Name = ret.UserID - } - return ret, nil -} diff --git a/internal/wxwork/wxwork.go b/internal/wxwork/wxwork.go index 6525ad6..f88ff43 100644 --- a/internal/wxwork/wxwork.go +++ b/internal/wxwork/wxwork.go @@ -1,14 +1,12 @@ package wxwork import ( - "agent-desk/internal/pkg/config" + "code.tczkiot.com/wlw/ai-agent/internal/pkg/config" "strings" "github.com/silenceper/wechat/v2/cache" "github.com/silenceper/wechat/v2/work" - "github.com/silenceper/wechat/v2/work/addresslist" wxconfig "github.com/silenceper/wechat/v2/work/config" - "github.com/silenceper/wechat/v2/work/oauth" ) var ( @@ -16,22 +14,6 @@ var ( wxCfg config.WxWorkConfig ) -type LoginUser struct { - CorpID string `json:"corpId"` - UserID string `json:"userId"` - OpenID string `json:"openId,omitempty"` - ExternalUserID string `json:"externalUserId,omitempty"` - UserTicket string `json:"userTicket,omitempty"` - Name string `json:"name,omitempty"` - Avatar string `json:"avatar,omitempty"` - Mobile string `json:"mobile,omitempty"` - Email string `json:"email,omitempty"` - BizMail string `json:"bizMail,omitempty"` - UserInfo *oauth.GetUserInfoResponse `json:"userInfo,omitempty"` - UserDetail *oauth.GetUserDetailResponse `json:"userDetail,omitempty"` - UserProfile *addresslist.UserGetResponse `json:"userProfile,omitempty"` -} - func Init() { w = nil wxCfg = config.WxWorkConfig{} @@ -58,13 +40,6 @@ func Enabled() bool { return w != nil && wxCfg.Enabled } -func StateSecret() string { - if strings.TrimSpace(wxCfg.StateSecret) != "" { - return strings.TrimSpace(wxCfg.StateSecret) - } - return strings.TrimSpace(wxCfg.CorpSecret) -} - func GetWorkCli() *work.Work { return w }