diff --git a/internal/admin/enterprise_handler.go b/internal/admin/enterprise_handler.go index 231840fa33..6bd4fb2905 100644 --- a/internal/admin/enterprise_handler.go +++ b/internal/admin/enterprise_handler.go @@ -1563,6 +1563,31 @@ func (h *Handler) ShowUsersPlanSummary(c *gin.Context) { common.SuccessWithData(c, usersPlanSummary, "") } +// ShowUsersPlan handle show users plan +func (h *Handler) ShowUsersPlan(c *gin.Context) { + var quota int + quotaStr := c.Query("quota") + if quotaStr != "" { + var err error + quota, err = strconv.Atoi(quotaStr) + if err != nil { + common.ErrorWithCode(c, common.CodeBadRequest, "Quota must be an integer") + return + } + } + usersPlanQuota, err := h.service.ShowUsersPlanQuota(quota) + if err != nil { + if errors.Is(err, common.ErrUserNotFound) { + common.ErrorWithCode(c, common.CodeNotFound, "User not found") + return + } + common.ErrorWithCode(c, common.CodeServerError, err.Error()) + return + } + + common.SuccessWithData(c, usersPlanQuota, "") +} + // 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 9b1d9eb6cc..f9a001a0d9 100644 --- a/internal/admin/enterprise_service.go +++ b/internal/admin/enterprise_service.go @@ -915,6 +915,18 @@ func (s *Service) ShowUsersPlanSummary() (map[string]interface{}, error) { return result, nil } +// ShowUsersPlanQuota show users plan quota for enterprise edition +func (s *Service) ShowUsersPlanQuota(quota int) (map[string]interface{}, error) { + + result := map[string]interface{}{ + "quota": quota, + "command": "show_users_plan_quota", + "error": "'Show users plan quota' is not supported", + } + + 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 5b065d7f2a..89aaa6d059 100644 --- a/internal/admin/router.go +++ b/internal/admin/router.go @@ -143,6 +143,7 @@ func (r *Router) Setup(engine *gin.Engine) { 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/plan", r.handler.ShowUsersPlan) 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 13e1a80cf5..af27ea1ccb 100644 --- a/internal/cli/admin_command.go +++ b/internal/cli/admin_command.go @@ -1678,7 +1678,7 @@ func (c *CLI) AdminShowUsersActivityCommand(cmd *Command) (ResponseIf, error) { return HandleCommonDataResponse(resp, "get users activity") } -func (c *CLI) AdminShowUsersPlanCommand(cmd *Command) (ResponseIf, error) { +func (c *CLI) AdminShowUsersPlanSummaryCommand(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") @@ -1694,6 +1694,27 @@ func (c *CLI) AdminShowUsersPlanCommand(cmd *Command) (ResponseIf, error) { return HandleCommonDataResponse(resp, "get users plan") } +func (c *CLI) AdminShowUsersPlanQuotaCommand(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") + } + + quota, ok := cmd.Params["quota"].(int) + if !ok { + return nil, fmt.Errorf("quota not provided") + } + + apiURL := fmt.Sprintf("/admin/users/plan?quota=%d", quota) + + resp, err := c.AdminServerClient.Request("GET", apiURL, "admin", nil, nil) + if err != nil { + return nil, fmt.Errorf("failed to get users plan quota: %w", err) + } + + return HandleCommonDataResponse(resp, "get users plan quota") +} + // 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 29db840891..6995fc891f 100644 --- a/internal/cli/admin_parser.go +++ b/internal/cli/admin_parser.go @@ -2601,15 +2601,36 @@ commandLoop: return cmd, nil } +// SHOW USERS PLAN SUMMARY; func (p *Parser) parseAdminShowUsersPlan() (*Command, error) { p.nextToken() // consume PLAN - if p.curToken.Type != TokenSummary { - return nil, fmt.Errorf("expected SUMMARY") - } - p.nextToken() + var cmd *Command + switch p.curToken.Type { + case TokenSummary: + p.nextToken() + cmd = NewCommand("admin_show_users_plan_summary") + case TokenQuota: + p.nextToken() + cmd = NewCommand("admin_show_users_plan_quota") + + if p.curToken.Type != TokenNumber { + return nil, fmt.Errorf("expected QUOTA") + } + quotaInt, err := p.parseNumber() + if err != nil { + return nil, err + } + p.nextToken() + if quotaInt < 0 || quotaInt > 100 { + return nil, fmt.Errorf("invalid quota value") + } + + cmd.Params["quota"] = quotaInt + default: + return nil, fmt.Errorf("expected SUMMARY or QUOTA") + } - cmd := NewCommand("admin_show_users_plan_command") if p.curToken.Type == TokenSemicolon { p.nextToken() } diff --git a/internal/cli/cli_http.go b/internal/cli/cli_http.go index 176b8f78f3..836f4927b6 100644 --- a/internal/cli/cli_http.go +++ b/internal/cli/cli_http.go @@ -199,8 +199,10 @@ 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_show_users_plan_summary": + return c.AdminShowUsersPlanSummaryCommand(cmd) + case "admin_show_users_plan_quota": + return c.AdminShowUsersPlanQuotaCommand(cmd) case "admin_list_users_command": return c.AdminListUsersCommand(cmd) case "admin_list_users_condition_command":