diff --git a/internal/admin/enterprise_handler.go b/internal/admin/enterprise_handler.go index aed4321df8..9cd31bfc34 100644 --- a/internal/admin/enterprise_handler.go +++ b/internal/admin/enterprise_handler.go @@ -1706,6 +1706,21 @@ func (h *Handler) ListUsersQuota(c *gin.Context) { success(c, usersQuota, "") } +// ShowUsersPlanSummary handle show users plan summary +func (h *Handler) ShowUsersPlanSummary(c *gin.Context) { + usersPlanSummary, err := h.service.ShowUsersPlanSummary() + if err != nil { + if errors.Is(err, common.ErrUserNotFound) { + errorResponse(c, "User not found", 404) + return + } + errorResponse(c, err.Error(), 500) + return + } + + success(c, usersPlanSummary, "") +} + // ShowUsersQuotaSummary handle show users quota summary func (h *Handler) ShowUsersQuotaSummary(c *gin.Context) { usersQuotaSummary, err := h.service.ShowUsersQuotaSummary() diff --git a/internal/admin/enterprise_service.go b/internal/admin/enterprise_service.go index d2c6e71d7f..85627978a9 100644 --- a/internal/admin/enterprise_service.go +++ b/internal/admin/enterprise_service.go @@ -904,6 +904,17 @@ func (s *Service) ListUsersQuota(pageIndex, pageSize, top int, quotaThreshold *i return result, nil } +// ShowUsersPlanSummary show users plan summary for enterprise edition +func (s *Service) ShowUsersPlanSummary() (map[string]interface{}, error) { + + result := map[string]interface{}{ + "command": "show_users_plan_summary", + "error": "'Show users plan summary' is implemented in enterprise edition", + } + + return result, nil +} + // ShowUsersQuotaSummary show users quota summary for enterprise edition func (s *Service) ShowUsersQuotaSummary() (map[string]interface{}, error) { diff --git a/internal/admin/router.go b/internal/admin/router.go index abcc064a1c..87f0a06ce2 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -138,6 +138,7 @@ func (r *Router) Setup(engine *gin.Engine) { protected.GET("/users/documents", r.handler.ListUsersDocuments) protected.GET("/users/index", r.handler.ListUsersIndex) protected.GET("/users/quota", r.handler.ListUsersQuota) + protected.GET("/users/plan/summary", r.handler.ShowUsersPlanSummary) protected.GET("/users/quota/summary", r.handler.ShowUsersQuotaSummary) protected.GET("/ingestion/tasks/summary", r.handler.ShowIngestionTasksSummary) protected.GET("/data/summary", r.handler.ShowDataSummary) diff --git a/internal/cli/admin_command.go b/internal/cli/admin_command.go index 13c02ccc43..279a09a750 100644 --- a/internal/cli/admin_command.go +++ b/internal/cli/admin_command.go @@ -2283,6 +2283,36 @@ func (c *CLI) AdminShowUsersActivityCommand(cmd *Command) (ResponseIf, error) { return &result, nil } +func (c *CLI) AdminShowUsersPlanCommand(cmd *Command) (ResponseIf, error) { + + if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil { + return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login") + } + + apiURL := "/admin/users/plan/summary" + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to get users activity: %w", err) + } + + if resp.StatusCode != 200 { + return nil, fmt.Errorf("failed to get users plan: HTTP %d, body: %s", resp.StatusCode, string(resp.Body)) + } + + var result CommonDataResponse + if err = json.Unmarshal(resp.Body, &result); err != nil { + return nil, fmt.Errorf("get users plan failed: invalid JSON (%w)", err) + } + + if result.Code != 0 { + return nil, fmt.Errorf("%s", result.Message) + } + + result.Duration = resp.Duration + return &result, nil +} + // ListUsers lists all users (admin mode only) // Returns (result_map, error) - result_map is non-nil for benchmark mode func (c *CLI) AdminListUsersCommand(cmd *Command) (ResponseIf, error) { diff --git a/internal/cli/admin_parser.go b/internal/cli/admin_parser.go index e11e1d4bcc..c355953029 100644 --- a/internal/cli/admin_parser.go +++ b/internal/cli/admin_parser.go @@ -2525,6 +2525,8 @@ func (p *Parser) parseAdminShowUsersCommands() (*Command, error) { return cmd, nil case TokenActivity: return p.parseAdminShowUsersActivity() + case TokenPlan: + return p.parseAdminShowUsersPlan() default: return nil, fmt.Errorf("invalid command") } @@ -2581,6 +2583,21 @@ commandLoop: return cmd, nil } +func (p *Parser) parseAdminShowUsersPlan() (*Command, error) { + p.nextToken() // consume PLAN + + if p.curToken.Type != TokenSummary { + return nil, fmt.Errorf("expected SUMMARY") + } + p.nextToken() + + cmd := NewCommand("admin_show_users_plan_command") + if p.curToken.Type == TokenSemicolon { + p.nextToken() + } + return cmd, nil +} + // LIST USERS; // LIST USERS ACTIVE 30 DAYS; // default 7 days // LIST USERS INACTIVE 30 DAYS; // default 7 days diff --git a/internal/cli/cli_http.go b/internal/cli/cli_http.go index de3debb22d..61a1f110b5 100644 --- a/internal/cli/cli_http.go +++ b/internal/cli/cli_http.go @@ -191,6 +191,8 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) { return c.AdminShowUsersSummaryCommand(cmd) case "admin_show_users_activity_command": return c.AdminShowUsersActivityCommand(cmd) + case "admin_show_users_plan_command": + return c.AdminShowUsersPlanCommand(cmd) case "admin_list_users_command": return c.AdminListUsersCommand(cmd) case "admin_list_users_condition_command":