From b2dc684adeba85a585e3f3de0bf9d0f1e6d68f42 Mon Sep 17 00:00:00 2001 From: Anang Yusman Date: Thu, 8 Jan 2026 15:04:21 +0800 Subject: [PATCH] update --- .../entity/approval_workflow_steps.entity.go | 24 + .../entity/approval_workflows.entity.go | 23 + .../entity/client_approval_settings.entity.go | 57 + app/database/entity/clients.go | 15 + app/database/entity/user_levels.entity.go | 21 + app/database/entity/users.entity.go | 36 + app/database/index.database.go | 2 + app/middleware/client.middleware.go | 128 + app/middleware/user.middleware.go | 57 + .../client_approval_settings.module.go | 65 + .../client_approval_settings.controller.go | 430 + .../controller/controller.go | 17 + .../mapper/client_approval_settings.mapper.go | 104 + .../client_approval_settings.repository.go | 33 + ...lient_approval_settings.repository.impl.go | 139 + .../client_approval_settings.request.go | 85 + .../client_approval_settings.response.go | 82 + .../client_approval_settings.service.go | 326 + app/module/clients/clients.module.go | 54 + .../clients/controller/clients.controller.go | 197 + app/module/clients/controller/controller.go | 17 + app/module/clients/mapper/clients.mapper.go | 20 + .../clients/repository/clients.repository.go | 94 + app/module/clients/request/clients.request.go | 66 + .../clients/response/clients.response.go | 15 + app/module/clients/service/clients.service.go | 96 + app/router/api.go | 10 + config/toml/config.toml | 2 +- docs/docs.go | 12213 ++++++++++++++++ docs/swagger.json | 12184 +++++++++++++++ docs/swagger.yaml | 7823 ++++++++++ main.go | 4 + plan/api-documentation.md | 818 ++ plan/approval-workflow-architecture.md | 347 + plan/approval-workflow-flow-diagram.md | 255 + plan/database-relationships-detailed.md | 440 + plan/dynamic-article-approval-system-plan.md | 335 + plan/end-to-end-testing-scenarios.md | 785 + plan/implementation-examples.md | 1091 ++ utils/response/index.response.go | 9 + 40 files changed, 38518 insertions(+), 1 deletion(-) create mode 100644 app/database/entity/approval_workflow_steps.entity.go create mode 100644 app/database/entity/approval_workflows.entity.go create mode 100644 app/database/entity/client_approval_settings.entity.go create mode 100644 app/database/entity/clients.go create mode 100644 app/database/entity/user_levels.entity.go create mode 100644 app/database/entity/users.entity.go create mode 100644 app/middleware/client.middleware.go create mode 100644 app/middleware/user.middleware.go create mode 100644 app/module/client_approval_settings/client_approval_settings.module.go create mode 100644 app/module/client_approval_settings/controller/client_approval_settings.controller.go create mode 100644 app/module/client_approval_settings/controller/controller.go create mode 100644 app/module/client_approval_settings/mapper/client_approval_settings.mapper.go create mode 100644 app/module/client_approval_settings/repository/client_approval_settings.repository.go create mode 100644 app/module/client_approval_settings/repository/client_approval_settings.repository.impl.go create mode 100644 app/module/client_approval_settings/request/client_approval_settings.request.go create mode 100644 app/module/client_approval_settings/response/client_approval_settings.response.go create mode 100644 app/module/client_approval_settings/service/client_approval_settings.service.go create mode 100644 app/module/clients/clients.module.go create mode 100644 app/module/clients/controller/clients.controller.go create mode 100644 app/module/clients/controller/controller.go create mode 100644 app/module/clients/mapper/clients.mapper.go create mode 100644 app/module/clients/repository/clients.repository.go create mode 100644 app/module/clients/request/clients.request.go create mode 100644 app/module/clients/response/clients.response.go create mode 100644 app/module/clients/service/clients.service.go create mode 100644 docs/docs.go create mode 100644 docs/swagger.json create mode 100644 docs/swagger.yaml create mode 100644 plan/api-documentation.md create mode 100644 plan/approval-workflow-architecture.md create mode 100644 plan/approval-workflow-flow-diagram.md create mode 100644 plan/database-relationships-detailed.md create mode 100644 plan/dynamic-article-approval-system-plan.md create mode 100644 plan/end-to-end-testing-scenarios.md create mode 100644 plan/implementation-examples.md diff --git a/app/database/entity/approval_workflow_steps.entity.go b/app/database/entity/approval_workflow_steps.entity.go new file mode 100644 index 0000000..c59676c --- /dev/null +++ b/app/database/entity/approval_workflow_steps.entity.go @@ -0,0 +1,24 @@ +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type ApprovalWorkflowSteps struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + WorkflowId uint `json:"workflow_id" gorm:"type:int4;not null"` + StepOrder int `json:"step_order" gorm:"type:int4;not null"` + StepName string `json:"step_name" gorm:"type:varchar;not null"` + RequiredUserLevelId uint `json:"required_user_level_id" gorm:"type:int4;not null"` + CanSkip *bool `json:"can_skip" gorm:"type:bool;default:false"` + AutoApproveAfterHours *int `json:"auto_approve_after_hours" gorm:"type:int4"` + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Workflow ApprovalWorkflows `json:"workflow" gorm:"foreignKey:WorkflowId;constraint:OnDelete:CASCADE"` + RequiredUserLevel UserLevels `json:"required_user_level" gorm:"foreignKey:RequiredUserLevelId"` +} \ No newline at end of file diff --git a/app/database/entity/approval_workflows.entity.go b/app/database/entity/approval_workflows.entity.go new file mode 100644 index 0000000..94747c6 --- /dev/null +++ b/app/database/entity/approval_workflows.entity.go @@ -0,0 +1,23 @@ +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type ApprovalWorkflows struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Name string `json:"name" gorm:"type:varchar;not null"` + Description *string `json:"description" gorm:"type:text"` + IsDefault *bool `json:"is_default" gorm:"type:bool;default:false"` + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + // New fields for no-approval support + RequiresApproval *bool `json:"requires_approval" gorm:"type:bool;default:true"` // false = no approval needed + AutoPublish *bool `json:"auto_publish" gorm:"type:bool;default:false"` // true = auto publish after creation + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Steps []ApprovalWorkflowSteps `json:"steps" gorm:"foreignKey:WorkflowId;constraint:OnDelete:CASCADE"` +} \ No newline at end of file diff --git a/app/database/entity/client_approval_settings.entity.go b/app/database/entity/client_approval_settings.entity.go new file mode 100644 index 0000000..6caa3bd --- /dev/null +++ b/app/database/entity/client_approval_settings.entity.go @@ -0,0 +1,57 @@ +package entity + +import ( + "database/sql/driver" + "encoding/json" + "time" + + "github.com/google/uuid" +) + +// StringArray is a custom type for handling string arrays with JSON serialization +type StringArray []string + +// Scan implements the sql.Scanner interface +func (s *StringArray) Scan(value interface{}) error { + if value == nil { + *s = StringArray{} + return nil + } + + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, s) + case string: + return json.Unmarshal([]byte(v), s) + default: + return nil + } +} + +// Value implements the driver.Valuer interface +func (s StringArray) Value() (driver.Value, error) { + if s == nil || len(s) == 0 { + return "[]", nil + } + return json.Marshal(s) +} + +type ClientApprovalSettings struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + ClientId uuid.UUID `json:"client_id" gorm:"type:UUID;not null;uniqueIndex"` + RequiresApproval *bool `json:"requires_approval" gorm:"type:bool;default:true"` // false = no approval needed + DefaultWorkflowId *uint `json:"default_workflow_id" gorm:"type:int4"` // default workflow for this client + AutoPublishArticles *bool `json:"auto_publish_articles" gorm:"type:bool;default:false"` // auto publish after creation + ApprovalExemptUsers []uint `json:"approval_exempt_users" gorm:"type:int4[]"` // user IDs exempt from approval + ApprovalExemptRoles []uint `json:"approval_exempt_roles" gorm:"type:int4[]"` // role IDs exempt from approval + ApprovalExemptCategories []uint `json:"approval_exempt_categories" gorm:"type:int4[]"` // category IDs exempt from approval + RequireApprovalFor []string `json:"require_approval_for" gorm:"type:jsonb"` // specific content types that need approval + SkipApprovalFor []string `json:"skip_approval_for" gorm:"type:jsonb"` // specific content types that skip approval + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Client Clients `json:"client" gorm:"foreignKey:ClientId;constraint:OnDelete:CASCADE"` + Workflow *ApprovalWorkflows `json:"workflow" gorm:"foreignKey:DefaultWorkflowId"` +} diff --git a/app/database/entity/clients.go b/app/database/entity/clients.go new file mode 100644 index 0000000..b4ba2f1 --- /dev/null +++ b/app/database/entity/clients.go @@ -0,0 +1,15 @@ +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type Clients struct { + ID uuid.UUID `json:"id" gorm:"primaryKey;type:UUID"` + Name string `json:"name" gorm:"type:varchar"` + CreatedById *uint `json:"created_by_id" gorm:"type:int4"` + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` +} diff --git a/app/database/entity/user_levels.entity.go b/app/database/entity/user_levels.entity.go new file mode 100644 index 0000000..ee7a906 --- /dev/null +++ b/app/database/entity/user_levels.entity.go @@ -0,0 +1,21 @@ +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type UserLevels struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Name string `json:"name" gorm:"type:varchar"` + AliasName string `json:"alias_name" gorm:"type:varchar"` + LevelNumber int `json:"level_number" gorm:"type:int4"` + ParentLevelId *int `json:"parent_level_id" gorm:"type:int4"` + ProvinceId *int `json:"province_id" gorm:"type:int4"` + Group *string `json:"group" gorm:"type:varchar"` + IsApprovalActive *bool `json:"is_approval_active" gorm:"type:bool;default:false"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + IsActive *bool `json:"is_active" gorm:"type:bool"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` +} diff --git a/app/database/entity/users.entity.go b/app/database/entity/users.entity.go new file mode 100644 index 0000000..0b0adf0 --- /dev/null +++ b/app/database/entity/users.entity.go @@ -0,0 +1,36 @@ +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type Users struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Username string `json:"username" gorm:"type:varchar"` + Email string `json:"email" gorm:"type:varchar"` + Fullname string `json:"fullname" gorm:"type:varchar"` + Address *string `json:"address" gorm:"type:varchar"` + PhoneNumber *string `json:"phone_number" gorm:"type:varchar"` + WorkType *string `json:"work_type" gorm:"type:varchar"` + GenderType *string `json:"gender_type" gorm:"type:varchar"` + IdentityType *string `json:"identity_type" gorm:"type:varchar"` + IdentityGroup *string `json:"identity_group" gorm:"type:varchar"` + IdentityGroupNumber *string `json:"identity_group_number" gorm:"type:varchar"` + IdentityNumber *string `json:"identity_number" gorm:"type:varchar"` + DateOfBirth *string `json:"date_of_birth" gorm:"type:varchar"` + LastEducation *string `json:"last_education" gorm:"type:varchar"` + UserRoleId uint `json:"user_role_id" gorm:"type:int4"` + UserLevelId uint `json:"user_level_id" gorm:"type:int4"` + UserLevel *UserLevels `json:"user_levels" gorm:"foreignKey:UserLevelId;references:ID"` + KeycloakId *string `json:"keycloak_id" gorm:"type:varchar"` + StatusId *int `json:"status_id" gorm:"type:int4;default:1"` + CreatedById *uint `json:"created_by_id" gorm:"type:int4"` + ProfilePicturePath *string `json:"profile_picture_path" gorm:"type:varchar"` + TempPassword *string `json:"temp_password" gorm:"type:varchar"` + IsEmailUpdated *bool `json:"is_email_updated" gorm:"type:bool;default:false"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` +} \ No newline at end of file diff --git a/app/database/index.database.go b/app/database/index.database.go index 982fe7b..10397ae 100644 --- a/app/database/index.database.go +++ b/app/database/index.database.go @@ -95,6 +95,8 @@ func Models() []interface{} { entity.ArticleComments{}, entity.AuditTrails{}, entity.Banners{}, + entity.Clients{}, + entity.ClientApprovalSettings{}, entity.Cities{}, entity.CsrfTokenRecords{}, entity.CustomStaticPages{}, diff --git a/app/middleware/client.middleware.go b/app/middleware/client.middleware.go new file mode 100644 index 0000000..f5df86c --- /dev/null +++ b/app/middleware/client.middleware.go @@ -0,0 +1,128 @@ +package middleware + +import ( + "jaecoo-be/app/database/entity" + "strings" + + "github.com/gofiber/fiber/v2" + "github.com/google/uuid" + "gorm.io/gorm" +) + +const ( + ClientKeyHeader = "X-Client-Key" + ClientContextKey = "client_id" +) + +// excludedPaths contains paths that don't require client key validation +var excludedPaths = []string{ + "/swagger/*", + "/docs/*", + "/users/login", + "/health/*", + "/clients", + "/clients/*", + "*/viewer/*", + "/bookmarks/test-table", +} + +// isPathExcluded checks if the given path should be excluded from client key validation +func isPathExcluded(path string) bool { + for _, excludedPath := range excludedPaths { + if strings.HasPrefix(excludedPath, "*") && strings.HasSuffix(excludedPath, "*") { + // Handle wildcard at both beginning and end (e.g., "*/viewer/*") + pattern := excludedPath[1 : len(excludedPath)-1] // Remove * from both ends + if strings.Contains(path, pattern) { + return true + } + } else if strings.HasPrefix(excludedPath, "*") { + // Handle wildcard at the beginning + if strings.HasSuffix(path, excludedPath[1:]) { + return true + } + } else if strings.HasSuffix(excludedPath, "*") { + // Handle wildcard at the end + prefix := excludedPath[:len(excludedPath)-1] + if strings.HasPrefix(path, prefix) { + return true + } + } else { + // Exact match + if path == excludedPath { + return true + } + } + } + return false +} + +// ClientMiddleware extracts and validates the Client Key from request headers +func ClientMiddleware(db *gorm.DB) fiber.Handler { + return func(c *fiber.Ctx) error { + // Check if path should be excluded from client key validation + if isPathExcluded(c.Path()) { + return c.Next() + } + + // Extract Client Key from header + clientKey := c.Get(ClientKeyHeader) + + if clientKey == "" { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "success": false, + "code": 400, + "messages": []string{"Client Key is required in header: " + ClientKeyHeader}, + }) + } + + // Parse UUID + clientUUID, err := uuid.Parse(clientKey) + if err != nil { + return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ + "success": false, + "code": 400, + "messages": []string{"Invalid Client Key format"}, + }) + } + + // Validate client exists and is active + var client entity.Clients + if err := db.Where("id = ? AND is_active = ?", clientUUID, true).First(&client).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ + "success": false, + "code": 401, + "messages": []string{"Invalid or inactive Client Key"}, + }) + } + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "success": false, + "code": 500, + "messages": []string{"Error validating Client Key"}, + }) + } + + // Store client ID in context for use in handlers + c.Locals(ClientContextKey, clientUUID) + + return c.Next() + } +} + +// GetClientID retrieves the client ID from the context +func GetClientID(c *fiber.Ctx) *uuid.UUID { + if clientID, ok := c.Locals(ClientContextKey).(uuid.UUID); ok { + return &clientID + } + return nil +} + +// AddExcludedPath adds a new path to the excluded paths list +func AddExcludedPath(path string) { + excludedPaths = append(excludedPaths, path) +} + +// GetExcludedPaths returns the current list of excluded paths +func GetExcludedPaths() []string { + return excludedPaths +} diff --git a/app/middleware/user.middleware.go b/app/middleware/user.middleware.go new file mode 100644 index 0000000..0cba1eb --- /dev/null +++ b/app/middleware/user.middleware.go @@ -0,0 +1,57 @@ +package middleware + +import ( + "jaecoo-be/app/database/entity/users" + "jaecoo-be/app/module/users/repository" + utilSvc "jaecoo-be/utils/service" + + "github.com/gofiber/fiber/v2" + "github.com/rs/zerolog" +) + +const ( + UserContextKey = "user" + UserLevelContextKey = "user_level_id" +) + +// UserMiddleware extracts user information from JWT token and stores in context +func UserMiddleware(usersRepo repository.UsersRepository) fiber.Handler { + return func(c *fiber.Ctx) error { + // Skip if no Authorization header + authHeader := c.Get("Authorization") + if authHeader == "" { + return c.Next() + } + + // Get user info from token + // Create a default logger if not available in context + log := zerolog.Nop() + if logFromCtx, ok := c.Locals("log").(zerolog.Logger); ok { + log = logFromCtx + } + user := utilSvc.GetUserInfo(log, usersRepo, authHeader) + if user != nil { + // Store user in context + c.Locals(UserContextKey, user) + c.Locals(UserLevelContextKey, user.UserLevelId) + } + + return c.Next() + } +} + +// GetUser retrieves the user from the context +func GetUser(c *fiber.Ctx) *users.Users { + if user, ok := c.Locals(UserContextKey).(*users.Users); ok { + return user + } + return nil +} + +// GetUserLevelID retrieves the user level ID from the context +func GetUserLevelID(c *fiber.Ctx) *uint { + if userLevelId, ok := c.Locals(UserLevelContextKey).(uint); ok { + return &userLevelId + } + return nil +} diff --git a/app/module/client_approval_settings/client_approval_settings.module.go b/app/module/client_approval_settings/client_approval_settings.module.go new file mode 100644 index 0000000..237f3f7 --- /dev/null +++ b/app/module/client_approval_settings/client_approval_settings.module.go @@ -0,0 +1,65 @@ +package client_approval_settings + +import ( + "jaecoo-be/app/module/client_approval_settings/controller" + "jaecoo-be/app/module/client_approval_settings/repository" + "jaecoo-be/app/module/client_approval_settings/service" + + "github.com/gofiber/fiber/v2" + "go.uber.org/fx" +) + +// ClientApprovalSettingsRouter struct of ClientApprovalSettingsRouter +type ClientApprovalSettingsRouter struct { + App fiber.Router + Controller *controller.Controller +} + +// NewClientApprovalSettingsModule register bulky of ClientApprovalSettings module +var NewClientApprovalSettingsModule = fx.Options( + // register repository of ClientApprovalSettings module + fx.Provide(repository.NewClientApprovalSettingsRepository), + + // register service of ClientApprovalSettings module + fx.Provide(service.NewClientApprovalSettingsService), + + // register controller of ClientApprovalSettings module + fx.Provide(controller.NewController), + + // register router of ClientApprovalSettings module + fx.Provide(NewClientApprovalSettingsRouter), +) + +// NewClientApprovalSettingsRouter init ClientApprovalSettingsRouter +func NewClientApprovalSettingsRouter(fiber *fiber.App, controller *controller.Controller) *ClientApprovalSettingsRouter { + return &ClientApprovalSettingsRouter{ + App: fiber, + Controller: controller, + } +} + +// RegisterClientApprovalSettingsRoutes register routes of ClientApprovalSettings +func (_i *ClientApprovalSettingsRouter) RegisterClientApprovalSettingsRoutes() { + // define controllers + clientApprovalSettingsController := _i.Controller.ClientApprovalSettings + + // define routes + _i.App.Route("/client-approval-settings", func(router fiber.Router) { + // Basic CRUD routes + router.Post("/", clientApprovalSettingsController.CreateSettings) + router.Get("/", clientApprovalSettingsController.GetSettings) + router.Put("/", clientApprovalSettingsController.UpdateSettings) + router.Delete("/", clientApprovalSettingsController.DeleteSettings) + + // Approval management routes + router.Post("/toggle-approval", clientApprovalSettingsController.ToggleApproval) + router.Post("/enable-approval", clientApprovalSettingsController.EnableApproval) + router.Post("/disable-approval", clientApprovalSettingsController.DisableApproval) + router.Put("/default-workflow", clientApprovalSettingsController.SetDefaultWorkflow) + + // Exemption management routes + router.Post("/exempt-users", clientApprovalSettingsController.ManageExemptUsers) + router.Post("/exempt-roles", clientApprovalSettingsController.ManageExemptRoles) + router.Post("/exempt-categories", clientApprovalSettingsController.ManageExemptCategories) + }) +} diff --git a/app/module/client_approval_settings/controller/client_approval_settings.controller.go b/app/module/client_approval_settings/controller/client_approval_settings.controller.go new file mode 100644 index 0000000..dafe8ce --- /dev/null +++ b/app/module/client_approval_settings/controller/client_approval_settings.controller.go @@ -0,0 +1,430 @@ +package controller + +import ( + "fmt" + "jaecoo-be/app/middleware" + "jaecoo-be/app/module/client_approval_settings/request" + "jaecoo-be/app/module/client_approval_settings/service" + utilRes "jaecoo-be/utils/response" + utilVal "jaecoo-be/utils/validator" + "strconv" + + "github.com/gofiber/fiber/v2" + "github.com/rs/zerolog" +) + +type clientApprovalSettingsController struct { + clientApprovalSettingsService service.ClientApprovalSettingsService + Log zerolog.Logger +} + +type ClientApprovalSettingsController interface { + CreateSettings(c *fiber.Ctx) error + GetSettings(c *fiber.Ctx) error + UpdateSettings(c *fiber.Ctx) error + DeleteSettings(c *fiber.Ctx) error + ToggleApproval(c *fiber.Ctx) error + EnableApproval(c *fiber.Ctx) error + DisableApproval(c *fiber.Ctx) error + SetDefaultWorkflow(c *fiber.Ctx) error + ManageExemptUsers(c *fiber.Ctx) error + ManageExemptRoles(c *fiber.Ctx) error + ManageExemptCategories(c *fiber.Ctx) error +} + +func NewClientApprovalSettingsController( + clientApprovalSettingsService service.ClientApprovalSettingsService, + log zerolog.Logger, +) ClientApprovalSettingsController { + return &clientApprovalSettingsController{ + clientApprovalSettingsService: clientApprovalSettingsService, + Log: log, + } +} + +// CreateSettings ClientApprovalSettings +// @Summary Create Client Approval Settings +// @Description API for creating client approval settings +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.CreateClientApprovalSettingsRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings [post] +func (_i *clientApprovalSettingsController) CreateSettings(c *fiber.Ctx) error { + req := new(request.CreateClientApprovalSettingsRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + settings, err := _i.clientApprovalSettingsService.Create(clientId, *req) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Client approval settings created successfully"}, + Data: settings, + }) +} + +// GetSettings ClientApprovalSettings +// @Summary Get Client Approval Settings +// @Description API for getting client approval settings +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings [get] +func (_i *clientApprovalSettingsController) GetSettings(c *fiber.Ctx) error { + // Get ClientId from context + clientId := middleware.GetClientID(c) + + settings, err := _i.clientApprovalSettingsService.GetByClientId(clientId) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Client approval settings successfully retrieved"}, + Data: settings, + }) +} + +// UpdateSettings ClientApprovalSettings +// @Summary Update Client Approval Settings +// @Description API for updating client approval settings +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.UpdateClientApprovalSettingsRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings [put] +func (_i *clientApprovalSettingsController) UpdateSettings(c *fiber.Ctx) error { + req := new(request.UpdateClientApprovalSettingsRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + settings, err := _i.clientApprovalSettingsService.Update(clientId, *req) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Client approval settings successfully updated"}, + Data: settings, + }) +} + +// DeleteSettings ClientApprovalSettings +// @Summary Delete Client Approval Settings +// @Description API for deleting client approval settings +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings [delete] +func (_i *clientApprovalSettingsController) DeleteSettings(c *fiber.Ctx) error { + // Get ClientId from context + clientId := middleware.GetClientID(c) + + err := _i.clientApprovalSettingsService.Delete(clientId) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Client approval settings successfully deleted"}, + }) +} + +// ToggleApproval ClientApprovalSettings +// @Summary Toggle Approval Requirement +// @Description API for toggling approval requirement on/off +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.ToggleApprovalRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/toggle [post] +func (_i *clientApprovalSettingsController) ToggleApproval(c *fiber.Ctx) error { + req := new(request.ToggleApprovalRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + err := _i.clientApprovalSettingsService.ToggleApprovalRequirement(clientId, req.RequiresApproval) + if err != nil { + return err + } + + action := "enabled" + if !req.RequiresApproval { + action = "disabled with auto-publish" + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{fmt.Sprintf("Approval system successfully %s", action)}, + }) +} + +// EnableApproval ClientApprovalSettings +// @Summary Enable Approval System +// @Description API for enabling approval system with smooth transition +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.EnableApprovalRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/enable [post] +func (_i *clientApprovalSettingsController) EnableApproval(c *fiber.Ctx) error { + req := new(request.EnableApprovalRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + err := _i.clientApprovalSettingsService.EnableApprovalWithTransition(clientId, req.DefaultWorkflowId) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Approval system successfully enabled with smooth transition"}, + }) +} + +// DisableApproval ClientApprovalSettings +// @Summary Disable Approval System +// @Description API for disabling approval system and auto-publish pending articles +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.DisableApprovalRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/disable [post] +func (_i *clientApprovalSettingsController) DisableApproval(c *fiber.Ctx) error { + req := new(request.DisableApprovalRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + err := _i.clientApprovalSettingsService.DisableApprovalWithAutoPublish(clientId, req.Reason) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Approval system successfully disabled with auto-publish enabled"}, + }) +} + +// SetDefaultWorkflow ClientApprovalSettings +// @Summary Set Default Workflow +// @Description API for setting default workflow for client +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param payload body request.SetDefaultWorkflowRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/default-workflow [post] +func (_i *clientApprovalSettingsController) SetDefaultWorkflow(c *fiber.Ctx) error { + req := new(request.SetDefaultWorkflowRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + err := _i.clientApprovalSettingsService.SetDefaultWorkflow(clientId, req.WorkflowId) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Default workflow successfully set"}, + }) +} + +// ManageExemptUsers ClientApprovalSettings +// @Summary Manage Exempt Users +// @Description API for adding/removing users from approval exemption +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param action path string true "Action: add or remove" +// @Param user_id path int true "User ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/exempt-users/{action}/{user_id} [post] +func (_i *clientApprovalSettingsController) ManageExemptUsers(c *fiber.Ctx) error { + action := c.Params("action") + userIdStr := c.Params("user_id") + + if action != "add" && action != "remove" { + return utilRes.ErrorBadRequest(c, "Invalid action. Use 'add' or 'remove'") + } + + userId, err := strconv.Atoi(userIdStr) + if err != nil { + return utilRes.ErrorBadRequest(c, "Invalid user ID format") + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + if action == "add" { + err = _i.clientApprovalSettingsService.AddExemptUser(clientId, uint(userId)) + } else { + err = _i.clientApprovalSettingsService.RemoveExemptUser(clientId, uint(userId)) + } + + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{fmt.Sprintf("User successfully %sd from approval exemption", action)}, + }) +} + +// ManageExemptRoles ClientApprovalSettings +// @Summary Manage Exempt Roles +// @Description API for adding/removing roles from approval exemption +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param action path string true "Action: add or remove" +// @Param role_id path int true "Role ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/exempt-roles/{action}/{role_id} [post] +func (_i *clientApprovalSettingsController) ManageExemptRoles(c *fiber.Ctx) error { + action := c.Params("action") + roleIdStr := c.Params("role_id") + + if action != "add" && action != "remove" { + return utilRes.ErrorBadRequest(c, "Invalid action. Use 'add' or 'remove'") + } + + roleId, err := strconv.Atoi(roleIdStr) + if err != nil { + return utilRes.ErrorBadRequest(c, "Invalid role ID format") + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + if action == "add" { + err = _i.clientApprovalSettingsService.AddExemptRole(clientId, uint(roleId)) + } else { + err = _i.clientApprovalSettingsService.RemoveExemptRole(clientId, uint(roleId)) + } + + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{fmt.Sprintf("Role successfully %sd from approval exemption", action)}, + }) +} + +// ManageExemptCategories ClientApprovalSettings +// @Summary Manage Exempt Categories +// @Description API for adding/removing categories from approval exemption +// @Tags ClientApprovalSettings +// @Security Bearer +// @Param X-Client-Key header string true "Insert the X-Client-Key" +// @Param action path string true "Action: add or remove" +// @Param category_id path int true "Category ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /client-approval-settings/exempt-categories/{action}/{category_id} [post] +func (_i *clientApprovalSettingsController) ManageExemptCategories(c *fiber.Ctx) error { + action := c.Params("action") + categoryIdStr := c.Params("category_id") + + if action != "add" && action != "remove" { + return utilRes.ErrorBadRequest(c, "Invalid action. Use 'add' or 'remove'") + } + + categoryId, err := strconv.Atoi(categoryIdStr) + if err != nil { + return utilRes.ErrorBadRequest(c, "Invalid category ID format") + } + + // Get ClientId from context + clientId := middleware.GetClientID(c) + + if action == "add" { + err = _i.clientApprovalSettingsService.AddExemptCategory(clientId, uint(categoryId)) + } else { + err = _i.clientApprovalSettingsService.RemoveExemptCategory(clientId, uint(categoryId)) + } + + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{fmt.Sprintf("Category successfully %sd from approval exemption", action)}, + }) +} diff --git a/app/module/client_approval_settings/controller/controller.go b/app/module/client_approval_settings/controller/controller.go new file mode 100644 index 0000000..d85779c --- /dev/null +++ b/app/module/client_approval_settings/controller/controller.go @@ -0,0 +1,17 @@ +package controller + +import ( + "jaecoo-be/app/module/client_approval_settings/service" + + "github.com/rs/zerolog" +) + +type Controller struct { + ClientApprovalSettings ClientApprovalSettingsController +} + +func NewController(ClientApprovalSettingsService service.ClientApprovalSettingsService, log zerolog.Logger) *Controller { + return &Controller{ + ClientApprovalSettings: NewClientApprovalSettingsController(ClientApprovalSettingsService, log), + } +} diff --git a/app/module/client_approval_settings/mapper/client_approval_settings.mapper.go b/app/module/client_approval_settings/mapper/client_approval_settings.mapper.go new file mode 100644 index 0000000..97e56b8 --- /dev/null +++ b/app/module/client_approval_settings/mapper/client_approval_settings.mapper.go @@ -0,0 +1,104 @@ +package mapper + +import ( + "jaecoo-be/app/database/entity" + res "jaecoo-be/app/module/client_approval_settings/response" + + "github.com/google/uuid" + "github.com/rs/zerolog" +) + +func ClientApprovalSettingsResponseMapper( + log zerolog.Logger, + clientId *uuid.UUID, + settings *entity.ClientApprovalSettings, +) *res.ClientApprovalSettingsResponse { + if settings == nil { + return nil + } + + return &res.ClientApprovalSettingsResponse{ + ID: settings.ID, + ClientId: settings.ClientId.String(), + RequiresApproval: *settings.RequiresApproval, + DefaultWorkflowId: settings.DefaultWorkflowId, + AutoPublishArticles: *settings.AutoPublishArticles, + ApprovalExemptUsers: settings.ApprovalExemptUsers, + ApprovalExemptRoles: settings.ApprovalExemptRoles, + ApprovalExemptCategories: settings.ApprovalExemptCategories, + RequireApprovalFor: settings.RequireApprovalFor, + SkipApprovalFor: settings.SkipApprovalFor, + IsActive: *settings.IsActive, + CreatedAt: settings.CreatedAt, + UpdatedAt: settings.UpdatedAt, + } +} + +func ClientApprovalSettingsDetailResponseMapper( + log zerolog.Logger, + clientId *uuid.UUID, + settings *entity.ClientApprovalSettings, +) *res.ClientApprovalSettingsDetailResponse { + if settings == nil { + return nil + } + + response := &res.ClientApprovalSettingsDetailResponse{ + ID: settings.ID, + ClientId: settings.ClientId.String(), + RequiresApproval: *settings.RequiresApproval, + DefaultWorkflowId: settings.DefaultWorkflowId, + AutoPublishArticles: *settings.AutoPublishArticles, + ApprovalExemptUsers: settings.ApprovalExemptUsers, + ApprovalExemptRoles: settings.ApprovalExemptRoles, + ApprovalExemptCategories: settings.ApprovalExemptCategories, + RequireApprovalFor: settings.RequireApprovalFor, + SkipApprovalFor: settings.SkipApprovalFor, + IsActive: *settings.IsActive, + CreatedAt: settings.CreatedAt, + UpdatedAt: settings.UpdatedAt, + } + + // Add client relation if available + if settings.Client.ID != uuid.Nil { + response.Client = &res.ClientResponse{ + ID: 1, // Placeholder - would need proper ID mapping + Name: settings.Client.Name, + IsActive: *settings.Client.IsActive, + } + } + + // Add workflow relation if available + if settings.Workflow != nil && settings.Workflow.ID != 0 { + response.Workflow = &res.WorkflowResponse{ + ID: settings.Workflow.ID, + Name: settings.Workflow.Name, + Description: settings.Workflow.Description, + IsActive: *settings.Workflow.IsActive, + } + } + + return response +} + +func ApprovalStatusResponseMapper( + log zerolog.Logger, + clientId *uuid.UUID, + settings *entity.ClientApprovalSettings, +) *res.ApprovalStatusResponse { + if settings == nil { + return &res.ApprovalStatusResponse{ + RequiresApproval: true, // Default to requiring approval + AutoPublishArticles: false, + IsActive: false, + Message: "No approval settings found", + } + } + + return &res.ApprovalStatusResponse{ + RequiresApproval: *settings.RequiresApproval, + AutoPublishArticles: *settings.AutoPublishArticles, + IsActive: *settings.IsActive, + Message: "Approval settings loaded successfully", + } +} diff --git a/app/module/client_approval_settings/repository/client_approval_settings.repository.go b/app/module/client_approval_settings/repository/client_approval_settings.repository.go new file mode 100644 index 0000000..3916757 --- /dev/null +++ b/app/module/client_approval_settings/repository/client_approval_settings.repository.go @@ -0,0 +1,33 @@ +package repository + +import ( + "jaecoo-be/app/database/entity" + + "github.com/google/uuid" +) + +type ClientApprovalSettingsRepository interface { + // Basic CRUD + Create(clientId *uuid.UUID, settings *entity.ClientApprovalSettings) (*entity.ClientApprovalSettings, error) + FindOne(clientId *uuid.UUID) (*entity.ClientApprovalSettings, error) + Update(clientId *uuid.UUID, settings *entity.ClientApprovalSettings) (*entity.ClientApprovalSettings, error) + Delete(clientId *uuid.UUID) error + + // Specific queries + FindByClientId(clientId uuid.UUID) (*entity.ClientApprovalSettings, error) + FindActiveSettings(clientId *uuid.UUID) (*entity.ClientApprovalSettings, error) + FindByWorkflowId(workflowId uint) ([]*entity.ClientApprovalSettings, error) + + // Exemption management + AddExemptUser(clientId *uuid.UUID, userId uint) error + RemoveExemptUser(clientId *uuid.UUID, userId uint) error + AddExemptRole(clientId *uuid.UUID, roleId uint) error + RemoveExemptRole(clientId *uuid.UUID, roleId uint) error + AddExemptCategory(clientId *uuid.UUID, categoryId uint) error + RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error + + // Bulk operations + BulkUpdateExemptUsers(clientId *uuid.UUID, userIds []uint) error + BulkUpdateExemptRoles(clientId *uuid.UUID, roleIds []uint) error + BulkUpdateExemptCategories(clientId *uuid.UUID, categoryIds []uint) error +} diff --git a/app/module/client_approval_settings/repository/client_approval_settings.repository.impl.go b/app/module/client_approval_settings/repository/client_approval_settings.repository.impl.go new file mode 100644 index 0000000..eed872d --- /dev/null +++ b/app/module/client_approval_settings/repository/client_approval_settings.repository.impl.go @@ -0,0 +1,139 @@ +package repository + +import ( + "errors" + "jaecoo-be/app/database" + "jaecoo-be/app/database/entity" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "gorm.io/gorm" +) + +type clientApprovalSettingsRepository struct { + DB *database.Database + Log zerolog.Logger +} + +func NewClientApprovalSettingsRepository(db *database.Database, log zerolog.Logger) ClientApprovalSettingsRepository { + return &clientApprovalSettingsRepository{ + DB: db, + Log: log, + } +} + +func (r *clientApprovalSettingsRepository) Create(clientId *uuid.UUID, settings *entity.ClientApprovalSettings) (*entity.ClientApprovalSettings, error) { + settings.ClientId = *clientId + if err := r.DB.DB.Create(settings).Error; err != nil { + return nil, err + } + return settings, nil +} + +func (r *clientApprovalSettingsRepository) FindOne(clientId *uuid.UUID) (*entity.ClientApprovalSettings, error) { + var settings entity.ClientApprovalSettings + err := r.DB.DB.Where("client_id = ?", clientId).First(&settings).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, err + } + return &settings, nil +} + +func (r *clientApprovalSettingsRepository) Update(clientId *uuid.UUID, settings *entity.ClientApprovalSettings) (*entity.ClientApprovalSettings, error) { + settings.ClientId = *clientId + if err := r.DB.DB.Where("client_id = ?", clientId).Save(settings).Error; err != nil { + return nil, err + } + return settings, nil +} + +func (r *clientApprovalSettingsRepository) Delete(clientId *uuid.UUID) error { + return r.DB.DB.Where("client_id = ?", clientId).Delete(&entity.ClientApprovalSettings{}).Error +} + +func (r *clientApprovalSettingsRepository) FindByClientId(clientId uuid.UUID) (*entity.ClientApprovalSettings, error) { + var settings entity.ClientApprovalSettings + err := r.DB.DB.Where("client_id = ?", clientId).First(&settings).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, err + } + return &settings, nil +} + +func (r *clientApprovalSettingsRepository) FindActiveSettings(clientId *uuid.UUID) (*entity.ClientApprovalSettings, error) { + var settings entity.ClientApprovalSettings + err := r.DB.DB.Where("client_id = ? AND is_active = ?", clientId, true).First(&settings).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, nil + } + return nil, err + } + return &settings, nil +} + +func (r *clientApprovalSettingsRepository) FindByWorkflowId(workflowId uint) ([]*entity.ClientApprovalSettings, error) { + var settings []*entity.ClientApprovalSettings + err := r.DB.DB.Where("default_workflow_id = ?", workflowId).Find(&settings).Error + return settings, err +} + +func (r *clientApprovalSettingsRepository) AddExemptUser(clientId *uuid.UUID, userId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_users", gorm.Expr("array_append(approval_exempt_users, ?)", userId)).Error +} + +func (r *clientApprovalSettingsRepository) RemoveExemptUser(clientId *uuid.UUID, userId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_users", gorm.Expr("array_remove(approval_exempt_users, ?)", userId)).Error +} + +func (r *clientApprovalSettingsRepository) AddExemptRole(clientId *uuid.UUID, roleId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_roles", gorm.Expr("array_append(approval_exempt_roles, ?)", roleId)).Error +} + +func (r *clientApprovalSettingsRepository) RemoveExemptRole(clientId *uuid.UUID, roleId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_roles", gorm.Expr("array_remove(approval_exempt_roles, ?)", roleId)).Error +} + +func (r *clientApprovalSettingsRepository) AddExemptCategory(clientId *uuid.UUID, categoryId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_categories", gorm.Expr("array_append(approval_exempt_categories, ?)", categoryId)).Error +} + +func (r *clientApprovalSettingsRepository) RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_categories", gorm.Expr("array_remove(approval_exempt_categories, ?)", categoryId)).Error +} + +func (r *clientApprovalSettingsRepository) BulkUpdateExemptUsers(clientId *uuid.UUID, userIds []uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_users", userIds).Error +} + +func (r *clientApprovalSettingsRepository) BulkUpdateExemptRoles(clientId *uuid.UUID, roleIds []uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_roles", roleIds).Error +} + +func (r *clientApprovalSettingsRepository) BulkUpdateExemptCategories(clientId *uuid.UUID, categoryIds []uint) error { + return r.DB.DB.Model(&entity.ClientApprovalSettings{}). + Where("client_id = ?", clientId). + Update("approval_exempt_categories", categoryIds).Error +} diff --git a/app/module/client_approval_settings/request/client_approval_settings.request.go b/app/module/client_approval_settings/request/client_approval_settings.request.go new file mode 100644 index 0000000..3a9612f --- /dev/null +++ b/app/module/client_approval_settings/request/client_approval_settings.request.go @@ -0,0 +1,85 @@ +package request + +// CreateClientApprovalSettingsRequest represents request for creating client approval settings +type CreateClientApprovalSettingsRequest struct { + RequiresApproval bool `json:"requiresApproval"` + DefaultWorkflowId *uint `json:"defaultWorkflowId" validate:"omitempty,min=1"` + AutoPublishArticles bool `json:"autoPublishArticles"` + ApprovalExemptUsers []uint `json:"approvalExemptUsers" validate:"omitempty,dive,min=1"` + ApprovalExemptRoles []uint `json:"approvalExemptRoles" validate:"omitempty,dive,min=1"` + ApprovalExemptCategories []uint `json:"approvalExemptCategories" validate:"omitempty,dive,min=1"` + RequireApprovalFor []string `json:"requireApprovalFor" validate:"omitempty,dive,min=1"` + SkipApprovalFor []string `json:"skipApprovalFor" validate:"omitempty,dive,min=1"` + IsActive bool `json:"isActive"` +} + +// UpdateClientApprovalSettingsRequest represents request for updating client approval settings +type UpdateClientApprovalSettingsRequest struct { + RequiresApproval *bool `json:"requiresApproval"` + DefaultWorkflowId **uint `json:"defaultWorkflowId"` // double pointer to allow nil + AutoPublishArticles *bool `json:"autoPublishArticles"` + ApprovalExemptUsers []uint `json:"approvalExemptUsers" validate:"omitempty,dive,min=1"` + ApprovalExemptRoles []uint `json:"approvalExemptRoles" validate:"omitempty,dive,min=1"` + ApprovalExemptCategories []uint `json:"approvalExemptCategories" validate:"omitempty,dive,min=1"` + RequireApprovalFor []string `json:"requireApprovalFor" validate:"omitempty,dive,min=1"` + SkipApprovalFor []string `json:"skipApprovalFor" validate:"omitempty,dive,min=1"` + IsActive *bool `json:"isActive"` +} + +// ToggleApprovalRequest represents request for toggling approval requirement +type ToggleApprovalRequest struct { + RequiresApproval bool `json:"requiresApproval"` +} + +// EnableApprovalRequest represents request for enabling approval with smooth transition +type EnableApprovalRequest struct { + DefaultWorkflowId *uint `json:"defaultWorkflowId" validate:"omitempty,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// DisableApprovalRequest represents request for disabling approval system +type DisableApprovalRequest struct { + Reason string `json:"reason" validate:"required,max=500"` + HandleAction string `json:"handleAction" validate:"required,oneof=auto_approve keep_pending reset_to_draft"` // How to handle pending articles +} + +// SetDefaultWorkflowRequest represents request for setting default workflow +type SetDefaultWorkflowRequest struct { + WorkflowId *uint `json:"workflowId" validate:"omitempty,min=1"` +} + +// AddExemptUserRequest represents request for adding user to exemption +type AddExemptUserRequest struct { + UserId uint `json:"userId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// RemoveExemptUserRequest represents request for removing user from exemption +type RemoveExemptUserRequest struct { + UserId uint `json:"userId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// AddExemptRoleRequest represents request for adding role to exemption +type AddExemptRoleRequest struct { + RoleId uint `json:"roleId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// RemoveExemptRoleRequest represents request for removing role from exemption +type RemoveExemptRoleRequest struct { + RoleId uint `json:"roleId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// AddExemptCategoryRequest represents request for adding category to exemption +type AddExemptCategoryRequest struct { + CategoryId uint `json:"categoryId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} + +// RemoveExemptCategoryRequest represents request for removing category from exemption +type RemoveExemptCategoryRequest struct { + CategoryId uint `json:"categoryId" validate:"required,min=1"` + Reason string `json:"reason" validate:"omitempty,max=500"` +} diff --git a/app/module/client_approval_settings/response/client_approval_settings.response.go b/app/module/client_approval_settings/response/client_approval_settings.response.go new file mode 100644 index 0000000..ecbafd8 --- /dev/null +++ b/app/module/client_approval_settings/response/client_approval_settings.response.go @@ -0,0 +1,82 @@ +package response + +import ( + "time" +) + +type ClientApprovalSettingsResponse struct { + ID uint `json:"id"` + ClientId string `json:"clientId"` + RequiresApproval bool `json:"requiresApproval"` + DefaultWorkflowId *uint `json:"defaultWorkflowId,omitempty"` + AutoPublishArticles bool `json:"autoPublishArticles"` + ApprovalExemptUsers []uint `json:"approvalExemptUsers"` + ApprovalExemptRoles []uint `json:"approvalExemptRoles"` + ApprovalExemptCategories []uint `json:"approvalExemptCategories"` + RequireApprovalFor []string `json:"requireApprovalFor"` + SkipApprovalFor []string `json:"skipApprovalFor"` + IsActive bool `json:"isActive"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} + +type ClientApprovalSettingsDetailResponse struct { + ID uint `json:"id"` + ClientId string `json:"clientId"` + RequiresApproval bool `json:"requiresApproval"` + DefaultWorkflowId *uint `json:"defaultWorkflowId,omitempty"` + AutoPublishArticles bool `json:"autoPublishArticles"` + ApprovalExemptUsers []uint `json:"approvalExemptUsers"` + ApprovalExemptRoles []uint `json:"approvalExemptRoles"` + ApprovalExemptCategories []uint `json:"approvalExemptCategories"` + RequireApprovalFor []string `json:"requireApprovalFor"` + SkipApprovalFor []string `json:"skipApprovalFor"` + IsActive bool `json:"isActive"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + + // Relations + Client *ClientResponse `json:"client,omitempty"` + Workflow *WorkflowResponse `json:"workflow,omitempty"` +} + +type ClientResponse struct { + ID uint `json:"id"` + Name string `json:"name"` + IsActive bool `json:"isActive"` +} + +type WorkflowResponse struct { + ID uint `json:"id"` + Name string `json:"name"` + Description *string `json:"description,omitempty"` + IsActive bool `json:"isActive"` +} + +type ApprovalStatusResponse struct { + RequiresApproval bool `json:"requiresApproval"` + AutoPublishArticles bool `json:"autoPublishArticles"` + IsActive bool `json:"isActive"` + Message string `json:"message,omitempty"` +} + +type ExemptUserResponse struct { + UserId uint `json:"userId"` + Reason string `json:"reason,omitempty"` +} + +type ExemptRoleResponse struct { + RoleId uint `json:"roleId"` + Reason string `json:"reason,omitempty"` +} + +type ExemptCategoryResponse struct { + CategoryId uint `json:"categoryId"` + Reason string `json:"reason,omitempty"` +} + +type ApprovalTransitionResponse struct { + Success bool `json:"success"` + Message string `json:"message"` + AffectedArticles int `json:"affectedArticles,omitempty"` +} diff --git a/app/module/client_approval_settings/service/client_approval_settings.service.go b/app/module/client_approval_settings/service/client_approval_settings.service.go new file mode 100644 index 0000000..e6049fb --- /dev/null +++ b/app/module/client_approval_settings/service/client_approval_settings.service.go @@ -0,0 +1,326 @@ +package service + +import ( + "fmt" + "jaecoo-be/app/database/entity" + "jaecoo-be/app/module/client_approval_settings/mapper" + "jaecoo-be/app/module/client_approval_settings/repository" + "jaecoo-be/app/module/client_approval_settings/request" + "jaecoo-be/app/module/client_approval_settings/response" + + "github.com/google/uuid" + "github.com/rs/zerolog" +) + +type clientApprovalSettingsService struct { + clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository + Log zerolog.Logger +} + +type ClientApprovalSettingsService interface { + GetByClientId(clientId *uuid.UUID) (*response.ClientApprovalSettingsResponse, error) + Create(clientId *uuid.UUID, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) + Update(clientId *uuid.UUID, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) + Delete(clientId *uuid.UUID) error + ToggleApprovalRequirement(clientId *uuid.UUID, requiresApproval bool) error + SetDefaultWorkflow(clientId *uuid.UUID, workflowId *uint) error + AddExemptUser(clientId *uuid.UUID, userId uint) error + RemoveExemptUser(clientId *uuid.UUID, userId uint) error + AddExemptRole(clientId *uuid.UUID, roleId uint) error + RemoveExemptRole(clientId *uuid.UUID, roleId uint) error + AddExemptCategory(clientId *uuid.UUID, categoryId uint) error + RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error + CheckIfApprovalRequired(clientId *uuid.UUID, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error) + + // Enhanced methods for dynamic approval management + EnableApprovalWithTransition(clientId *uuid.UUID, defaultWorkflowId *uint) error + DisableApprovalWithAutoPublish(clientId *uuid.UUID, reason string) error + HandlePendingApprovalsOnDisable(clientId *uuid.UUID, action string) error // "auto_approve", "keep_pending", "reset_to_draft" +} + +func NewClientApprovalSettingsService( + clientApprovalSettingsRepo repository.ClientApprovalSettingsRepository, + log zerolog.Logger, +) ClientApprovalSettingsService { + return &clientApprovalSettingsService{ + clientApprovalSettingsRepo: clientApprovalSettingsRepo, + Log: log, + } +} + +func (_i *clientApprovalSettingsService) GetByClientId(clientId *uuid.UUID) (*response.ClientApprovalSettingsResponse, error) { + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return nil, err + } + + if settings == nil { + // Return default settings if none found + return &response.ClientApprovalSettingsResponse{ + ClientId: clientId.String(), + RequiresApproval: true, // Default to requiring approval + AutoPublishArticles: false, + ApprovalExemptUsers: []uint{}, + ApprovalExemptRoles: []uint{}, + ApprovalExemptCategories: []uint{}, + RequireApprovalFor: []string{}, + SkipApprovalFor: []string{}, + IsActive: true, + }, nil + } + + return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, settings), nil +} + +func (_i *clientApprovalSettingsService) Create(clientId *uuid.UUID, req request.CreateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) { + // Check if settings already exist + existing, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return nil, err + } + + if existing != nil { + return nil, fmt.Errorf("approval settings already exist for this client") + } + + // Create new settings + settings := &entity.ClientApprovalSettings{ + RequiresApproval: &req.RequiresApproval, + DefaultWorkflowId: req.DefaultWorkflowId, + AutoPublishArticles: &req.AutoPublishArticles, + ApprovalExemptUsers: req.ApprovalExemptUsers, + ApprovalExemptRoles: req.ApprovalExemptRoles, + ApprovalExemptCategories: req.ApprovalExemptCategories, + RequireApprovalFor: req.RequireApprovalFor, + SkipApprovalFor: req.SkipApprovalFor, + IsActive: &req.IsActive, + } + + createdSettings, err := _i.clientApprovalSettingsRepo.Create(clientId, settings) + if err != nil { + return nil, err + } + + return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, createdSettings), nil +} + +func (_i *clientApprovalSettingsService) Update(clientId *uuid.UUID, req request.UpdateClientApprovalSettingsRequest) (*response.ClientApprovalSettingsResponse, error) { + // Get existing settings + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return nil, err + } + + if settings == nil { + return nil, fmt.Errorf("approval settings not found for this client") + } + + // Update fields if provided + if req.RequiresApproval != nil { + settings.RequiresApproval = req.RequiresApproval + } + if req.DefaultWorkflowId != nil { + settings.DefaultWorkflowId = *req.DefaultWorkflowId + } + if req.AutoPublishArticles != nil { + settings.AutoPublishArticles = req.AutoPublishArticles + } + if req.ApprovalExemptUsers != nil { + settings.ApprovalExemptUsers = req.ApprovalExemptUsers + } + if req.ApprovalExemptRoles != nil { + settings.ApprovalExemptRoles = req.ApprovalExemptRoles + } + if req.ApprovalExemptCategories != nil { + settings.ApprovalExemptCategories = req.ApprovalExemptCategories + } + if req.RequireApprovalFor != nil { + settings.RequireApprovalFor = req.RequireApprovalFor + } + if req.SkipApprovalFor != nil { + settings.SkipApprovalFor = req.SkipApprovalFor + } + if req.IsActive != nil { + settings.IsActive = req.IsActive + } + + updatedSettings, err := _i.clientApprovalSettingsRepo.Update(clientId, settings) + if err != nil { + return nil, err + } + + return mapper.ClientApprovalSettingsResponseMapper(_i.Log, clientId, updatedSettings), nil +} + +func (_i *clientApprovalSettingsService) Delete(clientId *uuid.UUID) error { + return _i.clientApprovalSettingsRepo.Delete(clientId) +} + +func (_i *clientApprovalSettingsService) ToggleApprovalRequirement(clientId *uuid.UUID, requiresApproval bool) error { + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return err + } + + if settings == nil { + return fmt.Errorf("approval settings not found for this client") + } + + settings.RequiresApproval = &requiresApproval + _, err = _i.clientApprovalSettingsRepo.Update(clientId, settings) + return err +} + +func (_i *clientApprovalSettingsService) SetDefaultWorkflow(clientId *uuid.UUID, workflowId *uint) error { + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return err + } + + if settings == nil { + return fmt.Errorf("approval settings not found for this client") + } + + settings.DefaultWorkflowId = workflowId + _, err = _i.clientApprovalSettingsRepo.Update(clientId, settings) + return err +} + +func (_i *clientApprovalSettingsService) AddExemptUser(clientId *uuid.UUID, userId uint) error { + return _i.clientApprovalSettingsRepo.AddExemptUser(clientId, userId) +} + +func (_i *clientApprovalSettingsService) RemoveExemptUser(clientId *uuid.UUID, userId uint) error { + return _i.clientApprovalSettingsRepo.RemoveExemptUser(clientId, userId) +} + +func (_i *clientApprovalSettingsService) AddExemptRole(clientId *uuid.UUID, roleId uint) error { + return _i.clientApprovalSettingsRepo.AddExemptRole(clientId, roleId) +} + +func (_i *clientApprovalSettingsService) RemoveExemptRole(clientId *uuid.UUID, roleId uint) error { + return _i.clientApprovalSettingsRepo.RemoveExemptRole(clientId, roleId) +} + +func (_i *clientApprovalSettingsService) AddExemptCategory(clientId *uuid.UUID, categoryId uint) error { + return _i.clientApprovalSettingsRepo.AddExemptCategory(clientId, categoryId) +} + +func (_i *clientApprovalSettingsService) RemoveExemptCategory(clientId *uuid.UUID, categoryId uint) error { + return _i.clientApprovalSettingsRepo.RemoveExemptCategory(clientId, categoryId) +} + +func (_i *clientApprovalSettingsService) CheckIfApprovalRequired(clientId *uuid.UUID, userId uint, userLevelId uint, categoryId uint, contentType string) (bool, error) { + settings, err := _i.clientApprovalSettingsRepo.FindActiveSettings(clientId) + if err != nil { + return true, err // Default to requiring approval on error + } + + if settings == nil { + return true, nil // Default to requiring approval if no settings + } + + // Check if approval is disabled + if settings.RequiresApproval != nil && !*settings.RequiresApproval { + return false, nil + } + + // Check user exemption + for _, exemptUserId := range settings.ApprovalExemptUsers { + if exemptUserId == userId { + return false, nil + } + } + + // Check role exemption + for _, exemptRoleId := range settings.ApprovalExemptRoles { + if exemptRoleId == userLevelId { + return false, nil + } + } + + // Check category exemption + for _, exemptCategoryId := range settings.ApprovalExemptCategories { + if exemptCategoryId == categoryId { + return false, nil + } + } + + // Check content type exemptions + for _, skipType := range settings.SkipApprovalFor { + if skipType == contentType { + return false, nil + } + } + + // Check if content type requires approval + for _, requireType := range settings.RequireApprovalFor { + if requireType == contentType { + return true, nil + } + } + + // Default to requiring approval + return true, nil +} + +func (_i *clientApprovalSettingsService) EnableApprovalWithTransition(clientId *uuid.UUID, defaultWorkflowId *uint) error { + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return err + } + + if settings == nil { + // Create new settings + settings = &entity.ClientApprovalSettings{ + RequiresApproval: &[]bool{true}[0], + DefaultWorkflowId: defaultWorkflowId, + AutoPublishArticles: &[]bool{false}[0], + IsActive: &[]bool{true}[0], + } + _, err = _i.clientApprovalSettingsRepo.Create(clientId, settings) + } else { + // Update existing settings + settings.RequiresApproval = &[]bool{true}[0] + settings.DefaultWorkflowId = defaultWorkflowId + settings.AutoPublishArticles = &[]bool{false}[0] + settings.IsActive = &[]bool{true}[0] + _, err = _i.clientApprovalSettingsRepo.Update(clientId, settings) + } + + return err +} + +func (_i *clientApprovalSettingsService) DisableApprovalWithAutoPublish(clientId *uuid.UUID, reason string) error { + settings, err := _i.clientApprovalSettingsRepo.FindByClientId(*clientId) + if err != nil { + return err + } + + if settings == nil { + return fmt.Errorf("approval settings not found for this client") + } + + settings.RequiresApproval = &[]bool{false}[0] + settings.AutoPublishArticles = &[]bool{true}[0] + settings.IsActive = &[]bool{true}[0] + + _, err = _i.clientApprovalSettingsRepo.Update(clientId, settings) + return err +} + +func (_i *clientApprovalSettingsService) HandlePendingApprovalsOnDisable(clientId *uuid.UUID, action string) error { + // This would typically interact with article approval flows + // For now, just log the action + _i.Log.Info(). + Str("client_id", clientId.String()). + Str("action", action). + Msg("Handling pending approvals on disable") + + // TODO: Implement actual logic based on action: + // - "auto_approve": Auto approve all pending articles + // - "keep_pending": Keep articles in pending state + // - "reset_to_draft": Reset articles to draft state + + return nil +} diff --git a/app/module/clients/clients.module.go b/app/module/clients/clients.module.go new file mode 100644 index 0000000..78599b7 --- /dev/null +++ b/app/module/clients/clients.module.go @@ -0,0 +1,54 @@ +package clients + +import ( + "jaecoo-be/app/module/clients/controller" + "jaecoo-be/app/module/clients/repository" + "jaecoo-be/app/module/clients/service" + + "github.com/gofiber/fiber/v2" + "go.uber.org/fx" +) + +// struct of ClientsRouter +type ClientsRouter struct { + App fiber.Router + Controller *controller.Controller +} + +// register bulky of Clients module +var NewClientsModule = fx.Options( + // register repository of Clients module + fx.Provide(repository.NewClientsRepository), + + // register service of Clients module + fx.Provide(service.NewClientsService), + + // register controller of Clients module + fx.Provide(controller.NewController), + + // register router of Clients module + fx.Provide(NewClientsRouter), +) + +// init ClientsRouter +func NewClientsRouter(fiber *fiber.App, controller *controller.Controller) *ClientsRouter { + return &ClientsRouter{ + App: fiber, + Controller: controller, + } +} + +// register routes of Clients module +func (_i *ClientsRouter) RegisterClientsRoutes() { + // define controllers + clientsController := _i.Controller.Clients + + // define routes + _i.App.Route("/clients", func(router fiber.Router) { + router.Get("/", clientsController.All) + router.Get("/:id", clientsController.Show) + router.Post("/", clientsController.Save) + router.Put("/:id", clientsController.Update) + router.Delete("/:id", clientsController.Delete) + }) +} diff --git a/app/module/clients/controller/clients.controller.go b/app/module/clients/controller/clients.controller.go new file mode 100644 index 0000000..343930b --- /dev/null +++ b/app/module/clients/controller/clients.controller.go @@ -0,0 +1,197 @@ +package controller + +import ( + "jaecoo-be/app/module/clients/request" + "jaecoo-be/app/module/clients/service" + "jaecoo-be/utils/paginator" + + "github.com/gofiber/fiber/v2" + "github.com/google/uuid" + "github.com/rs/zerolog" + + utilRes "jaecoo-be/utils/response" + utilVal "jaecoo-be/utils/validator" +) + +type clientsController struct { + clientsService service.ClientsService + Log zerolog.Logger +} + +type ClientsController interface { + All(c *fiber.Ctx) error + Show(c *fiber.Ctx) error + Save(c *fiber.Ctx) error + Update(c *fiber.Ctx) error + Delete(c *fiber.Ctx) error +} + +func NewClientsController(clientsService service.ClientsService, log zerolog.Logger) ClientsController { + return &clientsController{ + clientsService: clientsService, + Log: log, + } +} + +// All get all Clients +// @Summary Get all Clients +// @Description API for getting all Clients +// @Tags Clients +// @Security Bearer +// @Param req query request.ClientsQueryRequest false "query parameters" +// @Param req query paginator.Pagination false "pagination parameters" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /clients [get] +func (_i *clientsController) All(c *fiber.Ctx) error { + paginate, err := paginator.Paginate(c) + if err != nil { + return err + } + + reqContext := request.ClientsQueryRequestContext{ + Name: c.Query("name"), + CreatedById: c.Query("createdById"), + } + req := reqContext.ToParamRequest() + req.Pagination = paginate + + clientsData, paging, err := _i.clientsService.All(req) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Clients list successfully retrieved"}, + Data: clientsData, + Meta: paging, + }) +} + +// Show get one Clients +// @Summary Get one Clients +// @Description API for getting one Clients +// @Tags Clients +// @Security Bearer +// @Param id path int true "Clients ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /clients/{id} [get] +func (_i *clientsController) Show(c *fiber.Ctx) error { + idStr := c.Params("id") + id, err := uuid.Parse(idStr) + if err != nil { + return err + } + + clientsData, err := _i.clientsService.Show(id) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Clients successfully retrieved"}, + Data: clientsData, + }) +} + +// Save create Clients +// @Summary Create Clients +// @Description API for create Clients +// @Tags Clients +// @Security Bearer +// @Param Authorization header string false "Insert your access token" default(Bearer ) +// @Param payload body request.ClientsCreateRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /clients [post] +func (_i *clientsController) Save(c *fiber.Ctx) error { + req := new(request.ClientsCreateRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + authToken := c.Get("Authorization") + dataResult, err := _i.clientsService.Save(*req, authToken) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Clients successfully created"}, + Data: dataResult, + }) +} + +// Update update Clients +// @Summary update Clients +// @Description API for update Clients +// @Tags Clients +// @Security Bearer +// @Param payload body request.ClientsUpdateRequest true "Required payload" +// @Param id path string true "Clients ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /clients/{id} [put] +func (_i *clientsController) Update(c *fiber.Ctx) error { + idStr := c.Params("id") + id, err := uuid.Parse(idStr) + if err != nil { + return err + } + + req := new(request.ClientsUpdateRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + err = _i.clientsService.Update(id, *req) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Clients successfully updated"}, + }) +} + +// Delete delete Clients +// @Summary delete Clients +// @Description API for delete Clients +// @Tags Clients +// @Security Bearer +// @Param id path string true "Clients ID" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /clients/{id} [delete] +func (_i *clientsController) Delete(c *fiber.Ctx) error { + idStr := c.Params("id") + id, err := uuid.Parse(idStr) + if err != nil { + return err + } + + err = _i.clientsService.Delete(id) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Clients successfully deleted"}, + }) +} diff --git a/app/module/clients/controller/controller.go b/app/module/clients/controller/controller.go new file mode 100644 index 0000000..6faeebc --- /dev/null +++ b/app/module/clients/controller/controller.go @@ -0,0 +1,17 @@ +package controller + +import ( + "jaecoo-be/app/module/clients/service" + + "github.com/rs/zerolog" +) + +type Controller struct { + Clients ClientsController +} + +func NewController(ClientsService service.ClientsService, log zerolog.Logger) *Controller { + return &Controller{ + Clients: NewClientsController(ClientsService, log), + } +} diff --git a/app/module/clients/mapper/clients.mapper.go b/app/module/clients/mapper/clients.mapper.go new file mode 100644 index 0000000..f7528c6 --- /dev/null +++ b/app/module/clients/mapper/clients.mapper.go @@ -0,0 +1,20 @@ +package mapper + +import ( + "jaecoo-be/app/database/entity" + res "jaecoo-be/app/module/clients/response" +) + +func ClientsResponseMapper(clientsReq *entity.Clients) (clientsRes *res.ClientsResponse) { + if clientsReq != nil { + clientsRes = &res.ClientsResponse{ + ClientID: clientsReq.ID, + Name: clientsReq.Name, + CreatedById: *clientsReq.CreatedById, + IsActive: *clientsReq.IsActive, + CreatedAt: clientsReq.CreatedAt, + UpdatedAt: clientsReq.UpdatedAt, + } + } + return clientsRes +} diff --git a/app/module/clients/repository/clients.repository.go b/app/module/clients/repository/clients.repository.go new file mode 100644 index 0000000..0653d00 --- /dev/null +++ b/app/module/clients/repository/clients.repository.go @@ -0,0 +1,94 @@ +package repository + +import ( + "fmt" + "jaecoo-be/app/database" + "jaecoo-be/app/database/entity" + "jaecoo-be/app/module/clients/request" + "jaecoo-be/utils/paginator" + "strings" + + "github.com/google/uuid" + "github.com/rs/zerolog" +) + +type clientsRepository struct { + DB *database.Database + Log zerolog.Logger +} + +// ClientsRepository define interface of IClientsRepository +type ClientsRepository interface { + GetAll(req request.ClientsQueryRequest) (clientss []*entity.Clients, paging paginator.Pagination, err error) + FindOne(id uuid.UUID) (clients *entity.Clients, err error) + Create(clients *entity.Clients) (clientsReturn *entity.Clients, err error) + Update(id uuid.UUID, clients *entity.Clients) (err error) + Delete(id uuid.UUID) (err error) +} + +func NewClientsRepository(db *database.Database, logger zerolog.Logger) ClientsRepository { + return &clientsRepository{ + DB: db, + Log: logger, + } +} + +// implement interface of IClientsRepository +func (_i *clientsRepository) GetAll(req request.ClientsQueryRequest) (clientss []*entity.Clients, paging paginator.Pagination, err error) { + var count int64 + + query := _i.DB.DB.Model(&entity.Clients{}) + query = query.Where("is_active = ?", true) + + if req.Name != nil && *req.Name != "" { + name := strings.ToLower(*req.Name) + query = query.Where("LOWER(name) LIKE ?", "%"+strings.ToLower(name)+"%") + } + if req.CreatedById != nil { + query = query.Where("created_by_id = ?", req.CreatedById) + } + query.Count(&count) + + if req.Pagination.SortBy != "" { + direction := "ASC" + if req.Pagination.Sort == "desc" { + direction = "DESC" + } + query.Order(fmt.Sprintf("%s %s", req.Pagination.SortBy, direction)) + } + + req.Pagination.Count = count + req.Pagination = paginator.Paging(req.Pagination) + + err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&clientss).Error + if err != nil { + return + } + + paging = *req.Pagination + + return +} + +func (_i *clientsRepository) FindOne(id uuid.UUID) (clients *entity.Clients, err error) { + if err := _i.DB.DB.First(&clients, id).Error; err != nil { + return nil, err + } + + return clients, nil +} + +func (_i *clientsRepository) Create(clients *entity.Clients) (clientsReturn *entity.Clients, err error) { + result := _i.DB.DB.Create(clients) + return clients, result.Error +} + +func (_i *clientsRepository) Update(id uuid.UUID, clients *entity.Clients) (err error) { + return _i.DB.DB.Model(&entity.Clients{}). + Where(&entity.Clients{ID: id}). + Updates(clients).Error +} + +func (_i *clientsRepository) Delete(id uuid.UUID) error { + return _i.DB.DB.Delete(&entity.Clients{}, id).Error +} diff --git a/app/module/clients/request/clients.request.go b/app/module/clients/request/clients.request.go new file mode 100644 index 0000000..b484304 --- /dev/null +++ b/app/module/clients/request/clients.request.go @@ -0,0 +1,66 @@ +package request + +import ( + "jaecoo-be/app/database/entity" + "jaecoo-be/utils/paginator" + "strconv" + "time" +) + +type ClientsGeneric interface { + ToEntity() +} + +type ClientsQueryRequest struct { + Name *string `json:"name"` + CreatedById *uint `json:"createdBy"` + Pagination *paginator.Pagination `json:"pagination"` +} + +type ClientsCreateRequest struct { + Name string `json:"name" validate:"required"` + CreatedById *uint `json:"createdById"` +} + +func (req ClientsCreateRequest) ToEntity() *entity.Clients { + return &entity.Clients{ + Name: req.Name, + CreatedById: req.CreatedById, + CreatedAt: time.Now(), + } +} + +type ClientsUpdateRequest struct { + Name string `json:"name" validate:"required"` + CreatedById *uint `json:"createdById"` +} + +func (req ClientsUpdateRequest) ToEntity() *entity.Clients { + return &entity.Clients{ + Name: req.Name, + CreatedById: req.CreatedById, + UpdatedAt: time.Now(), + } +} + +type ClientsQueryRequestContext struct { + Name string `json:"name"` + CreatedById string `json:"createdById"` +} + +func (req ClientsQueryRequestContext) ToParamRequest() ClientsQueryRequest { + var request ClientsQueryRequest + + if name := req.Name; name != "" { + request.Name = &name + } + if createdByStr := req.CreatedById; createdByStr != "" { + createdBy, err := strconv.Atoi(createdByStr) + if err == nil { + createdByIdUint := uint(createdBy) + request.CreatedById = &createdByIdUint + } + } + + return request +} diff --git a/app/module/clients/response/clients.response.go b/app/module/clients/response/clients.response.go new file mode 100644 index 0000000..e832b38 --- /dev/null +++ b/app/module/clients/response/clients.response.go @@ -0,0 +1,15 @@ +package response + +import ( + "github.com/google/uuid" + "time" +) + +type ClientsResponse struct { + ClientID uuid.UUID `json:"clientId"` + Name string `json:"name"` + CreatedById uint `json:"createdById"` + IsActive bool `json:"isActive"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` +} diff --git a/app/module/clients/service/clients.service.go b/app/module/clients/service/clients.service.go new file mode 100644 index 0000000..4105b91 --- /dev/null +++ b/app/module/clients/service/clients.service.go @@ -0,0 +1,96 @@ +package service + +import ( + "jaecoo-be/app/database/entity" + "jaecoo-be/app/module/clients/mapper" + "jaecoo-be/app/module/clients/repository" + "jaecoo-be/app/module/clients/request" + "jaecoo-be/app/module/clients/response" + usersRepository "jaecoo-be/app/module/users/repository" + "jaecoo-be/utils/paginator" + + "github.com/google/uuid" + "github.com/rs/zerolog" + + utilSvc "jaecoo-be/utils/service" +) + +// ClientsService +type clientsService struct { + Repo repository.ClientsRepository + UsersRepo usersRepository.UsersRepository + Log zerolog.Logger +} + +// ClientsService define interface of IClientsService +type ClientsService interface { + All(req request.ClientsQueryRequest) (clients []*response.ClientsResponse, paging paginator.Pagination, err error) + Show(id uuid.UUID) (clients *response.ClientsResponse, err error) + Save(req request.ClientsCreateRequest, authToken string) (clients *entity.Clients, err error) + Update(id uuid.UUID, req request.ClientsUpdateRequest) (err error) + Delete(id uuid.UUID) error +} + +// NewClientsService init ClientsService +func NewClientsService(repo repository.ClientsRepository, log zerolog.Logger, usersRepo usersRepository.UsersRepository) ClientsService { + + return &clientsService{ + Repo: repo, + Log: log, + UsersRepo: usersRepo, + } +} + +// All implement interface of ClientsService +func (_i *clientsService) All(req request.ClientsQueryRequest) (clientss []*response.ClientsResponse, paging paginator.Pagination, err error) { + results, paging, err := _i.Repo.GetAll(req) + if err != nil { + return + } + + for _, result := range results { + clientss = append(clientss, mapper.ClientsResponseMapper(result)) + } + + return +} + +func (_i *clientsService) Show(id uuid.UUID) (clients *response.ClientsResponse, err error) { + result, err := _i.Repo.FindOne(id) + if err != nil { + return nil, err + } + + return mapper.ClientsResponseMapper(result), nil +} + +func (_i *clientsService) Save(req request.ClientsCreateRequest, authToken string) (clients *entity.Clients, err error) { + _i.Log.Info().Interface("data", req).Msg("") + newReq := req.ToEntity() + _i.Log.Info().Interface("token", authToken).Msg("") + createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken) + _i.Log.Info().Interface("token", authToken).Msg("") + newReq.CreatedById = &createdBy.ID + + newReq.ID = uuid.New() + + _i.Log.Info().Interface("new data", newReq).Msg("") + + return _i.Repo.Create(newReq) +} + +func (_i *clientsService) Update(id uuid.UUID, req request.ClientsUpdateRequest) (err error) { + _i.Log.Info().Interface("data", req).Msg("") + return _i.Repo.Update(id, req.ToEntity()) +} + +func (_i *clientsService) Delete(id uuid.UUID) error { + result, err := _i.Repo.FindOne(id) + if err != nil { + return err + } + + isActive := false + result.IsActive = &isActive + return _i.Repo.Update(id, result) +} diff --git a/app/router/api.go b/app/router/api.go index 6bc4184..cc76a9e 100644 --- a/app/router/api.go +++ b/app/router/api.go @@ -10,6 +10,8 @@ import ( "jaecoo-be/app/module/articles" "jaecoo-be/app/module/banners" "jaecoo-be/app/module/cities" + "jaecoo-be/app/module/client_approval_settings" + "jaecoo-be/app/module/clients" "jaecoo-be/app/module/custom_static_pages" "jaecoo-be/app/module/districts" "jaecoo-be/app/module/feedbacks" @@ -44,6 +46,8 @@ type Router struct { ArticlesRouter *articles.ArticlesRouter BannersRouter *banners.BannersRouter CitiesRouter *cities.CitiesRouter + ClientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter + ClientsRouter *clients.ClientsRouter CustomStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter DistrictsRouter *districts.DistrictsRouter FeedbacksRouter *feedbacks.FeedbacksRouter @@ -73,6 +77,8 @@ func NewRouter( articlesRouter *articles.ArticlesRouter, bannersRouter *banners.BannersRouter, citiesRouter *cities.CitiesRouter, + clientApprovalSettingsRouter *client_approval_settings.ClientApprovalSettingsRouter, + clientsRouter *clients.ClientsRouter, customStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter, districtsRouter *districts.DistrictsRouter, feedbacksRouter *feedbacks.FeedbacksRouter, @@ -100,6 +106,8 @@ func NewRouter( ArticlesRouter: articlesRouter, BannersRouter: bannersRouter, CitiesRouter: citiesRouter, + ClientApprovalSettingsRouter: clientApprovalSettingsRouter, + ClientsRouter: clientsRouter, CustomStaticPagesRouter: customStaticPagesRouter, DistrictsRouter: districtsRouter, FeedbacksRouter: feedbacksRouter, @@ -137,6 +145,8 @@ func (r *Router) Register() { r.ArticleCommentsRouter.RegisterArticleCommentsRoutes() r.BannersRouter.RegisterBannersRoutes() r.CitiesRouter.RegisterCitiesRoutes() + r.ClientApprovalSettingsRouter.RegisterClientApprovalSettingsRoutes() + r.ClientsRouter.RegisterClientsRoutes() r.CustomStaticPagesRouter.RegisterCustomStaticPagesRoutes() r.DistrictsRouter.RegisterDistrictsRoutes() r.FeedbacksRouter.RegisterFeedbacksRoutes() diff --git a/config/toml/config.toml b/config/toml/config.toml index 90ebe02..670b2ad 100644 --- a/config/toml/config.toml +++ b/config/toml/config.toml @@ -6,7 +6,7 @@ port = ":8800" domain = "https://jaecoocihampelasbdg.com/api" external-port = ":8810" idle-timeout = 5 # As seconds -print-routes = false +print-routes = true prefork = true production = false body-limit = 1048576000 # "100 * 1024 * 1024" diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..9fc1e33 --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,12213 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/activity-logs": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get all ActivityLogs", + "parameters": [ + { + "type": "integer", + "name": "activityTypeId", + "in": "query" + }, + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "url", + "in": "query" + }, + { + "type": "integer", + "name": "userId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Create ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ActivityLogsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/detail/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get one ActivityLogs", + "parameters": [ + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/statistics": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for get activity stats ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get activity stats ActivityLogs", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "update ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ActivityLogsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "delete ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-approvals": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Get all ArticleApprovals", + "parameters": [ + { + "type": "integer", + "name": "approvalAtLevel", + "in": "query" + }, + { + "type": "integer", + "name": "approvalBy", + "in": "query" + }, + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Create ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleApprovalsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-approvals/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Get one ArticleApprovals", + "parameters": [ + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "update ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleApprovalsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "delete ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get all ArticleCategories", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "name": "UserLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "UserLevelNumber", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "parentId", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Create ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCategoriesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/old/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategories Old ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/slug/{slug}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "ArticleCategories Slug", + "name": "slug", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/thumbnail/viewer/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for View Thumbnail of ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Viewer ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/thumbnail/{id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Upload ArticleCategories Thumbnail", + "produces": [ + "application/json" + ], + "tags": [ + "Article Categories" + ], + "summary": "Upload ArticleCategories Thumbnail", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload thumbnail", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "update ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCategoriesUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "delete ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-category-details": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Get all ArticleCategoryDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Create ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/article-category-details/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Get one ArticleCategoryDetails", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "update ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "delete ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/article-comments": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Get all ArticleComments", + "parameters": [ + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "integer", + "name": "commentFrom", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublic", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "integer", + "name": "parentId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Create ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-comments/approval": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Approval ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Approval ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-comments/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Get one ArticleComments", + "parameters": [ + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "update ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "delete ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Get all ArticleFiles", + "parameters": [ + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "fileName", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/upload-status/{uploadId}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for GetUploadStatus ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "GetUploadStatus ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Upload ID of ArticleFiles", + "name": "uploadId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Viewer ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Viewer ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Article File Name", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/{articleId}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleFiles", + "produces": [ + "application/json" + ], + "tags": [ + "Article Files" + ], + "summary": "Upload ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Article ID", + "name": "articleId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Get one ArticleFiles", + "parameters": [ + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Update ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleFilesUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Delete ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Articles", + "tags": [ + "Articles" + ], + "summary": "Get all Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "category", + "in": "query" + }, + { + "type": "integer", + "name": "categoryId", + "in": "query" + }, + { + "type": "integer", + "name": "createdById", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "boolean", + "name": "isBanner", + "in": "query" + }, + { + "type": "boolean", + "name": "isDraft", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "string", + "name": "tags", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "typeId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Articles", + "tags": [ + "Articles" + ], + "summary": "Create Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header" + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticlesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/banner/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Update Banner Articles", + "tags": [ + "Articles" + ], + "summary": "Update Banner Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Articles Banner Status", + "name": "isBanner", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/old-id/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Articles", + "tags": [ + "Articles" + ], + "summary": "Get one Articles", + "parameters": [ + { + "type": "integer", + "description": "Articles Old ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/publish-scheduling": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Publish Schedule of Article", + "tags": [ + "Articles" + ], + "summary": "PublishScheduling Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "article id", + "name": "id", + "in": "query" + }, + { + "type": "string", + "description": "publish date", + "name": "date", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/monthly": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ArticleMonthlyStats of Article", + "tags": [ + "Articles" + ], + "summary": "ArticleMonthlyStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "year", + "name": "year", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/summary": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Summary Stats of Article", + "tags": [ + "Articles" + ], + "summary": "SummaryStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/user-levels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ArticlePerUserLevelStats of Article", + "tags": [ + "Articles" + ], + "summary": "ArticlePerUserLevelStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "string", + "description": "start date", + "name": "startDate", + "in": "query" + }, + { + "type": "string", + "description": "start date", + "name": "endDate", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/thumbnail/viewer/{thumbnailName}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for View Thumbnail of Article", + "tags": [ + "Articles" + ], + "summary": "Viewer Articles Thumbnail", + "parameters": [ + { + "type": "string", + "description": "Articles Thumbnail Name", + "name": "thumbnailName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/thumbnail/{id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Save Thumbnail of Articles", + "produces": [ + "application/json" + ], + "tags": [ + "Articles" + ], + "summary": "Save Thumbnail Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload thumbnail", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Articles", + "tags": [ + "Articles" + ], + "summary": "Get one Articles", + "parameters": [ + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Articles", + "tags": [ + "Articles" + ], + "summary": "Update Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticlesUpdateRequest" + } + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Articles", + "tags": [ + "Articles" + ], + "summary": "Delete Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Banners", + "tags": [ + "Banners" + ], + "summary": "Get all Banners", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "position", + "in": "query" + }, + { + "type": "string", + "name": "status", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Banner with file upload", + "tags": [ + "Banners" + ], + "summary": "Create Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Banner title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Banner description", + "name": "description", + "in": "formData" + }, + { + "type": "string", + "description": "Banner position", + "name": "position", + "in": "formData" + }, + { + "type": "string", + "description": "Banner status", + "name": "status", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Banner file", + "tags": [ + "Banners" + ], + "summary": "Viewer Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Banner File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Banner by ID", + "tags": [ + "Banners" + ], + "summary": "Get Banner by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Banner with file upload", + "tags": [ + "Banners" + ], + "summary": "Update Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Banner title", + "name": "title", + "in": "formData" + }, + { + "type": "string", + "description": "Banner description", + "name": "description", + "in": "formData" + }, + { + "type": "string", + "description": "Banner position", + "name": "position", + "in": "formData" + }, + { + "type": "string", + "description": "Banner status", + "name": "status", + "in": "formData" + }, + { + "type": "boolean", + "description": "Banner is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Banner (soft delete)", + "tags": [ + "Banners" + ], + "summary": "Delete Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/cities": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Cities", + "tags": [ + "Untags" + ], + "summary": "Get all Cities", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Cities", + "tags": [ + "Untags" + ], + "summary": "Create Cities", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CitiesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/cities/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Cities", + "tags": [ + "Untags" + ], + "summary": "Get one Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Cities", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Untags" + ], + "summary": "Update Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CitiesUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Cities", + "tags": [ + "Untags" + ], + "summary": "Delete Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/client-approval-settings": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Get Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Update Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UpdateClientApprovalSettingsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Create Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateClientApprovalSettingsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Delete Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/default-workflow": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for setting default workflow for client", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Set Default Workflow", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetDefaultWorkflowRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/disable": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for disabling approval system and auto-publish pending articles", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Disable Approval System", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.DisableApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/enable": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for enabling approval system with smooth transition", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Enable Approval System", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.EnableApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-categories/{action}/{category_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing categories from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Categories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Category ID", + "name": "category_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-roles/{action}/{role_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing roles from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Roles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Role ID", + "name": "role_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-users/{action}/{user_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing users from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "User ID", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/toggle": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for toggling approval requirement on/off", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Toggle Approval Requirement", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ToggleApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/clients": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Clients", + "tags": [ + "Clients" + ], + "summary": "Get all Clients", + "parameters": [ + { + "type": "integer", + "name": "createdBy", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Clients", + "tags": [ + "Clients" + ], + "summary": "Create Clients", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ClientsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/clients-test": { + "get": { + "tags": [ + "Clients" + ], + "summary": "TEST CLIENTS", + "responses": {} + } + }, + "/clients/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Clients", + "tags": [ + "Clients" + ], + "summary": "Get one Clients", + "parameters": [ + { + "type": "integer", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Clients", + "tags": [ + "Clients" + ], + "summary": "update Clients", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ClientsUpdateRequest" + } + }, + { + "type": "string", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Clients", + "tags": [ + "Clients" + ], + "summary": "delete Clients", + "parameters": [ + { + "type": "string", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get all CustomStaticPages", + "parameters": [ + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "string", + "name": "htmlBody", + "in": "query" + }, + { + "type": "string", + "name": "slug", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Create CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CustomStaticPagesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages/slug/{slug}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get one CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "CustomStaticPages Slug", + "name": "slug", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get one CustomStaticPages", + "parameters": [ + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "update CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CustomStaticPagesUpdateRequest" + } + }, + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "delete CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/districts": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Districts", + "tags": [ + "Untags" + ], + "summary": "Get all Districts", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Districts", + "tags": [ + "Untags" + ], + "summary": "Create Districts", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/districts/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Districts", + "tags": [ + "Untags" + ], + "summary": "Get one Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Districts", + "tags": [ + "Untags" + ], + "summary": "Update Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Districts", + "tags": [ + "Untags" + ], + "summary": "Delete Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/feedbacks": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Get all Feedbacks", + "parameters": [ + { + "type": "string", + "name": "commentFromEmail", + "in": "query" + }, + { + "type": "string", + "name": "commentFromName", + "in": "query" + }, + { + "type": "string", + "name": "endDate", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "string", + "name": "startDate", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Create Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.FeedbacksCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/feedbacks/statistic/monthly": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for FeedbackMonthlyStats of Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "FeedbackMonthlyStats Feedbacks", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "year", + "name": "year", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/feedbacks/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Get one Feedbacks", + "parameters": [ + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "update Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.FeedbacksUpdateRequest" + } + }, + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "delete Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/galleries": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Galleries", + "tags": [ + "Galleries" + ], + "summary": "Get all Galleries", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Gallery", + "tags": [ + "Galleries" + ], + "summary": "Create Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GalleriesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/galleries/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Gallery by ID", + "tags": [ + "Galleries" + ], + "summary": "Get Gallery by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Gallery", + "tags": [ + "Galleries" + ], + "summary": "Update Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GalleriesUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Gallery (soft delete)", + "tags": [ + "Galleries" + ], + "summary": "Delete Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all GalleryFiles", + "tags": [ + "GalleryFiles" + ], + "summary": "Get all GalleryFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "gallery_id", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating GalleryFile with file upload", + "tags": [ + "GalleryFiles" + ], + "summary": "Create GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "gallery_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Gallery file title", + "name": "title", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing GalleryFile file", + "tags": [ + "GalleryFiles" + ], + "summary": "Viewer GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Gallery File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting GalleryFile by ID", + "tags": [ + "GalleryFiles" + ], + "summary": "Get GalleryFile by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating GalleryFile with file upload", + "tags": [ + "GalleryFiles" + ], + "summary": "Update GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "gallery_id", + "in": "formData" + }, + { + "type": "string", + "description": "Gallery file title", + "name": "title", + "in": "formData" + }, + { + "type": "boolean", + "description": "Is active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting GalleryFile (soft delete)", + "tags": [ + "GalleryFiles" + ], + "summary": "Delete GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ProductSpecifications", + "tags": [ + "ProductSpecifications" + ], + "summary": "Get all ProductSpecifications", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "product_id", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating ProductSpecification with file upload", + "tags": [ + "ProductSpecifications" + ], + "summary": "Create ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Product ID", + "name": "product_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Product specification title", + "name": "title", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing ProductSpecification file", + "tags": [ + "ProductSpecifications" + ], + "summary": "Viewer ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Product Specification File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting ProductSpecification by ID", + "tags": [ + "ProductSpecifications" + ], + "summary": "Get ProductSpecification by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating ProductSpecification", + "tags": [ + "ProductSpecifications" + ], + "summary": "Update ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ProductSpecificationsUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting ProductSpecification (soft delete)", + "tags": [ + "ProductSpecifications" + ], + "summary": "Delete ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Products", + "tags": [ + "Products" + ], + "summary": "Get all Products", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "string", + "name": "variant", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Product with file upload", + "tags": [ + "Products" + ], + "summary": "Create Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Product title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Product variant", + "name": "variant", + "in": "formData" + }, + { + "type": "string", + "description": "Product price", + "name": "price", + "in": "formData" + }, + { + "type": "string", + "description": "Product colors (JSON array)", + "name": "colors", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Product file", + "tags": [ + "Products" + ], + "summary": "Viewer Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Product File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Product by ID", + "tags": [ + "Products" + ], + "summary": "Get Product by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Product with file upload", + "tags": [ + "Products" + ], + "summary": "Update Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Product title", + "name": "title", + "in": "formData" + }, + { + "type": "string", + "description": "Product variant", + "name": "variant", + "in": "formData" + }, + { + "type": "string", + "description": "Product price", + "name": "price", + "in": "formData" + }, + { + "type": "string", + "description": "Product colors (JSON array)", + "name": "colors", + "in": "formData" + }, + { + "type": "boolean", + "description": "Product is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Product (soft delete)", + "tags": [ + "Products" + ], + "summary": "Delete Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Promotions", + "tags": [ + "Promotions" + ], + "summary": "Get all Promotions", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Promotion with file upload", + "tags": [ + "Promotions" + ], + "summary": "Create Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Promotion title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Promotion description", + "name": "description", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Promotion file", + "tags": [ + "Promotions" + ], + "summary": "Viewer Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Promotion File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Promotion by ID", + "tags": [ + "Promotions" + ], + "summary": "Get Promotion by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Promotion", + "tags": [ + "Promotions" + ], + "summary": "Update Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.PromotionsUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Promotion (soft delete)", + "tags": [ + "Promotions" + ], + "summary": "Delete Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/provinces": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Provinces", + "tags": [ + "Untags" + ], + "summary": "Get all Provinces", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Provinces", + "tags": [ + "Untags" + ], + "summary": "Create Provinces", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/provinces/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Provinces", + "tags": [ + "Untags" + ], + "summary": "Get one Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Provinces", + "tags": [ + "Untags" + ], + "summary": "Update Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Provinces", + "tags": [ + "Untags" + ], + "summary": "Delete Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/sales-agents": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all SalesAgents", + "tags": [ + "SalesAgents" + ], + "summary": "Get all SalesAgents", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "agent_type", + "in": "query" + }, + { + "type": "string", + "name": "job_title", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating SalesAgent with file upload", + "tags": [ + "SalesAgents" + ], + "summary": "Create SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "SalesAgent job title", + "name": "job_title", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent phone", + "name": "phone", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent agent type (JSON array)", + "name": "agent_type", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/sales-agents/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing SalesAgent profile picture file", + "tags": [ + "SalesAgents" + ], + "summary": "Viewer SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "SalesAgent File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/sales-agents/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting SalesAgent by ID", + "tags": [ + "SalesAgents" + ], + "summary": "Get SalesAgent by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating SalesAgent with file upload", + "tags": [ + "SalesAgents" + ], + "summary": "Update SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent name", + "name": "name", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent job title", + "name": "job_title", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent phone", + "name": "phone", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent agent type (JSON array)", + "name": "agent_type", + "in": "formData" + }, + { + "type": "boolean", + "description": "SalesAgent is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting SalesAgent (soft delete)", + "tags": [ + "SalesAgents" + ], + "summary": "Delete SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get all UserLevels", + "parameters": [ + { + "type": "integer", + "name": "levelNumber", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "parentLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "provinceId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Create UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/alias/{alias}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get one UserLevels", + "parameters": [ + { + "type": "string", + "description": "UserLevels Alias", + "name": "alias", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/enable-approval": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Enable Approval of Article", + "tags": [ + "UserLevels" + ], + "summary": "EnableApproval Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get one UserLevels", + "parameters": [ + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "update UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "delete UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-role-accesses": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Get all UserRoleAccesses", + "parameters": [ + { + "type": "boolean", + "name": "isActive", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "menuId", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "userRoleId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Create UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRoleAccessesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-role-accesses/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Get one UserRoleAccesses", + "parameters": [ + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "update UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRoleAccessesUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "delete UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-role-level-details": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Get all UserRoleLevelDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Create UserRoleLevelDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-role-level-details/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Get one UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "update UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "delete UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-roles": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Get all UserRoles", + "parameters": [ + { + "type": "string", + "name": "code", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "userLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Create UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRolesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-roles/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Get one UserRoles", + "parameters": [ + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "update UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRolesUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "delete UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Users", + "tags": [ + "Users" + ], + "summary": "Get all Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "string", + "name": "degree", + "in": "query" + }, + { + "type": "string", + "name": "email", + "in": "query" + }, + { + "type": "string", + "name": "fullname", + "in": "query" + }, + { + "type": "string", + "name": "genderType", + "in": "query" + }, + { + "type": "string", + "name": "identityGroup", + "in": "query" + }, + { + "type": "string", + "name": "identityGroupNumber", + "in": "query" + }, + { + "type": "string", + "name": "identityNumber", + "in": "query" + }, + { + "type": "string", + "name": "identityType", + "in": "query" + }, + { + "type": "string", + "name": "phoneNumber", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "userRoleId", + "in": "query" + }, + { + "type": "string", + "name": "username", + "in": "query" + }, + { + "type": "string", + "name": "workType", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Users", + "tags": [ + "Users" + ], + "summary": "Create Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UsersCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/detail/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Users", + "tags": [ + "Users" + ], + "summary": "Get one Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/email-validation": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Email Validation Users", + "tags": [ + "Users" + ], + "summary": "EmailValidation Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserEmailValidationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/forgot-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ForgotPassword Users", + "tags": [ + "Users" + ], + "summary": "ForgotPassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserForgotPassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/info": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ShowUserInfo", + "tags": [ + "Users" + ], + "summary": "ShowInfo Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Login Users", + "tags": [ + "Users" + ], + "summary": "Login Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/otp-request": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for OtpRequest Users", + "tags": [ + "Users" + ], + "summary": "OtpRequest Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserOtpRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/otp-validation": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for OtpValidation Users", + "tags": [ + "Users" + ], + "summary": "OtpValidation Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserOtpValidation" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/pareto-login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ParetoLogin Users", + "tags": [ + "Users" + ], + "summary": "ParetoLogin Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/reset-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ResetPassword Users", + "tags": [ + "Users" + ], + "summary": "ResetPassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserResetPassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/save-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for SavePassword Users", + "tags": [ + "Users" + ], + "summary": "SavePassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserSavePassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/setup-email": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Setup Email Users", + "tags": [ + "Users" + ], + "summary": "SetupEmail Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserEmailValidationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/username/{username}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Users", + "tags": [ + "Users" + ], + "summary": "Get one Users", + "parameters": [ + { + "type": "string", + "description": "Username", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Users", + "tags": [ + "Users" + ], + "summary": "update Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UsersUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Users", + "tags": [ + "Users" + ], + "summary": "delete Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + } + }, + "definitions": { + "paginator.Pagination": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "limit": { + "type": "integer" + }, + "nextPage": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "previousPage": { + "type": "integer" + }, + "sort": { + "type": "string" + }, + "sortBy": { + "type": "string" + }, + "totalPage": { + "type": "integer" + } + } + }, + "request.ActivityLogsCreateRequest": { + "type": "object", + "required": [ + "activityTypeId", + "url" + ], + "properties": { + "activityTypeId": { + "type": "integer" + }, + "articleId": { + "type": "integer" + }, + "url": { + "type": "string" + }, + "userId": { + "type": "integer" + }, + "visitorIp": { + "type": "string" + } + } + }, + "request.ActivityLogsUpdateRequest": { + "type": "object", + "required": [ + "activityTypeId", + "id", + "url" + ], + "properties": { + "activityTypeId": { + "type": "integer" + }, + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "url": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "request.ArticleApprovalsCreateRequest": { + "type": "object", + "required": [ + "articleId", + "message", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleApprovalsUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "message", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleCategoriesCreateRequest": { + "type": "object", + "required": [ + "description", + "statusId", + "title" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "oldCategoryId": { + "type": "integer" + }, + "parentId": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ArticleCategoriesUpdateRequest": { + "type": "object", + "required": [ + "description", + "id", + "statusId", + "title" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "isPublish": { + "type": "boolean" + }, + "parentId": { + "type": "integer" + }, + "publishedAt": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ArticleCommentsApprovalRequest": { + "type": "object", + "required": [ + "id", + "statusId" + ], + "properties": { + "id": { + "type": "integer" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleCommentsCreateRequest": { + "type": "object", + "required": [ + "articleId", + "message" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "isPublic": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "parentId": { + "type": "integer" + } + } + }, + "request.ArticleCommentsUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "message" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "isPublic": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "parentId": { + "type": "integer" + } + } + }, + "request.ArticleFilesUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "isPublish", + "publishedAt", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "fileAlt": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "filePath": { + "type": "string" + }, + "fileThumbnail": { + "type": "string" + }, + "fileUrl": { + "type": "string" + }, + "heightPixel": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "isPublish": { + "type": "boolean" + }, + "publishedAt": { + "type": "string" + }, + "size": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "widthPixel": { + "type": "string" + } + } + }, + "request.ArticlesCreateRequest": { + "type": "object", + "required": [ + "categoryIds", + "description", + "htmlDescription", + "slug", + "tags", + "title", + "typeId" + ], + "properties": { + "aiArticleId": { + "type": "integer" + }, + "categoryIds": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "htmlDescription": { + "type": "string" + }, + "isDraft": { + "type": "boolean" + }, + "isPublish": { + "type": "boolean" + }, + "oldId": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + }, + "typeId": { + "type": "integer" + } + } + }, + "request.ArticlesUpdateRequest": { + "type": "object", + "required": [ + "categoryIds", + "description", + "htmlDescription", + "slug", + "tags", + "title", + "typeId" + ], + "properties": { + "aiArticleId": { + "type": "integer" + }, + "categoryIds": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "htmlDescription": { + "type": "string" + }, + "isDraft": { + "type": "boolean" + }, + "isPublish": { + "type": "boolean" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + }, + "typeId": { + "type": "integer" + } + } + }, + "request.CitiesCreateRequest": { + "type": "object", + "required": [ + "cityName", + "provId" + ], + "properties": { + "cityName": { + "type": "string" + }, + "provId": { + "type": "integer" + } + } + }, + "request.CitiesUpdateRequest": { + "type": "object", + "required": [ + "cityName", + "id", + "provId" + ], + "properties": { + "cityName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "provId": { + "type": "integer" + } + } + }, + "request.ClientsCreateRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "request.ClientsUpdateRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "request.CreateClientApprovalSettingsRequest": { + "type": "object", + "properties": { + "approvalExemptCategories": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptRoles": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptUsers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "autoPublishArticles": { + "type": "boolean" + }, + "defaultWorkflowId": { + "type": "integer", + "minimum": 1 + }, + "isActive": { + "type": "boolean" + }, + "requireApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + }, + "requiresApproval": { + "type": "boolean" + }, + "skipApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "request.CustomStaticPagesCreateRequest": { + "type": "object", + "required": [ + "htmlBody", + "slug", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "htmlBody": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.CustomStaticPagesUpdateRequest": { + "type": "object", + "required": [ + "htmlBody", + "id", + "slug", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "htmlBody": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "request.DisableApprovalRequest": { + "type": "object", + "required": [ + "handleAction", + "reason" + ], + "properties": { + "handleAction": { + "description": "How to handle pending articles", + "type": "string", + "enum": [ + "auto_approve", + "keep_pending", + "reset_to_draft" + ] + }, + "reason": { + "type": "string", + "maxLength": 500 + } + } + }, + "request.EnableApprovalRequest": { + "type": "object", + "properties": { + "defaultWorkflowId": { + "type": "integer", + "minimum": 1 + }, + "reason": { + "type": "string", + "maxLength": 500 + } + } + }, + "request.FeedbacksCreateRequest": { + "type": "object", + "required": [ + "commentFromEmail", + "commentFromName", + "message" + ], + "properties": { + "commentFromEmail": { + "type": "string" + }, + "commentFromName": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "request.FeedbacksUpdateRequest": { + "type": "object", + "required": [ + "commentFromEmail", + "commentFromName", + "id", + "message" + ], + "properties": { + "commentFromEmail": { + "type": "string" + }, + "commentFromName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "message": { + "type": "string" + } + } + }, + "request.GalleriesCreateRequest": { + "type": "object", + "required": [ + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.GalleriesUpdateRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ProductSpecificationsUpdateRequest": { + "type": "object", + "properties": { + "is_active": { + "type": "boolean" + }, + "product_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.PromotionsUpdateRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.SetDefaultWorkflowRequest": { + "type": "object", + "properties": { + "workflowId": { + "type": "integer", + "minimum": 1 + } + } + }, + "request.ToggleApprovalRequest": { + "type": "object", + "properties": { + "requiresApproval": { + "type": "boolean" + } + } + }, + "request.UpdateClientApprovalSettingsRequest": { + "type": "object", + "properties": { + "approvalExemptCategories": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptRoles": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptUsers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "autoPublishArticles": { + "type": "boolean" + }, + "defaultWorkflowId": { + "description": "double pointer to allow nil", + "type": "integer" + }, + "isActive": { + "type": "boolean" + }, + "requireApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + }, + "requiresApproval": { + "type": "boolean" + }, + "skipApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "request.UserEmailValidationRequest": { + "type": "object", + "properties": { + "newEmail": { + "type": "string" + }, + "oldEmail": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserForgotPassword": { + "type": "object", + "properties": { + "username": { + "type": "string" + } + } + }, + "request.UserLevelsApprovalRequest": { + "type": "object", + "required": [ + "ids", + "isApprovalActive" + ], + "properties": { + "ids": { + "type": "string" + }, + "isApprovalActive": { + "type": "boolean" + } + } + }, + "request.UserLevelsCreateRequest": { + "type": "object", + "required": [ + "aliasName", + "levelNumber", + "name" + ], + "properties": { + "aliasName": { + "type": "string" + }, + "group": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "isApprovalActive": { + "type": "boolean" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "parentLevelId": { + "type": "integer" + }, + "provinceId": { + "type": "integer" + } + } + }, + "request.UserLevelsUpdateRequest": { + "type": "object", + "required": [ + "aliasName", + "levelNumber", + "name" + ], + "properties": { + "aliasName": { + "type": "string" + }, + "group": { + "type": "string" + }, + "isApprovalActive": { + "type": "boolean" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "parentLevelId": { + "type": "integer" + }, + "provinceId": { + "type": "integer" + } + } + }, + "request.UserLogin": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserOtpRequest": { + "type": "object", + "required": [ + "email" + ], + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "request.UserOtpValidation": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "otpCode": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserResetPassword": { + "type": "object", + "properties": { + "codeRequest": { + "type": "string" + }, + "confirmPassword": { + "type": "string" + }, + "password": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + }, + "request.UserRoleAccessesCreateRequest": { + "type": "object", + "required": [ + "isAdminEnabled", + "isApprovalEnabled", + "isDeleteEnabled", + "isInsertEnabled", + "isUpdateEnabled", + "isViewEnabled", + "menuId" + ], + "properties": { + "isAdminEnabled": { + "type": "boolean" + }, + "isApprovalEnabled": { + "type": "boolean" + }, + "isDeleteEnabled": { + "type": "boolean" + }, + "isInsertEnabled": { + "type": "boolean" + }, + "isUpdateEnabled": { + "type": "boolean" + }, + "isViewEnabled": { + "type": "boolean" + }, + "menuId": { + "type": "integer" + } + } + }, + "request.UserRoleAccessesUpdateRequest": { + "type": "object", + "required": [ + "id", + "isAdminEnabled", + "isApprovalEnabled", + "isDeleteEnabled", + "isInsertEnabled", + "isUpdateEnabled", + "isViewEnabled", + "menuId", + "userRoleId" + ], + "properties": { + "id": { + "type": "integer" + }, + "isAdminEnabled": { + "type": "boolean" + }, + "isApprovalEnabled": { + "type": "boolean" + }, + "isDeleteEnabled": { + "type": "boolean" + }, + "isInsertEnabled": { + "type": "boolean" + }, + "isUpdateEnabled": { + "type": "boolean" + }, + "isViewEnabled": { + "type": "boolean" + }, + "menuId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + } + } + }, + "request.UserRolesCreateRequest": { + "type": "object", + "required": [ + "code", + "description", + "name", + "statusId", + "userLevelIds", + "userRoleAccess" + ], + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "userRoleAccess": { + "type": "array", + "items": { + "$ref": "#/definitions/request.UserRoleAccessesCreateRequest" + } + } + } + }, + "request.UserRolesUpdateRequest": { + "type": "object", + "required": [ + "code", + "description", + "levelNumber", + "name", + "statusId", + "userLevelIds" + ], + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelIds": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "request.UserSavePassword": { + "type": "object", + "properties": { + "confirmPassword": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "request.UsersCreateRequest": { + "type": "object", + "required": [ + "email", + "fullname", + "password", + "userLevelId", + "userRoleId", + "username" + ], + "properties": { + "address": { + "type": "string" + }, + "dateOfBirth": { + "type": "string" + }, + "degree": { + "type": "string" + }, + "email": { + "type": "string" + }, + "fullname": { + "type": "string" + }, + "genderType": { + "type": "string" + }, + "identityGroup": { + "type": "string" + }, + "identityGroupNumber": { + "type": "string" + }, + "identityNumber": { + "type": "string" + }, + "identityType": { + "type": "string" + }, + "lastEducation": { + "type": "string" + }, + "lastJobTitle": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "userLevelId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "whatsappNumber": { + "type": "string" + }, + "workType": { + "type": "string" + } + } + }, + "request.UsersUpdateRequest": { + "type": "object", + "required": [ + "email", + "fullname", + "userLevelId", + "userRoleId", + "username" + ], + "properties": { + "address": { + "type": "string" + }, + "dateOfBirth": { + "type": "string" + }, + "degree": { + "type": "string" + }, + "email": { + "type": "string" + }, + "fullname": { + "type": "string" + }, + "genderType": { + "type": "string" + }, + "identityGroup": { + "type": "string" + }, + "identityGroupNumber": { + "type": "string" + }, + "identityNumber": { + "type": "string" + }, + "identityType": { + "type": "string" + }, + "lastEducation": { + "type": "string" + }, + "lastJobTitle": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "whatsappNumber": { + "type": "string" + }, + "workType": { + "type": "string" + } + } + }, + "response.BadRequestError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 400 + }, + "message": { + "type": "string", + "example": "bad request" + }, + "success": { + "type": "boolean", + "example": false + } + } + }, + "response.InternalServerError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 500 + }, + "message": { + "type": "string", + "example": "internal server error" + }, + "success": { + "type": "boolean", + "example": false + } + } + }, + "response.Response": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 200 + }, + "data": {}, + "messages": { + "type": "array", + "items": {} + }, + "meta": {}, + "success": { + "type": "boolean", + "example": true + } + } + }, + "response.UnauthorizedError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 401 + }, + "message": { + "type": "string", + "example": "unauthorized access" + }, + "success": { + "type": "boolean", + "example": false + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "", + Host: "", + BasePath: "", + Schemes: []string{}, + Title: "", + Description: "", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..cd9f49a --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,12184 @@ +{ + "swagger": "2.0", + "info": { + "contact": {} + }, + "paths": { + "/activity-logs": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get all ActivityLogs", + "parameters": [ + { + "type": "integer", + "name": "activityTypeId", + "in": "query" + }, + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "url", + "in": "query" + }, + { + "type": "integer", + "name": "userId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Create ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ActivityLogsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/detail/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get one ActivityLogs", + "parameters": [ + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/statistics": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for get activity stats ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "Get activity stats ActivityLogs", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/activity-logs/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "update ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ActivityLogsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ActivityLogs", + "tags": [ + "ActivityLogs" + ], + "summary": "delete ActivityLogs", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ActivityLogs ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-approvals": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Get all ArticleApprovals", + "parameters": [ + { + "type": "integer", + "name": "approvalAtLevel", + "in": "query" + }, + { + "type": "integer", + "name": "approvalBy", + "in": "query" + }, + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Create ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleApprovalsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-approvals/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "Get one ArticleApprovals", + "parameters": [ + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "update ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleApprovalsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleApprovals", + "tags": [ + "ArticleApprovals" + ], + "summary": "delete ArticleApprovals", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleApprovals ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get all ArticleCategories", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "name": "UserLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "UserLevelNumber", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "parentId", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Create ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCategoriesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/old/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategories Old ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/slug/{slug}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "ArticleCategories Slug", + "name": "slug", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/thumbnail/viewer/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for View Thumbnail of ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Viewer ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/thumbnail/{id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Upload ArticleCategories Thumbnail", + "produces": [ + "application/json" + ], + "tags": [ + "Article Categories" + ], + "summary": "Upload ArticleCategories Thumbnail", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload thumbnail", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-categories/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "Get one ArticleCategories", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "update ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCategoriesUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleCategories", + "tags": [ + "Article Categories" + ], + "summary": "delete ArticleCategories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategories ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-category-details": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Get all ArticleCategoryDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Create ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/article-category-details/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "Get one ArticleCategoryDetails", + "parameters": [ + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "update ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleCategoryDetails", + "tags": [ + "Untags" + ], + "summary": "delete ArticleCategoryDetails", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleCategoryDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/article-comments": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Get all ArticleComments", + "parameters": [ + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "integer", + "name": "commentFrom", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublic", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "integer", + "name": "parentId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Create ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-comments/approval": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Approval ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Approval ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-comments/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "Get one ArticleComments", + "parameters": [ + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "update ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleCommentsUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleComments", + "tags": [ + "ArticleComments" + ], + "summary": "delete ArticleComments", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleComments ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Get all ArticleFiles", + "parameters": [ + { + "type": "integer", + "name": "articleId", + "in": "query" + }, + { + "type": "string", + "name": "fileName", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/upload-status/{uploadId}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for GetUploadStatus ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "GetUploadStatus ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Upload ID of ArticleFiles", + "name": "uploadId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Viewer ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Viewer ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Article File Name", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/{articleId}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create ArticleFiles", + "produces": [ + "application/json" + ], + "tags": [ + "Article Files" + ], + "summary": "Upload ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Article ID", + "name": "articleId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/article-files/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Get one ArticleFiles", + "parameters": [ + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Update ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticleFilesUpdateRequest" + } + }, + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete ArticleFiles", + "tags": [ + "Article Files" + ], + "summary": "Delete ArticleFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ArticleFiles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Articles", + "tags": [ + "Articles" + ], + "summary": "Get all Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "category", + "in": "query" + }, + { + "type": "integer", + "name": "categoryId", + "in": "query" + }, + { + "type": "integer", + "name": "createdById", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "boolean", + "name": "isBanner", + "in": "query" + }, + { + "type": "boolean", + "name": "isDraft", + "in": "query" + }, + { + "type": "boolean", + "name": "isPublish", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "string", + "name": "tags", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "typeId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Articles", + "tags": [ + "Articles" + ], + "summary": "Create Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header" + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticlesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/banner/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Update Banner Articles", + "tags": [ + "Articles" + ], + "summary": "Update Banner Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Articles Banner Status", + "name": "isBanner", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/old-id/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Articles", + "tags": [ + "Articles" + ], + "summary": "Get one Articles", + "parameters": [ + { + "type": "integer", + "description": "Articles Old ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/publish-scheduling": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Publish Schedule of Article", + "tags": [ + "Articles" + ], + "summary": "PublishScheduling Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "article id", + "name": "id", + "in": "query" + }, + { + "type": "string", + "description": "publish date", + "name": "date", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/monthly": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ArticleMonthlyStats of Article", + "tags": [ + "Articles" + ], + "summary": "ArticleMonthlyStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "year", + "name": "year", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/summary": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Summary Stats of Article", + "tags": [ + "Articles" + ], + "summary": "SummaryStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/statistic/user-levels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ArticlePerUserLevelStats of Article", + "tags": [ + "Articles" + ], + "summary": "ArticlePerUserLevelStats Articles", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "string", + "description": "start date", + "name": "startDate", + "in": "query" + }, + { + "type": "string", + "description": "start date", + "name": "endDate", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/thumbnail/viewer/{thumbnailName}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for View Thumbnail of Article", + "tags": [ + "Articles" + ], + "summary": "Viewer Articles Thumbnail", + "parameters": [ + { + "type": "string", + "description": "Articles Thumbnail Name", + "name": "thumbnailName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/thumbnail/{id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Save Thumbnail of Articles", + "produces": [ + "application/json" + ], + "tags": [ + "Articles" + ], + "summary": "Save Thumbnail Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload thumbnail", + "name": "files", + "in": "formData", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/articles/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Articles", + "tags": [ + "Articles" + ], + "summary": "Get one Articles", + "parameters": [ + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Articles", + "tags": [ + "Articles" + ], + "summary": "Update Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ArticlesUpdateRequest" + } + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Articles", + "tags": [ + "Articles" + ], + "summary": "Delete Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Articles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Banners", + "tags": [ + "Banners" + ], + "summary": "Get all Banners", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "position", + "in": "query" + }, + { + "type": "string", + "name": "status", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Banner with file upload", + "tags": [ + "Banners" + ], + "summary": "Create Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Banner title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Banner description", + "name": "description", + "in": "formData" + }, + { + "type": "string", + "description": "Banner position", + "name": "position", + "in": "formData" + }, + { + "type": "string", + "description": "Banner status", + "name": "status", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Banner file", + "tags": [ + "Banners" + ], + "summary": "Viewer Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Banner File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/banners/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Banner by ID", + "tags": [ + "Banners" + ], + "summary": "Get Banner by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Banner with file upload", + "tags": [ + "Banners" + ], + "summary": "Update Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Banner title", + "name": "title", + "in": "formData" + }, + { + "type": "string", + "description": "Banner description", + "name": "description", + "in": "formData" + }, + { + "type": "string", + "description": "Banner position", + "name": "position", + "in": "formData" + }, + { + "type": "string", + "description": "Banner status", + "name": "status", + "in": "formData" + }, + { + "type": "boolean", + "description": "Banner is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Banner (soft delete)", + "tags": [ + "Banners" + ], + "summary": "Delete Banner", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Banner ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/cities": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Cities", + "tags": [ + "Untags" + ], + "summary": "Get all Cities", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Cities", + "tags": [ + "Untags" + ], + "summary": "Create Cities", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CitiesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/cities/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Cities", + "tags": [ + "Untags" + ], + "summary": "Get one Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Cities", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Untags" + ], + "summary": "Update Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CitiesUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Cities", + "tags": [ + "Untags" + ], + "summary": "Delete Cities", + "parameters": [ + { + "type": "integer", + "description": "Cities ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/client-approval-settings": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Get Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Update Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UpdateClientApprovalSettingsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Create Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CreateClientApprovalSettingsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting client approval settings", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Delete Client Approval Settings", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/default-workflow": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for setting default workflow for client", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Set Default Workflow", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetDefaultWorkflowRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/disable": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for disabling approval system and auto-publish pending articles", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Disable Approval System", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.DisableApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/enable": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for enabling approval system with smooth transition", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Enable Approval System", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.EnableApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-categories/{action}/{category_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing categories from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Categories", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Category ID", + "name": "category_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-roles/{action}/{role_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing roles from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Roles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Role ID", + "name": "role_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/exempt-users/{action}/{user_id}": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for adding/removing users from approval exemption", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Manage Exempt Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Action: add or remove", + "name": "action", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "User ID", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/client-approval-settings/toggle": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for toggling approval requirement on/off", + "tags": [ + "ClientApprovalSettings" + ], + "summary": "Toggle Approval Requirement", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ToggleApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/clients": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Clients", + "tags": [ + "Clients" + ], + "summary": "Get all Clients", + "parameters": [ + { + "type": "integer", + "name": "createdBy", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Clients", + "tags": [ + "Clients" + ], + "summary": "Create Clients", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ClientsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/clients-test": { + "get": { + "tags": [ + "Clients" + ], + "summary": "TEST CLIENTS", + "responses": {} + } + }, + "/clients/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Clients", + "tags": [ + "Clients" + ], + "summary": "Get one Clients", + "parameters": [ + { + "type": "integer", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Clients", + "tags": [ + "Clients" + ], + "summary": "update Clients", + "parameters": [ + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ClientsUpdateRequest" + } + }, + { + "type": "string", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Clients", + "tags": [ + "Clients" + ], + "summary": "delete Clients", + "parameters": [ + { + "type": "string", + "description": "Clients ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get all CustomStaticPages", + "parameters": [ + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "string", + "name": "htmlBody", + "in": "query" + }, + { + "type": "string", + "name": "slug", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Create CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CustomStaticPagesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages/slug/{slug}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get one CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "CustomStaticPages Slug", + "name": "slug", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/custom-static-pages/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "Get one CustomStaticPages", + "parameters": [ + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "update CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.CustomStaticPagesUpdateRequest" + } + }, + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete CustomStaticPages", + "tags": [ + "CustomStaticPages" + ], + "summary": "delete CustomStaticPages", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "CustomStaticPages ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/districts": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Districts", + "tags": [ + "Untags" + ], + "summary": "Get all Districts", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Districts", + "tags": [ + "Untags" + ], + "summary": "Create Districts", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/districts/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Districts", + "tags": [ + "Untags" + ], + "summary": "Get one Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Districts", + "tags": [ + "Untags" + ], + "summary": "Update Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Districts", + "tags": [ + "Untags" + ], + "summary": "Delete Districts", + "parameters": [ + { + "type": "integer", + "description": "Districts ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/feedbacks": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Get all Feedbacks", + "parameters": [ + { + "type": "string", + "name": "commentFromEmail", + "in": "query" + }, + { + "type": "string", + "name": "commentFromName", + "in": "query" + }, + { + "type": "string", + "name": "endDate", + "in": "query" + }, + { + "type": "string", + "name": "message", + "in": "query" + }, + { + "type": "string", + "name": "startDate", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Create Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.FeedbacksCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/feedbacks/statistic/monthly": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for FeedbackMonthlyStats of Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "FeedbackMonthlyStats Feedbacks", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "year", + "name": "year", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/feedbacks/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "Get one Feedbacks", + "parameters": [ + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "update Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.FeedbacksUpdateRequest" + } + }, + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Feedbacks", + "tags": [ + "Feedbacks" + ], + "summary": "delete Feedbacks", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Feedbacks ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/galleries": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Galleries", + "tags": [ + "Galleries" + ], + "summary": "Get all Galleries", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Gallery", + "tags": [ + "Galleries" + ], + "summary": "Create Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GalleriesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/galleries/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Gallery by ID", + "tags": [ + "Galleries" + ], + "summary": "Get Gallery by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Gallery", + "tags": [ + "Galleries" + ], + "summary": "Update Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.GalleriesUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Gallery (soft delete)", + "tags": [ + "Galleries" + ], + "summary": "Delete Gallery", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all GalleryFiles", + "tags": [ + "GalleryFiles" + ], + "summary": "Get all GalleryFiles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "gallery_id", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating GalleryFile with file upload", + "tags": [ + "GalleryFiles" + ], + "summary": "Create GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "gallery_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Gallery file title", + "name": "title", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing GalleryFile file", + "tags": [ + "GalleryFiles" + ], + "summary": "Viewer GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Gallery File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/gallery-files/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting GalleryFile by ID", + "tags": [ + "GalleryFiles" + ], + "summary": "Get GalleryFile by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating GalleryFile with file upload", + "tags": [ + "GalleryFiles" + ], + "summary": "Update GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Gallery ID", + "name": "gallery_id", + "in": "formData" + }, + { + "type": "string", + "description": "Gallery file title", + "name": "title", + "in": "formData" + }, + { + "type": "boolean", + "description": "Is active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting GalleryFile (soft delete)", + "tags": [ + "GalleryFiles" + ], + "summary": "Delete GalleryFile", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "GalleryFile ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all ProductSpecifications", + "tags": [ + "ProductSpecifications" + ], + "summary": "Get all ProductSpecifications", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "product_id", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating ProductSpecification with file upload", + "tags": [ + "ProductSpecifications" + ], + "summary": "Create ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "integer", + "description": "Product ID", + "name": "product_id", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Product specification title", + "name": "title", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing ProductSpecification file", + "tags": [ + "ProductSpecifications" + ], + "summary": "Viewer ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Product Specification File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/product-specifications/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting ProductSpecification by ID", + "tags": [ + "ProductSpecifications" + ], + "summary": "Get ProductSpecification by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating ProductSpecification", + "tags": [ + "ProductSpecifications" + ], + "summary": "Update ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ProductSpecificationsUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting ProductSpecification (soft delete)", + "tags": [ + "ProductSpecifications" + ], + "summary": "Delete ProductSpecification", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "ProductSpecification ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Products", + "tags": [ + "Products" + ], + "summary": "Get all Products", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "string", + "name": "variant", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Product with file upload", + "tags": [ + "Products" + ], + "summary": "Create Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Product title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Product variant", + "name": "variant", + "in": "formData" + }, + { + "type": "string", + "description": "Product price", + "name": "price", + "in": "formData" + }, + { + "type": "string", + "description": "Product colors (JSON array)", + "name": "colors", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Product file", + "tags": [ + "Products" + ], + "summary": "Viewer Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Product File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/products/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Product by ID", + "tags": [ + "Products" + ], + "summary": "Get Product by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Product with file upload", + "tags": [ + "Products" + ], + "summary": "Update Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Product title", + "name": "title", + "in": "formData" + }, + { + "type": "string", + "description": "Product variant", + "name": "variant", + "in": "formData" + }, + { + "type": "string", + "description": "Product price", + "name": "price", + "in": "formData" + }, + { + "type": "string", + "description": "Product colors (JSON array)", + "name": "colors", + "in": "formData" + }, + { + "type": "boolean", + "description": "Product is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Product (soft delete)", + "tags": [ + "Products" + ], + "summary": "Delete Product", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Product ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Promotions", + "tags": [ + "Promotions" + ], + "summary": "Get all Promotions", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "title", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating Promotion with file upload", + "tags": [ + "Promotions" + ], + "summary": "Create Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "Promotion title", + "name": "title", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Promotion description", + "name": "description", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing Promotion file", + "tags": [ + "Promotions" + ], + "summary": "Viewer Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "Promotion File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/promotions/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting Promotion by ID", + "tags": [ + "Promotions" + ], + "summary": "Get Promotion by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating Promotion", + "tags": [ + "Promotions" + ], + "summary": "Update Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.PromotionsUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting Promotion (soft delete)", + "tags": [ + "Promotions" + ], + "summary": "Delete Promotion", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Promotion ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/provinces": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Provinces", + "tags": [ + "Untags" + ], + "summary": "Get all Provinces", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Provinces", + "tags": [ + "Untags" + ], + "summary": "Create Provinces", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/provinces/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Provinces", + "tags": [ + "Untags" + ], + "summary": "Get one Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Provinces", + "tags": [ + "Untags" + ], + "summary": "Update Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Provinces", + "tags": [ + "Untags" + ], + "summary": "Delete Provinces", + "parameters": [ + { + "type": "integer", + "description": "Provinces ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/sales-agents": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all SalesAgents", + "tags": [ + "SalesAgents" + ], + "summary": "Get all SalesAgents", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "name": "agent_type", + "in": "query" + }, + { + "type": "string", + "name": "job_title", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for creating SalesAgent with file upload", + "tags": [ + "SalesAgents" + ], + "summary": "Create SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "SalesAgent job title", + "name": "job_title", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent phone", + "name": "phone", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent agent type (JSON array)", + "name": "agent_type", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/sales-agents/viewer/{filename}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for viewing SalesAgent profile picture file", + "tags": [ + "SalesAgents" + ], + "summary": "Viewer SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "string", + "description": "SalesAgent File Name (e.g., user_277788.png)", + "name": "filename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/sales-agents/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting SalesAgent by ID", + "tags": [ + "SalesAgents" + ], + "summary": "Get SalesAgent by ID", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for updating SalesAgent with file upload", + "tags": [ + "SalesAgents" + ], + "summary": "Update SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "file", + "description": "Upload file", + "name": "file", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent name", + "name": "name", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent job title", + "name": "job_title", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent phone", + "name": "phone", + "in": "formData" + }, + { + "type": "string", + "description": "SalesAgent agent type (JSON array)", + "name": "agent_type", + "in": "formData" + }, + { + "type": "boolean", + "description": "SalesAgent is_active", + "name": "is_active", + "in": "formData" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for deleting SalesAgent (soft delete)", + "tags": [ + "SalesAgents" + ], + "summary": "Delete SalesAgent", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Client-Key", + "name": "X-Client-Key", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "SalesAgent ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get all UserLevels", + "parameters": [ + { + "type": "integer", + "name": "levelNumber", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "parentLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "provinceId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Create UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/alias/{alias}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get one UserLevels", + "parameters": [ + { + "type": "string", + "description": "UserLevels Alias", + "name": "alias", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/enable-approval": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Enable Approval of Article", + "tags": [ + "UserLevels" + ], + "summary": "EnableApproval Articles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsApprovalRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-levels/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "Get one UserLevels", + "parameters": [ + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "update UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLevelsUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserLevels", + "tags": [ + "UserLevels" + ], + "summary": "delete UserLevels", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserLevels ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-role-accesses": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Get all UserRoleAccesses", + "parameters": [ + { + "type": "boolean", + "name": "isActive", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "menuId", + "in": "query", + "required": true + }, + { + "type": "integer", + "name": "userRoleId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Create UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRoleAccessesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-role-accesses/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "Get one UserRoleAccesses", + "parameters": [ + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "update UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRoleAccessesUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoleAccesses", + "tags": [ + "UserRoleAccesses" + ], + "summary": "delete UserRoleAccesses", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserRoleAccesses ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-role-level-details": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Get all UserRoleLevelDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Create UserRoleLevelDetails", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-role-level-details/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "Get one UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "update UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoleLevelDetails", + "tags": [ + "Task" + ], + "summary": "delete UserRoleLevelDetails", + "parameters": [ + { + "type": "integer", + "description": "UserRoleLevelDetails ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "422": { + "description": "Unprocessable Entity", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.Response" + } + } + } + } + }, + "/user-roles": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Get all UserRoles", + "parameters": [ + { + "type": "string", + "name": "code", + "in": "query" + }, + { + "type": "string", + "name": "description", + "in": "query" + }, + { + "type": "string", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "userLevelId", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Create UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRolesCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/user-roles/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "Get one UserRoles", + "parameters": [ + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "update UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserRolesUpdateRequest" + } + }, + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete UserRoles", + "tags": [ + "UserRoles" + ], + "summary": "delete UserRoles", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "UserRoles ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting all Users", + "tags": [ + "Users" + ], + "summary": "Get all Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "string", + "name": "degree", + "in": "query" + }, + { + "type": "string", + "name": "email", + "in": "query" + }, + { + "type": "string", + "name": "fullname", + "in": "query" + }, + { + "type": "string", + "name": "genderType", + "in": "query" + }, + { + "type": "string", + "name": "identityGroup", + "in": "query" + }, + { + "type": "string", + "name": "identityGroupNumber", + "in": "query" + }, + { + "type": "string", + "name": "identityNumber", + "in": "query" + }, + { + "type": "string", + "name": "identityType", + "in": "query" + }, + { + "type": "string", + "name": "phoneNumber", + "in": "query" + }, + { + "type": "integer", + "name": "statusId", + "in": "query" + }, + { + "type": "integer", + "name": "userRoleId", + "in": "query" + }, + { + "type": "string", + "name": "username", + "in": "query" + }, + { + "type": "string", + "name": "workType", + "in": "query" + }, + { + "type": "integer", + "name": "count", + "in": "query" + }, + { + "type": "integer", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "name": "nextPage", + "in": "query" + }, + { + "type": "integer", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "name": "previousPage", + "in": "query" + }, + { + "type": "string", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "name": "sortBy", + "in": "query" + }, + { + "type": "integer", + "name": "totalPage", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for create Users", + "tags": [ + "Users" + ], + "summary": "Create Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UsersCreateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/detail/{id}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Users", + "tags": [ + "Users" + ], + "summary": "Get one Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/email-validation": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Email Validation Users", + "tags": [ + "Users" + ], + "summary": "EmailValidation Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserEmailValidationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/forgot-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ForgotPassword Users", + "tags": [ + "Users" + ], + "summary": "ForgotPassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserForgotPassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/info": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ShowUserInfo", + "tags": [ + "Users" + ], + "summary": "ShowInfo Users", + "parameters": [ + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Login Users", + "tags": [ + "Users" + ], + "summary": "Login Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/otp-request": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for OtpRequest Users", + "tags": [ + "Users" + ], + "summary": "OtpRequest Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserOtpRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/otp-validation": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for OtpValidation Users", + "tags": [ + "Users" + ], + "summary": "OtpValidation Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserOtpValidation" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/pareto-login": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ParetoLogin Users", + "tags": [ + "Users" + ], + "summary": "ParetoLogin Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserLogin" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/reset-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for ResetPassword Users", + "tags": [ + "Users" + ], + "summary": "ResetPassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserResetPassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/save-password": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for SavePassword Users", + "tags": [ + "Users" + ], + "summary": "SavePassword Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserSavePassword" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/setup-email": { + "post": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for Setup Email Users", + "tags": [ + "Users" + ], + "summary": "SetupEmail Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UserEmailValidationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/username/{username}": { + "get": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for getting one Users", + "tags": [ + "Users" + ], + "summary": "Get one Users", + "parameters": [ + { + "type": "string", + "description": "Username", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + }, + "/users/{id}": { + "put": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for update Users", + "tags": [ + "Users" + ], + "summary": "update Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "string", + "default": "Bearer \u003cAdd access token here\u003e", + "description": "Insert your access token", + "name": "Authorization", + "in": "header" + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Required payload", + "name": "payload", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.UsersUpdateRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + }, + "delete": { + "security": [ + { + "Bearer": [] + } + ], + "description": "API for delete Users", + "tags": [ + "Users" + ], + "summary": "delete Users", + "parameters": [ + { + "type": "string", + "description": "Insert the X-Csrf-Token", + "name": "X-Csrf-Token", + "in": "header", + "required": true + }, + { + "type": "integer", + "description": "Users ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/response.Response" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/response.BadRequestError" + } + }, + "401": { + "description": "Unauthorized", + "schema": { + "$ref": "#/definitions/response.UnauthorizedError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/response.InternalServerError" + } + } + } + } + } + }, + "definitions": { + "paginator.Pagination": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "limit": { + "type": "integer" + }, + "nextPage": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "previousPage": { + "type": "integer" + }, + "sort": { + "type": "string" + }, + "sortBy": { + "type": "string" + }, + "totalPage": { + "type": "integer" + } + } + }, + "request.ActivityLogsCreateRequest": { + "type": "object", + "required": [ + "activityTypeId", + "url" + ], + "properties": { + "activityTypeId": { + "type": "integer" + }, + "articleId": { + "type": "integer" + }, + "url": { + "type": "string" + }, + "userId": { + "type": "integer" + }, + "visitorIp": { + "type": "string" + } + } + }, + "request.ActivityLogsUpdateRequest": { + "type": "object", + "required": [ + "activityTypeId", + "id", + "url" + ], + "properties": { + "activityTypeId": { + "type": "integer" + }, + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "url": { + "type": "string" + }, + "userId": { + "type": "integer" + } + } + }, + "request.ArticleApprovalsCreateRequest": { + "type": "object", + "required": [ + "articleId", + "message", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleApprovalsUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "message", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleCategoriesCreateRequest": { + "type": "object", + "required": [ + "description", + "statusId", + "title" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "oldCategoryId": { + "type": "integer" + }, + "parentId": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ArticleCategoriesUpdateRequest": { + "type": "object", + "required": [ + "description", + "id", + "statusId", + "title" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "isPublish": { + "type": "boolean" + }, + "parentId": { + "type": "integer" + }, + "publishedAt": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ArticleCommentsApprovalRequest": { + "type": "object", + "required": [ + "id", + "statusId" + ], + "properties": { + "id": { + "type": "integer" + }, + "statusId": { + "type": "integer" + } + } + }, + "request.ArticleCommentsCreateRequest": { + "type": "object", + "required": [ + "articleId", + "message" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "isPublic": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "parentId": { + "type": "integer" + } + } + }, + "request.ArticleCommentsUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "message" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "isPublic": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "parentId": { + "type": "integer" + } + } + }, + "request.ArticleFilesUpdateRequest": { + "type": "object", + "required": [ + "articleId", + "id", + "isPublish", + "publishedAt", + "statusId" + ], + "properties": { + "articleId": { + "type": "integer" + }, + "fileAlt": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "filePath": { + "type": "string" + }, + "fileThumbnail": { + "type": "string" + }, + "fileUrl": { + "type": "string" + }, + "heightPixel": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "isPublish": { + "type": "boolean" + }, + "publishedAt": { + "type": "string" + }, + "size": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "widthPixel": { + "type": "string" + } + } + }, + "request.ArticlesCreateRequest": { + "type": "object", + "required": [ + "categoryIds", + "description", + "htmlDescription", + "slug", + "tags", + "title", + "typeId" + ], + "properties": { + "aiArticleId": { + "type": "integer" + }, + "categoryIds": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "htmlDescription": { + "type": "string" + }, + "isDraft": { + "type": "boolean" + }, + "isPublish": { + "type": "boolean" + }, + "oldId": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + }, + "typeId": { + "type": "integer" + } + } + }, + "request.ArticlesUpdateRequest": { + "type": "object", + "required": [ + "categoryIds", + "description", + "htmlDescription", + "slug", + "tags", + "title", + "typeId" + ], + "properties": { + "aiArticleId": { + "type": "integer" + }, + "categoryIds": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "createdById": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "htmlDescription": { + "type": "string" + }, + "isDraft": { + "type": "boolean" + }, + "isPublish": { + "type": "boolean" + }, + "slug": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "tags": { + "type": "string" + }, + "title": { + "type": "string" + }, + "typeId": { + "type": "integer" + } + } + }, + "request.CitiesCreateRequest": { + "type": "object", + "required": [ + "cityName", + "provId" + ], + "properties": { + "cityName": { + "type": "string" + }, + "provId": { + "type": "integer" + } + } + }, + "request.CitiesUpdateRequest": { + "type": "object", + "required": [ + "cityName", + "id", + "provId" + ], + "properties": { + "cityName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "provId": { + "type": "integer" + } + } + }, + "request.ClientsCreateRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "request.ClientsUpdateRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "createdById": { + "type": "integer" + }, + "name": { + "type": "string" + } + } + }, + "request.CreateClientApprovalSettingsRequest": { + "type": "object", + "properties": { + "approvalExemptCategories": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptRoles": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptUsers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "autoPublishArticles": { + "type": "boolean" + }, + "defaultWorkflowId": { + "type": "integer", + "minimum": 1 + }, + "isActive": { + "type": "boolean" + }, + "requireApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + }, + "requiresApproval": { + "type": "boolean" + }, + "skipApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "request.CustomStaticPagesCreateRequest": { + "type": "object", + "required": [ + "htmlBody", + "slug", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "htmlBody": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.CustomStaticPagesUpdateRequest": { + "type": "object", + "required": [ + "htmlBody", + "id", + "slug", + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "htmlBody": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "slug": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + } + }, + "request.DisableApprovalRequest": { + "type": "object", + "required": [ + "handleAction", + "reason" + ], + "properties": { + "handleAction": { + "description": "How to handle pending articles", + "type": "string", + "enum": [ + "auto_approve", + "keep_pending", + "reset_to_draft" + ] + }, + "reason": { + "type": "string", + "maxLength": 500 + } + } + }, + "request.EnableApprovalRequest": { + "type": "object", + "properties": { + "defaultWorkflowId": { + "type": "integer", + "minimum": 1 + }, + "reason": { + "type": "string", + "maxLength": 500 + } + } + }, + "request.FeedbacksCreateRequest": { + "type": "object", + "required": [ + "commentFromEmail", + "commentFromName", + "message" + ], + "properties": { + "commentFromEmail": { + "type": "string" + }, + "commentFromName": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "request.FeedbacksUpdateRequest": { + "type": "object", + "required": [ + "commentFromEmail", + "commentFromName", + "id", + "message" + ], + "properties": { + "commentFromEmail": { + "type": "string" + }, + "commentFromName": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "message": { + "type": "string" + } + } + }, + "request.GalleriesCreateRequest": { + "type": "object", + "required": [ + "title" + ], + "properties": { + "description": { + "type": "string" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.GalleriesUpdateRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.ProductSpecificationsUpdateRequest": { + "type": "object", + "properties": { + "is_active": { + "type": "boolean" + }, + "product_id": { + "type": "integer" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.PromotionsUpdateRequest": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "is_active": { + "type": "boolean" + }, + "thumbnail_path": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "request.SetDefaultWorkflowRequest": { + "type": "object", + "properties": { + "workflowId": { + "type": "integer", + "minimum": 1 + } + } + }, + "request.ToggleApprovalRequest": { + "type": "object", + "properties": { + "requiresApproval": { + "type": "boolean" + } + } + }, + "request.UpdateClientApprovalSettingsRequest": { + "type": "object", + "properties": { + "approvalExemptCategories": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptRoles": { + "type": "array", + "items": { + "type": "integer" + } + }, + "approvalExemptUsers": { + "type": "array", + "items": { + "type": "integer" + } + }, + "autoPublishArticles": { + "type": "boolean" + }, + "defaultWorkflowId": { + "description": "double pointer to allow nil", + "type": "integer" + }, + "isActive": { + "type": "boolean" + }, + "requireApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + }, + "requiresApproval": { + "type": "boolean" + }, + "skipApprovalFor": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "request.UserEmailValidationRequest": { + "type": "object", + "properties": { + "newEmail": { + "type": "string" + }, + "oldEmail": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserForgotPassword": { + "type": "object", + "properties": { + "username": { + "type": "string" + } + } + }, + "request.UserLevelsApprovalRequest": { + "type": "object", + "required": [ + "ids", + "isApprovalActive" + ], + "properties": { + "ids": { + "type": "string" + }, + "isApprovalActive": { + "type": "boolean" + } + } + }, + "request.UserLevelsCreateRequest": { + "type": "object", + "required": [ + "aliasName", + "levelNumber", + "name" + ], + "properties": { + "aliasName": { + "type": "string" + }, + "group": { + "type": "string" + }, + "isActive": { + "type": "boolean" + }, + "isApprovalActive": { + "type": "boolean" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "parentLevelId": { + "type": "integer" + }, + "provinceId": { + "type": "integer" + } + } + }, + "request.UserLevelsUpdateRequest": { + "type": "object", + "required": [ + "aliasName", + "levelNumber", + "name" + ], + "properties": { + "aliasName": { + "type": "string" + }, + "group": { + "type": "string" + }, + "isApprovalActive": { + "type": "boolean" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "parentLevelId": { + "type": "integer" + }, + "provinceId": { + "type": "integer" + } + } + }, + "request.UserLogin": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserOtpRequest": { + "type": "object", + "required": [ + "email" + ], + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "request.UserOtpValidation": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "otpCode": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "request.UserResetPassword": { + "type": "object", + "properties": { + "codeRequest": { + "type": "string" + }, + "confirmPassword": { + "type": "string" + }, + "password": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + }, + "request.UserRoleAccessesCreateRequest": { + "type": "object", + "required": [ + "isAdminEnabled", + "isApprovalEnabled", + "isDeleteEnabled", + "isInsertEnabled", + "isUpdateEnabled", + "isViewEnabled", + "menuId" + ], + "properties": { + "isAdminEnabled": { + "type": "boolean" + }, + "isApprovalEnabled": { + "type": "boolean" + }, + "isDeleteEnabled": { + "type": "boolean" + }, + "isInsertEnabled": { + "type": "boolean" + }, + "isUpdateEnabled": { + "type": "boolean" + }, + "isViewEnabled": { + "type": "boolean" + }, + "menuId": { + "type": "integer" + } + } + }, + "request.UserRoleAccessesUpdateRequest": { + "type": "object", + "required": [ + "id", + "isAdminEnabled", + "isApprovalEnabled", + "isDeleteEnabled", + "isInsertEnabled", + "isUpdateEnabled", + "isViewEnabled", + "menuId", + "userRoleId" + ], + "properties": { + "id": { + "type": "integer" + }, + "isAdminEnabled": { + "type": "boolean" + }, + "isApprovalEnabled": { + "type": "boolean" + }, + "isDeleteEnabled": { + "type": "boolean" + }, + "isInsertEnabled": { + "type": "boolean" + }, + "isUpdateEnabled": { + "type": "boolean" + }, + "isViewEnabled": { + "type": "boolean" + }, + "menuId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + } + } + }, + "request.UserRolesCreateRequest": { + "type": "object", + "required": [ + "code", + "description", + "name", + "statusId", + "userLevelIds", + "userRoleAccess" + ], + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelIds": { + "type": "array", + "items": { + "type": "integer" + } + }, + "userRoleAccess": { + "type": "array", + "items": { + "$ref": "#/definitions/request.UserRoleAccessesCreateRequest" + } + } + } + }, + "request.UserRolesUpdateRequest": { + "type": "object", + "required": [ + "code", + "description", + "levelNumber", + "name", + "statusId", + "userLevelIds" + ], + "properties": { + "code": { + "type": "string" + }, + "description": { + "type": "string" + }, + "levelNumber": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelIds": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "request.UserSavePassword": { + "type": "object", + "properties": { + "confirmPassword": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "request.UsersCreateRequest": { + "type": "object", + "required": [ + "email", + "fullname", + "password", + "userLevelId", + "userRoleId", + "username" + ], + "properties": { + "address": { + "type": "string" + }, + "dateOfBirth": { + "type": "string" + }, + "degree": { + "type": "string" + }, + "email": { + "type": "string" + }, + "fullname": { + "type": "string" + }, + "genderType": { + "type": "string" + }, + "identityGroup": { + "type": "string" + }, + "identityGroupNumber": { + "type": "string" + }, + "identityNumber": { + "type": "string" + }, + "identityType": { + "type": "string" + }, + "lastEducation": { + "type": "string" + }, + "lastJobTitle": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "userLevelId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "whatsappNumber": { + "type": "string" + }, + "workType": { + "type": "string" + } + } + }, + "request.UsersUpdateRequest": { + "type": "object", + "required": [ + "email", + "fullname", + "userLevelId", + "userRoleId", + "username" + ], + "properties": { + "address": { + "type": "string" + }, + "dateOfBirth": { + "type": "string" + }, + "degree": { + "type": "string" + }, + "email": { + "type": "string" + }, + "fullname": { + "type": "string" + }, + "genderType": { + "type": "string" + }, + "identityGroup": { + "type": "string" + }, + "identityGroupNumber": { + "type": "string" + }, + "identityNumber": { + "type": "string" + }, + "identityType": { + "type": "string" + }, + "lastEducation": { + "type": "string" + }, + "lastJobTitle": { + "type": "string" + }, + "phoneNumber": { + "type": "string" + }, + "statusId": { + "type": "integer" + }, + "userLevelId": { + "type": "integer" + }, + "userRoleId": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "whatsappNumber": { + "type": "string" + }, + "workType": { + "type": "string" + } + } + }, + "response.BadRequestError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 400 + }, + "message": { + "type": "string", + "example": "bad request" + }, + "success": { + "type": "boolean", + "example": false + } + } + }, + "response.InternalServerError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 500 + }, + "message": { + "type": "string", + "example": "internal server error" + }, + "success": { + "type": "boolean", + "example": false + } + } + }, + "response.Response": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 200 + }, + "data": {}, + "messages": { + "type": "array", + "items": {} + }, + "meta": {}, + "success": { + "type": "boolean", + "example": true + } + } + }, + "response.UnauthorizedError": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "example": 401 + }, + "message": { + "type": "string", + "example": "unauthorized access" + }, + "success": { + "type": "boolean", + "example": false + } + } + } + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..e5b4efe --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,7823 @@ +definitions: + paginator.Pagination: + properties: + count: + type: integer + limit: + type: integer + nextPage: + type: integer + page: + type: integer + previousPage: + type: integer + sort: + type: string + sortBy: + type: string + totalPage: + type: integer + type: object + request.ActivityLogsCreateRequest: + properties: + activityTypeId: + type: integer + articleId: + type: integer + url: + type: string + userId: + type: integer + visitorIp: + type: string + required: + - activityTypeId + - url + type: object + request.ActivityLogsUpdateRequest: + properties: + activityTypeId: + type: integer + articleId: + type: integer + id: + type: integer + url: + type: string + userId: + type: integer + required: + - activityTypeId + - id + - url + type: object + request.ArticleApprovalsCreateRequest: + properties: + articleId: + type: integer + message: + type: string + statusId: + type: integer + required: + - articleId + - message + - statusId + type: object + request.ArticleApprovalsUpdateRequest: + properties: + articleId: + type: integer + id: + type: integer + message: + type: string + statusId: + type: integer + required: + - articleId + - id + - message + - statusId + type: object + request.ArticleCategoriesCreateRequest: + properties: + createdById: + type: integer + description: + type: string + oldCategoryId: + type: integer + parentId: + type: integer + slug: + type: string + statusId: + type: integer + tags: + type: string + title: + type: string + required: + - description + - statusId + - title + type: object + request.ArticleCategoriesUpdateRequest: + properties: + createdById: + type: integer + description: + type: string + id: + type: integer + isPublish: + type: boolean + parentId: + type: integer + publishedAt: + type: string + slug: + type: string + statusId: + type: integer + tags: + type: string + title: + type: string + required: + - description + - id + - statusId + - title + type: object + request.ArticleCommentsApprovalRequest: + properties: + id: + type: integer + statusId: + type: integer + required: + - id + - statusId + type: object + request.ArticleCommentsCreateRequest: + properties: + articleId: + type: integer + isPublic: + type: boolean + message: + type: string + parentId: + type: integer + required: + - articleId + - message + type: object + request.ArticleCommentsUpdateRequest: + properties: + articleId: + type: integer + id: + type: integer + isPublic: + type: boolean + message: + type: string + parentId: + type: integer + required: + - articleId + - id + - message + type: object + request.ArticleFilesUpdateRequest: + properties: + articleId: + type: integer + fileAlt: + type: string + fileName: + type: string + filePath: + type: string + fileThumbnail: + type: string + fileUrl: + type: string + heightPixel: + type: string + id: + type: integer + isPublish: + type: boolean + publishedAt: + type: string + size: + type: string + statusId: + type: integer + widthPixel: + type: string + required: + - articleId + - id + - isPublish + - publishedAt + - statusId + type: object + request.ArticlesCreateRequest: + properties: + aiArticleId: + type: integer + categoryIds: + type: string + createdAt: + type: string + createdById: + type: integer + description: + type: string + htmlDescription: + type: string + isDraft: + type: boolean + isPublish: + type: boolean + oldId: + type: integer + slug: + type: string + tags: + type: string + title: + type: string + typeId: + type: integer + required: + - categoryIds + - description + - htmlDescription + - slug + - tags + - title + - typeId + type: object + request.ArticlesUpdateRequest: + properties: + aiArticleId: + type: integer + categoryIds: + type: string + createdAt: + type: string + createdById: + type: integer + description: + type: string + htmlDescription: + type: string + isDraft: + type: boolean + isPublish: + type: boolean + slug: + type: string + statusId: + type: integer + tags: + type: string + title: + type: string + typeId: + type: integer + required: + - categoryIds + - description + - htmlDescription + - slug + - tags + - title + - typeId + type: object + request.CitiesCreateRequest: + properties: + cityName: + type: string + provId: + type: integer + required: + - cityName + - provId + type: object + request.CitiesUpdateRequest: + properties: + cityName: + type: string + id: + type: integer + provId: + type: integer + required: + - cityName + - id + - provId + type: object + request.ClientsCreateRequest: + properties: + createdById: + type: integer + name: + type: string + required: + - name + type: object + request.ClientsUpdateRequest: + properties: + createdById: + type: integer + name: + type: string + required: + - name + type: object + request.CreateClientApprovalSettingsRequest: + properties: + approvalExemptCategories: + items: + type: integer + type: array + approvalExemptRoles: + items: + type: integer + type: array + approvalExemptUsers: + items: + type: integer + type: array + autoPublishArticles: + type: boolean + defaultWorkflowId: + minimum: 1 + type: integer + isActive: + type: boolean + requireApprovalFor: + items: + type: string + type: array + requiresApproval: + type: boolean + skipApprovalFor: + items: + type: string + type: array + type: object + request.CustomStaticPagesCreateRequest: + properties: + description: + type: string + htmlBody: + type: string + slug: + type: string + title: + type: string + required: + - htmlBody + - slug + - title + type: object + request.CustomStaticPagesUpdateRequest: + properties: + description: + type: string + htmlBody: + type: string + id: + type: integer + slug: + type: string + title: + type: string + updatedAt: + type: string + required: + - htmlBody + - id + - slug + - title + type: object + request.DisableApprovalRequest: + properties: + handleAction: + description: How to handle pending articles + enum: + - auto_approve + - keep_pending + - reset_to_draft + type: string + reason: + maxLength: 500 + type: string + required: + - handleAction + - reason + type: object + request.EnableApprovalRequest: + properties: + defaultWorkflowId: + minimum: 1 + type: integer + reason: + maxLength: 500 + type: string + type: object + request.FeedbacksCreateRequest: + properties: + commentFromEmail: + type: string + commentFromName: + type: string + message: + type: string + required: + - commentFromEmail + - commentFromName + - message + type: object + request.FeedbacksUpdateRequest: + properties: + commentFromEmail: + type: string + commentFromName: + type: string + id: + type: integer + message: + type: string + required: + - commentFromEmail + - commentFromName + - id + - message + type: object + request.GalleriesCreateRequest: + properties: + description: + type: string + thumbnail_path: + type: string + title: + type: string + required: + - title + type: object + request.GalleriesUpdateRequest: + properties: + description: + type: string + is_active: + type: boolean + thumbnail_path: + type: string + title: + type: string + type: object + request.ProductSpecificationsUpdateRequest: + properties: + is_active: + type: boolean + product_id: + type: integer + thumbnail_path: + type: string + title: + type: string + type: object + request.PromotionsUpdateRequest: + properties: + description: + type: string + is_active: + type: boolean + thumbnail_path: + type: string + title: + type: string + type: object + request.SetDefaultWorkflowRequest: + properties: + workflowId: + minimum: 1 + type: integer + type: object + request.ToggleApprovalRequest: + properties: + requiresApproval: + type: boolean + type: object + request.UpdateClientApprovalSettingsRequest: + properties: + approvalExemptCategories: + items: + type: integer + type: array + approvalExemptRoles: + items: + type: integer + type: array + approvalExemptUsers: + items: + type: integer + type: array + autoPublishArticles: + type: boolean + defaultWorkflowId: + description: double pointer to allow nil + type: integer + isActive: + type: boolean + requireApprovalFor: + items: + type: string + type: array + requiresApproval: + type: boolean + skipApprovalFor: + items: + type: string + type: array + type: object + request.UserEmailValidationRequest: + properties: + newEmail: + type: string + oldEmail: + type: string + password: + type: string + username: + type: string + type: object + request.UserForgotPassword: + properties: + username: + type: string + type: object + request.UserLevelsApprovalRequest: + properties: + ids: + type: string + isApprovalActive: + type: boolean + required: + - ids + - isApprovalActive + type: object + request.UserLevelsCreateRequest: + properties: + aliasName: + type: string + group: + type: string + isActive: + type: boolean + isApprovalActive: + type: boolean + levelNumber: + type: integer + name: + type: string + parentLevelId: + type: integer + provinceId: + type: integer + required: + - aliasName + - levelNumber + - name + type: object + request.UserLevelsUpdateRequest: + properties: + aliasName: + type: string + group: + type: string + isApprovalActive: + type: boolean + levelNumber: + type: integer + name: + type: string + parentLevelId: + type: integer + provinceId: + type: integer + required: + - aliasName + - levelNumber + - name + type: object + request.UserLogin: + properties: + password: + type: string + refreshToken: + type: string + username: + type: string + type: object + request.UserOtpRequest: + properties: + email: + type: string + name: + type: string + required: + - email + type: object + request.UserOtpValidation: + properties: + email: + type: string + otpCode: + type: string + username: + type: string + type: object + request.UserResetPassword: + properties: + codeRequest: + type: string + confirmPassword: + type: string + password: + type: string + userId: + type: string + type: object + request.UserRoleAccessesCreateRequest: + properties: + isAdminEnabled: + type: boolean + isApprovalEnabled: + type: boolean + isDeleteEnabled: + type: boolean + isInsertEnabled: + type: boolean + isUpdateEnabled: + type: boolean + isViewEnabled: + type: boolean + menuId: + type: integer + required: + - isAdminEnabled + - isApprovalEnabled + - isDeleteEnabled + - isInsertEnabled + - isUpdateEnabled + - isViewEnabled + - menuId + type: object + request.UserRoleAccessesUpdateRequest: + properties: + id: + type: integer + isAdminEnabled: + type: boolean + isApprovalEnabled: + type: boolean + isDeleteEnabled: + type: boolean + isInsertEnabled: + type: boolean + isUpdateEnabled: + type: boolean + isViewEnabled: + type: boolean + menuId: + type: integer + userRoleId: + type: integer + required: + - id + - isAdminEnabled + - isApprovalEnabled + - isDeleteEnabled + - isInsertEnabled + - isUpdateEnabled + - isViewEnabled + - menuId + - userRoleId + type: object + request.UserRolesCreateRequest: + properties: + code: + type: string + description: + type: string + name: + type: string + statusId: + type: integer + userLevelIds: + items: + type: integer + type: array + userRoleAccess: + items: + $ref: '#/definitions/request.UserRoleAccessesCreateRequest' + type: array + required: + - code + - description + - name + - statusId + - userLevelIds + - userRoleAccess + type: object + request.UserRolesUpdateRequest: + properties: + code: + type: string + description: + type: string + levelNumber: + type: integer + name: + type: string + statusId: + type: integer + userLevelIds: + items: + type: integer + type: array + required: + - code + - description + - levelNumber + - name + - statusId + - userLevelIds + type: object + request.UserSavePassword: + properties: + confirmPassword: + type: string + password: + type: string + type: object + request.UsersCreateRequest: + properties: + address: + type: string + dateOfBirth: + type: string + degree: + type: string + email: + type: string + fullname: + type: string + genderType: + type: string + identityGroup: + type: string + identityGroupNumber: + type: string + identityNumber: + type: string + identityType: + type: string + lastEducation: + type: string + lastJobTitle: + type: string + password: + type: string + phoneNumber: + type: string + userLevelId: + type: integer + userRoleId: + type: integer + username: + type: string + whatsappNumber: + type: string + workType: + type: string + required: + - email + - fullname + - password + - userLevelId + - userRoleId + - username + type: object + request.UsersUpdateRequest: + properties: + address: + type: string + dateOfBirth: + type: string + degree: + type: string + email: + type: string + fullname: + type: string + genderType: + type: string + identityGroup: + type: string + identityGroupNumber: + type: string + identityNumber: + type: string + identityType: + type: string + lastEducation: + type: string + lastJobTitle: + type: string + phoneNumber: + type: string + statusId: + type: integer + userLevelId: + type: integer + userRoleId: + type: integer + username: + type: string + whatsappNumber: + type: string + workType: + type: string + required: + - email + - fullname + - userLevelId + - userRoleId + - username + type: object + response.BadRequestError: + properties: + code: + example: 400 + type: integer + message: + example: bad request + type: string + success: + example: false + type: boolean + type: object + response.InternalServerError: + properties: + code: + example: 500 + type: integer + message: + example: internal server error + type: string + success: + example: false + type: boolean + type: object + response.Response: + properties: + code: + example: 200 + type: integer + data: {} + messages: + items: {} + type: array + meta: {} + success: + example: true + type: boolean + type: object + response.UnauthorizedError: + properties: + code: + example: 401 + type: integer + message: + example: unauthorized access + type: string + success: + example: false + type: boolean + type: object +info: + contact: {} +paths: + /activity-logs: + get: + description: API for getting all ActivityLogs + parameters: + - in: query + name: activityTypeId + type: integer + - in: query + name: articleId + type: integer + - in: query + name: url + type: string + - in: query + name: userId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ActivityLogs + tags: + - ActivityLogs + post: + description: API for create ActivityLogs + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ActivityLogsCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create ActivityLogs + tags: + - ActivityLogs + /activity-logs/{id}: + delete: + description: API for delete ActivityLogs + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ActivityLogs ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete ActivityLogs + tags: + - ActivityLogs + put: + description: API for update ActivityLogs + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ActivityLogsUpdateRequest' + - description: ActivityLogs ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update ActivityLogs + tags: + - ActivityLogs + /activity-logs/detail/{id}: + get: + description: API for getting one ActivityLogs + parameters: + - description: ActivityLogs ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ActivityLogs + tags: + - ActivityLogs + /activity-logs/statistics: + get: + description: API for get activity stats ActivityLogs + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get activity stats ActivityLogs + tags: + - ActivityLogs + /article-approvals: + get: + description: API for getting all ArticleApprovals + parameters: + - in: query + name: approvalAtLevel + type: integer + - in: query + name: approvalBy + type: integer + - in: query + name: articleId + type: integer + - in: query + name: message + type: string + - in: query + name: statusId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ArticleApprovals + tags: + - ArticleApprovals + post: + description: API for create ArticleApprovals + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleApprovalsCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create ArticleApprovals + tags: + - ArticleApprovals + /article-approvals/{id}: + delete: + description: API for delete ArticleApprovals + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleApprovals ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete ArticleApprovals + tags: + - ArticleApprovals + get: + description: API for getting one ArticleApprovals + parameters: + - description: ArticleApprovals ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleApprovals + tags: + - ArticleApprovals + put: + description: API for update ArticleApprovals + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleApprovalsUpdateRequest' + - description: ArticleApprovals ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update ArticleApprovals + tags: + - ArticleApprovals + /article-categories: + get: + description: API for getting all ArticleCategories + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - in: query + name: UserLevelId + type: integer + - in: query + name: UserLevelNumber + type: integer + - in: query + name: description + type: string + - in: query + name: isPublish + type: boolean + - in: query + name: parentId + type: integer + - in: query + name: statusId + type: integer + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ArticleCategories + tags: + - Article Categories + post: + description: API for create ArticleCategories + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleCategoriesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create ArticleCategories + tags: + - Article Categories + /article-categories/{id}: + delete: + description: API for delete ArticleCategories + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleCategories ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete ArticleCategories + tags: + - Article Categories + get: + description: API for getting one ArticleCategories + parameters: + - description: ArticleCategories ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleCategories + tags: + - Article Categories + put: + description: API for update ArticleCategories + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleCategoriesUpdateRequest' + - description: ArticleCategories ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update ArticleCategories + tags: + - Article Categories + /article-categories/old/{id}: + get: + description: API for getting one ArticleCategories + parameters: + - description: ArticleCategories Old ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleCategories + tags: + - Article Categories + /article-categories/slug/{slug}: + get: + description: API for getting one ArticleCategories + parameters: + - description: ArticleCategories Slug + in: path + name: slug + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleCategories + tags: + - Article Categories + /article-categories/thumbnail/{id}: + post: + description: API for Upload ArticleCategories Thumbnail + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Upload thumbnail + in: formData + name: files + required: true + type: file + - description: ArticleCategories ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Upload ArticleCategories Thumbnail + tags: + - Article Categories + /article-categories/thumbnail/viewer/{id}: + get: + description: API for View Thumbnail of ArticleCategories + parameters: + - description: ArticleCategories ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer ArticleCategories + tags: + - Article Categories + /article-category-details: + get: + description: API for getting all ArticleCategoryDetails + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get all ArticleCategoryDetails + tags: + - Untags + post: + description: API for create ArticleCategoryDetails + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Create ArticleCategoryDetails + tags: + - Untags + /article-category-details/{id}: + delete: + description: API for delete ArticleCategoryDetails + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleCategoryDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: delete ArticleCategoryDetails + tags: + - Untags + get: + description: API for getting one ArticleCategoryDetails + parameters: + - description: ArticleCategoryDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get one ArticleCategoryDetails + tags: + - Untags + put: + description: API for update ArticleCategoryDetails + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleCategoryDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: update ArticleCategoryDetails + tags: + - Untags + /article-comments: + get: + description: API for getting all ArticleComments + parameters: + - in: query + name: articleId + type: integer + - in: query + name: commentFrom + type: integer + - in: query + name: isPublic + type: boolean + - in: query + name: message + type: string + - in: query + name: parentId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ArticleComments + tags: + - ArticleComments + post: + description: API for create ArticleComments + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleCommentsCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create ArticleComments + tags: + - ArticleComments + /article-comments/{id}: + delete: + description: API for delete ArticleComments + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleComments ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete ArticleComments + tags: + - ArticleComments + get: + description: API for getting one ArticleComments + parameters: + - description: ArticleComments ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleComments + tags: + - ArticleComments + put: + description: API for update ArticleComments + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleCommentsUpdateRequest' + - description: ArticleComments ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update ArticleComments + tags: + - ArticleComments + /article-comments/approval: + post: + description: API for Approval ArticleComments + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleCommentsApprovalRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Approval ArticleComments + tags: + - ArticleComments + /article-files: + get: + description: API for getting all ArticleFiles + parameters: + - in: query + name: articleId + type: integer + - in: query + name: fileName + type: string + - in: query + name: isPublish + type: boolean + - in: query + name: statusId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ArticleFiles + tags: + - Article Files + /article-files/{articleId}: + post: + description: API for create ArticleFiles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Upload file + in: formData + name: files + required: true + type: file + - description: Article ID + in: path + name: articleId + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Upload ArticleFiles + tags: + - Article Files + /article-files/{id}: + delete: + description: API for delete ArticleFiles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: ArticleFiles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete ArticleFiles + tags: + - Article Files + get: + description: API for getting one ArticleFiles + parameters: + - description: ArticleFiles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one ArticleFiles + tags: + - Article Files + put: + description: API for update ArticleFiles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticleFilesUpdateRequest' + - description: ArticleFiles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update ArticleFiles + tags: + - Article Files + /article-files/upload-status/{uploadId}: + get: + description: API for GetUploadStatus ArticleFiles + parameters: + - description: Upload ID of ArticleFiles + in: path + name: uploadId + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: GetUploadStatus ArticleFiles + tags: + - Article Files + /article-files/viewer/{filename}: + get: + description: API for Viewer ArticleFiles + parameters: + - description: Article File Name + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer ArticleFiles + tags: + - Article Files + /articles: + get: + description: API for getting all Articles + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: category + type: string + - in: query + name: categoryId + type: integer + - in: query + name: createdById + type: integer + - in: query + name: description + type: string + - in: query + name: isBanner + type: boolean + - in: query + name: isDraft + type: boolean + - in: query + name: isPublish + type: boolean + - in: query + name: statusId + type: integer + - in: query + name: tags + type: string + - in: query + name: title + type: string + - in: query + name: typeId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Articles + tags: + - Articles + post: + description: API for create Articles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticlesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Articles + tags: + - Articles + /articles/{id}: + delete: + description: API for delete Articles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Articles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Articles + tags: + - Articles + get: + description: API for getting one Articles + parameters: + - description: Articles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Articles + tags: + - Articles + put: + description: API for update Articles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ArticlesUpdateRequest' + - description: Articles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Articles + tags: + - Articles + /articles/banner/{id}: + put: + description: API for Update Banner Articles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Articles ID + in: path + name: id + required: true + type: integer + - description: Articles Banner Status + in: query + name: isBanner + required: true + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Banner Articles + tags: + - Articles + /articles/old-id/{id}: + get: + description: API for getting one Articles + parameters: + - description: Articles Old ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Articles + tags: + - Articles + /articles/publish-scheduling: + post: + description: API for Publish Schedule of Article + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: article id + in: query + name: id + type: integer + - description: publish date + in: query + name: date + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: PublishScheduling Articles + tags: + - Articles + /articles/statistic/monthly: + get: + description: API for ArticleMonthlyStats of Article + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: year + in: query + name: year + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ArticleMonthlyStats Articles + tags: + - Articles + /articles/statistic/summary: + get: + description: API for Summary Stats of Article + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: SummaryStats Articles + tags: + - Articles + /articles/statistic/user-levels: + get: + description: API for ArticlePerUserLevelStats of Article + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: start date + in: query + name: startDate + type: string + - description: start date + in: query + name: endDate + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ArticlePerUserLevelStats Articles + tags: + - Articles + /articles/thumbnail/{id}: + post: + description: API for Save Thumbnail of Articles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Upload thumbnail + in: formData + name: files + required: true + type: file + - description: Articles ID + in: path + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Save Thumbnail Articles + tags: + - Articles + /articles/thumbnail/viewer/{thumbnailName}: + get: + description: API for View Thumbnail of Article + parameters: + - description: Articles Thumbnail Name + in: path + name: thumbnailName + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer Articles Thumbnail + tags: + - Articles + /banners: + get: + description: API for getting all Banners + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: position + type: string + - in: query + name: status + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Banners + tags: + - Banners + post: + description: API for creating Banner with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: Banner title + in: formData + name: title + required: true + type: string + - description: Banner description + in: formData + name: description + type: string + - description: Banner position + in: formData + name: position + type: string + - description: Banner status + in: formData + name: status + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Banner + tags: + - Banners + /banners/{id}: + delete: + description: API for deleting Banner (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Banner ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Banner + tags: + - Banners + get: + description: API for getting Banner by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Banner ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get Banner by ID + tags: + - Banners + put: + description: API for updating Banner with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Banner ID + in: path + name: id + required: true + type: integer + - description: Upload file + in: formData + name: file + type: file + - description: Banner title + in: formData + name: title + type: string + - description: Banner description + in: formData + name: description + type: string + - description: Banner position + in: formData + name: position + type: string + - description: Banner status + in: formData + name: status + type: string + - description: Banner is_active + in: formData + name: is_active + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Banner + tags: + - Banners + /banners/viewer/{filename}: + get: + description: API for viewing Banner file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Banner File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer Banner + tags: + - Banners + /cities: + get: + description: API for getting all Cities + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get all Cities + tags: + - Untags + post: + description: API for create Cities + parameters: + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.CitiesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Create Cities + tags: + - Untags + /cities/{id}: + delete: + description: API for delete Cities + parameters: + - description: Cities ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Delete Cities + tags: + - Untags + get: + description: API for getting one Cities + parameters: + - description: Cities ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get one Cities + tags: + - Untags + put: + consumes: + - application/json + description: API for update Cities + parameters: + - description: Cities ID + in: path + name: id + required: true + type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.CitiesUpdateRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Update Cities + tags: + - Untags + /client-approval-settings: + delete: + description: API for deleting client approval settings + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Client Approval Settings + tags: + - ClientApprovalSettings + get: + description: API for getting client approval settings + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get Client Approval Settings + tags: + - ClientApprovalSettings + post: + description: API for creating client approval settings + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.CreateClientApprovalSettingsRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Client Approval Settings + tags: + - ClientApprovalSettings + put: + description: API for updating client approval settings + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UpdateClientApprovalSettingsRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Client Approval Settings + tags: + - ClientApprovalSettings + /client-approval-settings/default-workflow: + post: + description: API for setting default workflow for client + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.SetDefaultWorkflowRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Set Default Workflow + tags: + - ClientApprovalSettings + /client-approval-settings/disable: + post: + description: API for disabling approval system and auto-publish pending articles + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.DisableApprovalRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Disable Approval System + tags: + - ClientApprovalSettings + /client-approval-settings/enable: + post: + description: API for enabling approval system with smooth transition + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.EnableApprovalRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Enable Approval System + tags: + - ClientApprovalSettings + /client-approval-settings/exempt-categories/{action}/{category_id}: + post: + description: API for adding/removing categories from approval exemption + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: 'Action: add or remove' + in: path + name: action + required: true + type: string + - description: Category ID + in: path + name: category_id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Manage Exempt Categories + tags: + - ClientApprovalSettings + /client-approval-settings/exempt-roles/{action}/{role_id}: + post: + description: API for adding/removing roles from approval exemption + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: 'Action: add or remove' + in: path + name: action + required: true + type: string + - description: Role ID + in: path + name: role_id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Manage Exempt Roles + tags: + - ClientApprovalSettings + /client-approval-settings/exempt-users/{action}/{user_id}: + post: + description: API for adding/removing users from approval exemption + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: 'Action: add or remove' + in: path + name: action + required: true + type: string + - description: User ID + in: path + name: user_id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Manage Exempt Users + tags: + - ClientApprovalSettings + /client-approval-settings/toggle: + post: + description: API for toggling approval requirement on/off + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ToggleApprovalRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Toggle Approval Requirement + tags: + - ClientApprovalSettings + /clients: + get: + description: API for getting all Clients + parameters: + - in: query + name: createdBy + type: integer + - in: query + name: name + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Clients + tags: + - Clients + post: + description: API for create Clients + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ClientsCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Clients + tags: + - Clients + /clients-test: + get: + responses: {} + summary: TEST CLIENTS + tags: + - Clients + /clients/{id}: + delete: + description: API for delete Clients + parameters: + - description: Clients ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete Clients + tags: + - Clients + get: + description: API for getting one Clients + parameters: + - description: Clients ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Clients + tags: + - Clients + put: + description: API for update Clients + parameters: + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ClientsUpdateRequest' + - description: Clients ID + in: path + name: id + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update Clients + tags: + - Clients + /custom-static-pages: + get: + description: API for getting all CustomStaticPages + parameters: + - in: query + name: description + type: string + - in: query + name: htmlBody + type: string + - in: query + name: slug + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all CustomStaticPages + tags: + - CustomStaticPages + post: + description: API for create CustomStaticPages + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.CustomStaticPagesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create CustomStaticPages + tags: + - CustomStaticPages + /custom-static-pages/{id}: + delete: + description: API for delete CustomStaticPages + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: CustomStaticPages ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete CustomStaticPages + tags: + - CustomStaticPages + get: + description: API for getting one CustomStaticPages + parameters: + - description: CustomStaticPages ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one CustomStaticPages + tags: + - CustomStaticPages + put: + description: API for update CustomStaticPages + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.CustomStaticPagesUpdateRequest' + - description: CustomStaticPages ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update CustomStaticPages + tags: + - CustomStaticPages + /custom-static-pages/slug/{slug}: + get: + description: API for getting one CustomStaticPages + parameters: + - description: CustomStaticPages Slug + in: path + name: slug + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one CustomStaticPages + tags: + - CustomStaticPages + /districts: + get: + description: API for getting all Districts + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get all Districts + tags: + - Untags + post: + description: API for create Districts + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Create Districts + tags: + - Untags + /districts/{id}: + delete: + description: API for delete Districts + parameters: + - description: Districts ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Delete Districts + tags: + - Untags + get: + description: API for getting one Districts + parameters: + - description: Districts ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get one Districts + tags: + - Untags + put: + description: API for update Districts + parameters: + - description: Districts ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Update Districts + tags: + - Untags + /feedbacks: + get: + description: API for getting all Feedbacks + parameters: + - in: query + name: commentFromEmail + type: string + - in: query + name: commentFromName + type: string + - in: query + name: endDate + type: string + - in: query + name: message + type: string + - in: query + name: startDate + type: string + - in: query + name: statusId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Feedbacks + tags: + - Feedbacks + post: + description: API for create Feedbacks + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.FeedbacksCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Feedbacks + tags: + - Feedbacks + /feedbacks/{id}: + delete: + description: API for delete Feedbacks + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Feedbacks ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete Feedbacks + tags: + - Feedbacks + get: + description: API for getting one Feedbacks + parameters: + - description: Feedbacks ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Feedbacks + tags: + - Feedbacks + put: + description: API for update Feedbacks + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.FeedbacksUpdateRequest' + - description: Feedbacks ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update Feedbacks + tags: + - Feedbacks + /feedbacks/statistic/monthly: + get: + description: API for FeedbackMonthlyStats of Feedbacks + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: year + in: query + name: year + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: FeedbackMonthlyStats Feedbacks + tags: + - Feedbacks + /galleries: + get: + description: API for getting all Galleries + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Galleries + tags: + - Galleries + post: + description: API for creating Gallery + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.GalleriesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Gallery + tags: + - Galleries + /galleries/{id}: + delete: + description: API for deleting Gallery (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Gallery ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Gallery + tags: + - Galleries + get: + description: API for getting Gallery by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Gallery ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get Gallery by ID + tags: + - Galleries + put: + description: API for updating Gallery + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Gallery ID + in: path + name: id + required: true + type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.GalleriesUpdateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Gallery + tags: + - Galleries + /gallery-files: + get: + description: API for getting all GalleryFiles + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: gallery_id + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all GalleryFiles + tags: + - GalleryFiles + post: + description: API for creating GalleryFile with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: Gallery ID + in: formData + name: gallery_id + required: true + type: integer + - description: Gallery file title + in: formData + name: title + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create GalleryFile + tags: + - GalleryFiles + /gallery-files/{id}: + delete: + description: API for deleting GalleryFile (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: GalleryFile ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete GalleryFile + tags: + - GalleryFiles + get: + description: API for getting GalleryFile by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: GalleryFile ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get GalleryFile by ID + tags: + - GalleryFiles + put: + description: API for updating GalleryFile with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: GalleryFile ID + in: path + name: id + required: true + type: integer + - description: Upload file + in: formData + name: file + type: file + - description: Gallery ID + in: formData + name: gallery_id + type: integer + - description: Gallery file title + in: formData + name: title + type: string + - description: Is active + in: formData + name: is_active + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update GalleryFile + tags: + - GalleryFiles + /gallery-files/viewer/{filename}: + get: + description: API for viewing GalleryFile file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Gallery File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer GalleryFile + tags: + - GalleryFiles + /product-specifications: + get: + description: API for getting all ProductSpecifications + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: product_id + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all ProductSpecifications + tags: + - ProductSpecifications + post: + description: API for creating ProductSpecification with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: Product ID + in: formData + name: product_id + required: true + type: integer + - description: Product specification title + in: formData + name: title + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create ProductSpecification + tags: + - ProductSpecifications + /product-specifications/{id}: + delete: + description: API for deleting ProductSpecification (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: ProductSpecification ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete ProductSpecification + tags: + - ProductSpecifications + get: + description: API for getting ProductSpecification by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: ProductSpecification ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get ProductSpecification by ID + tags: + - ProductSpecifications + put: + description: API for updating ProductSpecification + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: ProductSpecification ID + in: path + name: id + required: true + type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.ProductSpecificationsUpdateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update ProductSpecification + tags: + - ProductSpecifications + /product-specifications/viewer/{filename}: + get: + description: API for viewing ProductSpecification file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Product Specification File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer ProductSpecification + tags: + - ProductSpecifications + /products: + get: + description: API for getting all Products + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: title + type: string + - in: query + name: variant + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Products + tags: + - Products + post: + description: API for creating Product with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: Product title + in: formData + name: title + required: true + type: string + - description: Product variant + in: formData + name: variant + type: string + - description: Product price + in: formData + name: price + type: string + - description: Product colors (JSON array) + in: formData + name: colors + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Product + tags: + - Products + /products/{id}: + delete: + description: API for deleting Product (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Product ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Product + tags: + - Products + get: + description: API for getting Product by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Product ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get Product by ID + tags: + - Products + put: + description: API for updating Product with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Product ID + in: path + name: id + required: true + type: integer + - description: Upload file + in: formData + name: file + type: file + - description: Product title + in: formData + name: title + type: string + - description: Product variant + in: formData + name: variant + type: string + - description: Product price + in: formData + name: price + type: string + - description: Product colors (JSON array) + in: formData + name: colors + type: string + - description: Product is_active + in: formData + name: is_active + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Product + tags: + - Products + /products/viewer/{filename}: + get: + description: API for viewing Product file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Product File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer Product + tags: + - Products + /promotions: + get: + description: API for getting all Promotions + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: title + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Promotions + tags: + - Promotions + post: + description: API for creating Promotion with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: Promotion title + in: formData + name: title + required: true + type: string + - description: Promotion description + in: formData + name: description + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Promotion + tags: + - Promotions + /promotions/{id}: + delete: + description: API for deleting Promotion (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Promotion ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete Promotion + tags: + - Promotions + get: + description: API for getting Promotion by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Promotion ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get Promotion by ID + tags: + - Promotions + put: + description: API for updating Promotion + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Promotion ID + in: path + name: id + required: true + type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.PromotionsUpdateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update Promotion + tags: + - Promotions + /promotions/viewer/{filename}: + get: + description: API for viewing Promotion file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Promotion File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer Promotion + tags: + - Promotions + /provinces: + get: + description: API for getting all Provinces + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get all Provinces + tags: + - Untags + post: + description: API for create Provinces + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Create Provinces + tags: + - Untags + /provinces/{id}: + delete: + description: API for delete Provinces + parameters: + - description: Provinces ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Delete Provinces + tags: + - Untags + get: + description: API for getting one Provinces + parameters: + - description: Provinces ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get one Provinces + tags: + - Untags + put: + description: API for update Provinces + parameters: + - description: Provinces ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Update Provinces + tags: + - Untags + /sales-agents: + get: + description: API for getting all SalesAgents + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - in: query + name: agent_type + type: string + - in: query + name: job_title + type: string + - in: query + name: name + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all SalesAgents + tags: + - SalesAgents + post: + description: API for creating SalesAgent with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: Upload file + in: formData + name: file + type: file + - description: SalesAgent name + in: formData + name: name + required: true + type: string + - description: SalesAgent job title + in: formData + name: job_title + type: string + - description: SalesAgent phone + in: formData + name: phone + type: string + - description: SalesAgent agent type (JSON array) + in: formData + name: agent_type + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create SalesAgent + tags: + - SalesAgents + /sales-agents/{id}: + delete: + description: API for deleting SalesAgent (soft delete) + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: SalesAgent ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Delete SalesAgent + tags: + - SalesAgents + get: + description: API for getting SalesAgent by ID + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: SalesAgent ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get SalesAgent by ID + tags: + - SalesAgents + put: + description: API for updating SalesAgent with file upload + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: SalesAgent ID + in: path + name: id + required: true + type: integer + - description: Upload file + in: formData + name: file + type: file + - description: SalesAgent name + in: formData + name: name + type: string + - description: SalesAgent job title + in: formData + name: job_title + type: string + - description: SalesAgent phone + in: formData + name: phone + type: string + - description: SalesAgent agent type (JSON array) + in: formData + name: agent_type + type: string + - description: SalesAgent is_active + in: formData + name: is_active + type: boolean + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Update SalesAgent + tags: + - SalesAgents + /sales-agents/viewer/{filename}: + get: + description: API for viewing SalesAgent profile picture file + parameters: + - description: Insert the X-Client-Key + in: header + name: X-Client-Key + required: true + type: string + - description: SalesAgent File Name (e.g., user_277788.png) + in: path + name: filename + required: true + type: string + responses: + "200": + description: OK + schema: + type: file + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Viewer SalesAgent + tags: + - SalesAgents + /user-levels: + get: + description: API for getting all UserLevels + parameters: + - in: query + name: levelNumber + type: integer + - in: query + name: name + type: string + - in: query + name: parentLevelId + type: integer + - in: query + name: provinceId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all UserLevels + tags: + - UserLevels + post: + description: API for create UserLevels + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLevelsCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create UserLevels + tags: + - UserLevels + /user-levels/{id}: + delete: + description: API for delete UserLevels + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: UserLevels ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: delete UserLevels + tags: + - UserLevels + get: + description: API for getting one UserLevels + parameters: + - description: UserLevels ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one UserLevels + tags: + - UserLevels + put: + description: API for update UserLevels + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLevelsUpdateRequest' + - description: UserLevels ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update UserLevels + tags: + - UserLevels + /user-levels/alias/{alias}: + get: + description: API for getting one UserLevels + parameters: + - description: UserLevels Alias + in: path + name: alias + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one UserLevels + tags: + - UserLevels + /user-levels/enable-approval: + post: + description: API for Enable Approval of Article + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLevelsApprovalRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: EnableApproval Articles + tags: + - UserLevels + /user-role-accesses: + get: + description: API for getting all UserRoleAccesses + parameters: + - in: query + name: isActive + required: true + type: boolean + - in: query + name: menuId + required: true + type: integer + - in: query + name: userRoleId + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all UserRoleAccesses + tags: + - UserRoleAccesses + post: + description: API for create UserRoleAccesses + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserRoleAccessesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create UserRoleAccesses + tags: + - UserRoleAccesses + /user-role-accesses/{id}: + delete: + description: API for delete UserRoleAccesses + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: UserRoleAccesses ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete UserRoleAccesses + tags: + - UserRoleAccesses + get: + description: API for getting one UserRoleAccesses + parameters: + - description: UserRoleAccesses ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one UserRoleAccesses + tags: + - UserRoleAccesses + put: + description: API for update UserRoleAccesses + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserRoleAccessesUpdateRequest' + - description: UserRoleAccesses ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update UserRoleAccesses + tags: + - UserRoleAccesses + /user-role-level-details: + get: + description: API for getting all UserRoleLevelDetails + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get all UserRoleLevelDetails + tags: + - Task + post: + description: API for create UserRoleLevelDetails + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Create UserRoleLevelDetails + tags: + - Task + /user-role-level-details/{id}: + delete: + description: API for delete UserRoleLevelDetails + parameters: + - description: UserRoleLevelDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: delete UserRoleLevelDetails + tags: + - Task + get: + description: API for getting one UserRoleLevelDetails + parameters: + - description: UserRoleLevelDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: Get one UserRoleLevelDetails + tags: + - Task + put: + description: API for update UserRoleLevelDetails + parameters: + - description: UserRoleLevelDetails ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.Response' + "404": + description: Not Found + schema: + $ref: '#/definitions/response.Response' + "422": + description: Unprocessable Entity + schema: + $ref: '#/definitions/response.Response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.Response' + security: + - Bearer: [] + summary: update UserRoleLevelDetails + tags: + - Task + /user-roles: + get: + description: API for getting all UserRoles + parameters: + - in: query + name: code + type: string + - in: query + name: description + type: string + - in: query + name: name + type: string + - in: query + name: statusId + type: integer + - in: query + name: userLevelId + type: integer + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all UserRoles + tags: + - UserRoles + post: + description: API for create UserRoles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserRolesCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create UserRoles + tags: + - UserRoles + /user-roles/{id}: + delete: + description: API for delete UserRoles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: UserRoles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete UserRoles + tags: + - UserRoles + get: + description: API for getting one UserRoles + parameters: + - description: UserRoles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one UserRoles + tags: + - UserRoles + put: + description: API for update UserRoles + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserRolesUpdateRequest' + - description: UserRoles ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update UserRoles + tags: + - UserRoles + /users: + get: + description: API for getting all Users + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - in: query + name: degree + type: string + - in: query + name: email + type: string + - in: query + name: fullname + type: string + - in: query + name: genderType + type: string + - in: query + name: identityGroup + type: string + - in: query + name: identityGroupNumber + type: string + - in: query + name: identityNumber + type: string + - in: query + name: identityType + type: string + - in: query + name: phoneNumber + type: string + - in: query + name: statusId + type: integer + - in: query + name: userRoleId + type: integer + - in: query + name: username + type: string + - in: query + name: workType + type: string + - in: query + name: count + type: integer + - in: query + name: limit + type: integer + - in: query + name: nextPage + type: integer + - in: query + name: page + type: integer + - in: query + name: previousPage + type: integer + - in: query + name: sort + type: string + - in: query + name: sortBy + type: string + - in: query + name: totalPage + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get all Users + tags: + - Users + post: + description: API for create Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UsersCreateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Create Users + tags: + - Users + /users/{id}: + delete: + description: API for delete Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Users ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: delete Users + tags: + - Users + put: + description: API for update Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Users ID + in: path + name: id + required: true + type: integer + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UsersUpdateRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: update Users + tags: + - Users + /users/detail/{id}: + get: + description: API for getting one Users + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Users ID + in: path + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Users + tags: + - Users + /users/email-validation: + post: + description: API for Email Validation Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserEmailValidationRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: EmailValidation Users + tags: + - Users + /users/forgot-password: + post: + description: API for ForgotPassword Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserForgotPassword' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ForgotPassword Users + tags: + - Users + /users/info: + get: + description: API for ShowUserInfo + parameters: + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ShowInfo Users + tags: + - Users + /users/login: + post: + description: API for Login Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLogin' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Login Users + tags: + - Users + /users/otp-request: + post: + description: API for OtpRequest Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserOtpRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: OtpRequest Users + tags: + - Users + /users/otp-validation: + post: + description: API for OtpValidation Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserOtpValidation' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: OtpValidation Users + tags: + - Users + /users/pareto-login: + post: + description: API for ParetoLogin Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserLogin' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ParetoLogin Users + tags: + - Users + /users/reset-password: + post: + description: API for ResetPassword Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserResetPassword' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: ResetPassword Users + tags: + - Users + /users/save-password: + post: + description: API for SavePassword Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - default: Bearer + description: Insert your access token + in: header + name: Authorization + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserSavePassword' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: SavePassword Users + tags: + - Users + /users/setup-email: + post: + description: API for Setup Email Users + parameters: + - description: Insert the X-Csrf-Token + in: header + name: X-Csrf-Token + required: true + type: string + - description: Required payload + in: body + name: payload + required: true + schema: + $ref: '#/definitions/request.UserEmailValidationRequest' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: SetupEmail Users + tags: + - Users + /users/username/{username}: + get: + description: API for getting one Users + parameters: + - description: Username + in: path + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/response.Response' + "400": + description: Bad Request + schema: + $ref: '#/definitions/response.BadRequestError' + "401": + description: Unauthorized + schema: + $ref: '#/definitions/response.UnauthorizedError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/response.InternalServerError' + security: + - Bearer: [] + summary: Get one Users + tags: + - Users +swagger: "2.0" diff --git a/main.go b/main.go index 0417094..e619d3c 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,8 @@ import ( "jaecoo-be/app/module/articles" "jaecoo-be/app/module/banners" "jaecoo-be/app/module/cities" + "jaecoo-be/app/module/client_approval_settings" + "jaecoo-be/app/module/clients" "jaecoo-be/app/module/custom_static_pages" "jaecoo-be/app/module/districts" "jaecoo-be/app/module/feedbacks" @@ -70,6 +72,8 @@ func main() { article_comments.NewArticleCommentsModule, banners.NewBannersModule, cities.NewCitiesModule, + client_approval_settings.NewClientApprovalSettingsModule, + clients.NewClientsModule, custom_static_pages.NewCustomStaticPagesModule, districts.NewDistrictsModule, feedbacks.NewFeedbacksModule, diff --git a/plan/api-documentation.md b/plan/api-documentation.md new file mode 100644 index 0000000..7158035 --- /dev/null +++ b/plan/api-documentation.md @@ -0,0 +1,818 @@ +# API Documentation - Sistem Approval Artikel Dinamis + +## Overview +Dokumentasi ini menjelaskan API endpoints yang tersedia untuk sistem approval artikel dinamis. Sistem ini memungkinkan pembuatan workflow approval yang fleksibel dengan multiple level dan proses revisi. + +## Base URL +``` +http://localhost:8800/api +``` + +## Authentication +Semua endpoint memerlukan Bearer token authentication: +``` +Authorization: Bearer +``` + +## 1. Approval Workflows Management + +### 1.1 Get All Workflows +```http +GET /approval-workflows +``` + +**Query Parameters:** +- `page` (optional): Page number (default: 1) +- `limit` (optional): Items per page (default: 10) +- `search` (optional): Search by workflow name +- `is_active` (optional): Filter by active status (true/false) + +**Response:** +```json +{ + "success": true, + "messages": ["Workflows retrieved successfully"], + "data": [ + { + "id": 1, + "name": "Standard 3-Level Approval", + "description": "Default workflow with 3 approval levels", + "is_active": true, + "created_at": "2024-01-15T10:30:00Z", + "updated_at": "2024-01-15T10:30:00Z", + "steps": [ + { + "id": 1, + "step_order": 1, + "user_level_id": 3, + "user_level": { + "id": 3, + "level_name": "Approver Level 3", + "level_number": 3 + }, + "is_required": true, + "can_skip": false + } + ] + } + ], + "pagination": { + "current_page": 1, + "per_page": 10, + "total": 5, + "total_pages": 1 + } +} +``` + +### 1.2 Get Workflow by ID +```http +GET /approval-workflows/{id} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Workflow retrieved successfully"], + "data": { + "id": 1, + "name": "Standard 3-Level Approval", + "description": "Default workflow with 3 approval levels", + "is_active": true, + "steps": [ + { + "id": 1, + "step_order": 1, + "user_level_id": 3, + "is_required": true, + "can_skip": false + } + ] + } +} +``` + +### 1.3 Create New Workflow +```http +POST /approval-workflows +``` + +**Request Body:** +```json +{ + "name": "Custom 2-Level Approval", + "description": "Fast track approval for urgent articles", + "steps": [ + { + "stepOrder": 1, + "userLevelId": 2, + "isRequired": true, + "canSkip": false + }, + { + "stepOrder": 2, + "userLevelId": 1, + "isRequired": true, + "canSkip": false + } + ] +} +``` + +**Validation Rules:** +- `name`: Required, max 255 characters +- `steps`: Required, minimum 1 step +- `stepOrder`: Must be sequential starting from 1 +- `userLevelId`: Must exist in user_levels table + +**Response:** +```json +{ + "success": true, + "messages": ["Workflow created successfully"], + "data": { + "id": 5, + "name": "Custom 2-Level Approval", + "description": "Fast track approval for urgent articles", + "is_active": true, + "created_at": "2024-01-15T14:30:00Z" + } +} +``` + +### 1.4 Update Workflow +```http +PUT /approval-workflows/{id} +``` + +**Request Body:** +```json +{ + "name": "Updated Workflow Name", + "description": "Updated description", + "is_active": true +} +``` + +### 1.5 Delete Workflow +```http +DELETE /approval-workflows/{id} +``` + +**Note:** Workflow can only be deleted if no articles are currently using it. + +## 2. Article Approval Management + +### 2.1 Submit Article for Approval +```http +POST /articles/{id}/submit-approval +``` + +**Request Body:** +```json +{ + "workflowId": 2 +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Article submitted for approval successfully"], + "data": { + "id": 15, + "article_id": 123, + "workflow_id": 2, + "current_step": 1, + "status_id": 1, + "created_at": "2024-01-15T15:00:00Z" + } +} +``` + +### 2.2 Approve Current Step +```http +POST /articles/{id}/approve +``` + +**Request Body:** +```json +{ + "message": "Article content is excellent, approved for next level" +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Article approved successfully"], + "data": { + "next_step": 2, + "status": "moved_to_next_level" + } +} +``` + +### 2.3 Reject Article +```http +POST /articles/{id}/reject +``` + +**Request Body:** +```json +{ + "message": "Article does not meet quality standards" +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Article rejected successfully"] +} +``` + +### 2.4 Request Revision +```http +POST /articles/{id}/request-revision +``` + +**Request Body:** +```json +{ + "message": "Please fix grammar issues in paragraph 3 and add more references" +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Revision requested successfully"] +} +``` + +### 2.5 Resubmit After Revision +```http +POST /articles/{id}/resubmit +``` + +**Request Body:** +```json +{ + "message": "Fixed all requested issues" +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Article resubmitted successfully"], + "data": { + "current_step": 1, + "status": "back_in_approval_flow" + } +} +``` + +## 3. Approval Dashboard + +### 3.1 Get Pending Approvals for Current User +```http +GET /approvals/pending +``` + +**Query Parameters:** +- `page` (optional): Page number (default: 1) +- `limit` (optional): Items per page (default: 10, max: 50) +- `priority` (optional): Filter by priority (high, medium, low) +- `category_id` (optional): Filter by article category +- `search` (optional): Search in article title or author name +- `date_from` (optional): Filter articles submitted from date (YYYY-MM-DD) +- `date_to` (optional): Filter articles submitted to date (YYYY-MM-DD) +- `sort_by` (optional): Sort by field (waiting_time, created_at, title, priority) +- `sort_order` (optional): Sort order (asc, desc) - default: desc +- `workflow_id` (optional): Filter by specific workflow + +**Response:** +```json +{ + "success": true, + "messages": ["Pending approvals retrieved successfully"], + "data": [ + { + "id": 15, + "article": { + "id": 123, + "title": "Understanding Machine Learning", + "excerpt": "This article explores the fundamentals of machine learning...", + "author": { + "id": 45, + "name": "John Doe", + "email": "john@example.com", + "profile_picture": "https://example.com/avatar.jpg" + }, + "category": { + "id": 5, + "name": "Technology", + "color": "#3B82F6" + }, + "word_count": 1250, + "estimated_read_time": "5 min", + "created_at": "2024-01-15T10:00:00Z", + "submitted_at": "2024-01-15T14:30:00Z" + }, + "workflow": { + "id": 2, + "name": "Standard 3-Level Approval", + "total_steps": 3 + }, + "current_step": 2, + "my_step_order": 2, + "waiting_since": "2024-01-15T14:30:00Z", + "waiting_duration_hours": 6.5, + "priority": "medium", + "previous_approvals": [ + { + "step_order": 1, + "approver_name": "Jane Smith", + "approved_at": "2024-01-15T14:30:00Z", + "message": "Content looks good" + } + ], + "urgency_score": 7.5, + "can_approve": true, + "can_reject": true, + "can_request_revision": true + } + ], + "pagination": { + "current_page": 1, + "per_page": 10, + "total": 5, + "total_pages": 1 + }, + "summary": { + "total_pending": 5, + "high_priority": 2, + "medium_priority": 2, + "low_priority": 1, + "overdue_count": 1, + "avg_waiting_hours": 8.2 + } +} +``` + +### 3.2 Get Approval History for Article +```http +GET /articles/{id}/approval-history +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Approval history retrieved successfully"], + "data": { + "article_id": 123, + "workflow": { + "id": 2, + "name": "Standard 3-Level Approval" + }, + "current_step": 2, + "status": "in_progress", + "history": [ + { + "id": 1, + "step_order": 1, + "action": "approved", + "message": "Good content, approved", + "approver": { + "id": 67, + "name": "Jane Smith", + "level": "Approver Level 3" + }, + "approved_at": "2024-01-15T14:30:00Z" + } + ] + } +} +``` + +### 3.3 Get My Approval Statistics +```http +GET /approvals/my-stats +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Statistics retrieved successfully"], + "data": { + "pending_count": 5, + "overdue_count": 1, + "approved_today": 3, + "approved_this_week": 15, + "approved_this_month": 45, + "rejected_this_month": 2, + "revision_requests_this_month": 8, + "average_approval_time_hours": 4.5, + "fastest_approval_minutes": 15, + "slowest_approval_hours": 48, + "approval_rate_percentage": 85.2, + "categories_breakdown": [ + { + "category_name": "Technology", + "pending": 2, + "approved_this_month": 12 + }, + { + "category_name": "Health", + "pending": 3, + "approved_this_month": 8 + } + ] + } +} +``` + +### 3.4 Get Articles Requiring My Approval (Detailed View) +```http +GET /approvals/my-queue +``` + +**Query Parameters:** +- Same as `/approvals/pending` but specifically filtered for current user's level +- `include_preview` (optional): Include article content preview (true/false) +- `urgency_only` (optional): Show only urgent articles (true/false) + +**Response:** +```json +{ + "success": true, + "messages": ["My approval queue retrieved successfully"], + "data": [ + { + "id": 15, + "article": { + "id": 123, + "title": "Understanding Machine Learning", + "content_preview": "Machine learning is a subset of artificial intelligence that enables computers to learn and improve from experience without being explicitly programmed...", + "full_content_available": true, + "author": { + "id": 45, + "name": "John Doe", + "reputation_score": 8.5, + "articles_published": 25, + "approval_success_rate": 92.3 + }, + "submission_notes": "This is an updated version based on previous feedback", + "tags": ["AI", "Technology", "Education"], + "seo_score": 85, + "readability_score": "Good" + }, + "approval_context": { + "my_role_in_workflow": "Senior Editor Review", + "step_description": "Review content quality and technical accuracy", + "expected_action": "Approve or request technical revisions", + "deadline": "2024-01-16T18:00:00Z", + "is_overdue": false, + "escalation_available": true + }, + "workflow_progress": { + "completed_steps": 1, + "total_steps": 3, + "progress_percentage": 33.3, + "next_approver": "Chief Editor" + } + } + ] +} +``` + +### 3.5 Get Approval Workload Distribution +```http +GET /approvals/workload +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Workload distribution retrieved successfully"], + "data": { + "my_level": { + "level_name": "Senior Editor", + "level_number": 2, + "pending_articles": 5, + "avg_daily_approvals": 8.5 + }, + "team_comparison": [ + { + "approver_name": "Jane Smith", + "level_name": "Senior Editor", + "pending_articles": 3, + "avg_response_time_hours": 2.5 + }, + { + "approver_name": "Mike Johnson", + "level_name": "Senior Editor", + "pending_articles": 7, + "avg_response_time_hours": 4.2 + } + ], + "bottlenecks": [ + { + "level_name": "Chief Editor", + "pending_count": 12, + "avg_waiting_time_hours": 18.5, + "is_bottleneck": true + } + ] + } +} +``` + +### 3.6 Bulk Approval Actions +```http +POST /approvals/bulk-action +``` + +**Request Body:** +```json +{ + "article_ids": [123, 124, 125], + "action": "approve", + "message": "Bulk approval for similar content type", + "apply_to_similar": false +} +``` + +**Response:** +```json +{ + "success": true, + "messages": ["Bulk action completed successfully"], + "data": { + "processed_count": 3, + "successful_count": 3, + "failed_count": 0, + "results": [ + { + "article_id": 123, + "status": "success", + "next_step": 3 + }, + { + "article_id": 124, + "status": "success", + "next_step": 3 + }, + { + "article_id": 125, + "status": "success", + "next_step": "published" + } + ] + } +} +``` + +## 4. User Level Management + +### 4.1 Get Available User Levels +```http +GET /user-levels +``` + +**Response:** +```json +{ + "success": true, + "messages": ["User levels retrieved successfully"], + "data": [ + { + "id": 1, + "level_name": "Chief Editor", + "level_number": 1, + "parent_level_id": null, + "is_approval_active": true + }, + { + "id": 2, + "level_name": "Senior Editor", + "level_number": 2, + "parent_level_id": 1, + "is_approval_active": true + }, + { + "id": 3, + "level_name": "Junior Editor", + "level_number": 3, + "parent_level_id": 2, + "is_approval_active": true + } + ] +} +``` + +## 5. Error Responses + +### 5.1 Validation Error (400) +```json +{ + "success": false, + "messages": ["Validation failed"], + "errors": { + "name": ["Name is required"], + "steps": ["At least one step is required"] + } +} +``` + +### 5.2 Unauthorized (401) +```json +{ + "success": false, + "messages": ["Unauthorized access"] +} +``` + +### 5.3 Forbidden (403) +```json +{ + "success": false, + "messages": ["You don't have permission to approve this article"] +} +``` + +### 5.4 Not Found (404) +```json +{ + "success": false, + "messages": ["Article not found"] +} +``` + +### 5.5 Business Logic Error (422) +```json +{ + "success": false, + "messages": ["Article already has active approval flow"] +} +``` + +### 5.6 Internal Server Error (500) +```json +{ + "success": false, + "messages": ["Internal server error occurred"] +} +``` + +## 6. Webhook Events (Optional) + +Sistem dapat mengirim webhook notifications untuk event-event penting: + +### 6.1 Article Submitted for Approval +```json +{ + "event": "article.submitted_for_approval", + "timestamp": "2024-01-15T15:00:00Z", + "data": { + "article_id": 123, + "workflow_id": 2, + "submitted_by": { + "id": 45, + "name": "John Doe" + }, + "next_approver_level": 3 + } +} +``` + +### 6.2 Article Approved +```json +{ + "event": "article.approved", + "timestamp": "2024-01-15T16:00:00Z", + "data": { + "article_id": 123, + "approved_by": { + "id": 67, + "name": "Jane Smith", + "level": 3 + }, + "current_step": 2, + "is_final_approval": false + } +} +``` + +### 6.3 Article Published +```json +{ + "event": "article.published", + "timestamp": "2024-01-15T17:00:00Z", + "data": { + "article_id": 123, + "final_approver": { + "id": 89, + "name": "Chief Editor", + "level": 1 + }, + "total_approval_time_hours": 6.5 + } +} +``` + +### 6.4 Revision Requested +```json +{ + "event": "article.revision_requested", + "timestamp": "2024-01-15T16:30:00Z", + "data": { + "article_id": 123, + "requested_by": { + "id": 67, + "name": "Jane Smith", + "level": 2 + }, + "message": "Please fix grammar issues", + "author": { + "id": 45, + "name": "John Doe" + } + } +} +``` + +## 7. Rate Limiting + +API menggunakan rate limiting untuk mencegah abuse: +- **General endpoints**: 100 requests per minute per user +- **Approval actions**: 50 requests per minute per user +- **Workflow management**: 20 requests per minute per user + +## 8. Pagination + +Semua endpoint yang mengembalikan list menggunakan pagination: +- Default `limit`: 10 +- Maximum `limit`: 100 +- Default `page`: 1 + +## 9. Filtering dan Sorting + +Beberapa endpoint mendukung filtering dan sorting: + +### Query Parameters untuk Filtering: +- `status`: Filter by status +- `user_level`: Filter by user level +- `date_from`: Filter from date (YYYY-MM-DD) +- `date_to`: Filter to date (YYYY-MM-DD) +- `search`: Search in title/content + +### Query Parameters untuk Sorting: +- `sort_by`: Field to sort by (created_at, updated_at, title, etc.) +- `sort_order`: asc atau desc (default: desc) + +Contoh: +``` +GET /articles?status=pending&sort_by=created_at&sort_order=asc&page=1&limit=20 +``` + +## 10. Bulk Operations + +### 10.1 Bulk Approve Articles +```http +POST /articles/bulk-approve +``` + +**Request Body:** +```json +{ + "article_ids": [123, 124, 125], + "message": "Bulk approval for similar articles" +} +``` + +### 10.2 Bulk Assign Workflow +```http +POST /articles/bulk-assign-workflow +``` + +**Request Body:** +```json +{ + "article_ids": [123, 124, 125], + "workflow_id": 2 +} +``` + +Dokumentasi API ini memberikan panduan lengkap untuk mengintegrasikan sistem approval artikel dinamis dengan frontend atau sistem eksternal lainnya. \ No newline at end of file diff --git a/plan/approval-workflow-architecture.md b/plan/approval-workflow-architecture.md new file mode 100644 index 0000000..9b008a7 --- /dev/null +++ b/plan/approval-workflow-architecture.md @@ -0,0 +1,347 @@ +# Approval Workflow Architecture & Module Relationships + +## ๐Ÿ“‹ **Overview** + +Sistem approval workflow di MEDOLS menggunakan arsitektur multi-module yang saling terintegrasi untuk mengelola proses persetujuan artikel secara dinamis. Setiap module memiliki peran spesifik dalam alur approval yang kompleks. + +## ๐Ÿ—๏ธ **Module Architecture** + +### **1. Core Workflow Modules** + +#### **`approval_workflows`** - Master Workflow Definition +- **Purpose**: Mendefinisikan template workflow approval +- **Key Fields**: + - `id`: Primary key + - `name`: Nama workflow (e.g., "Standard Approval", "Fast Track") + - `description`: Deskripsi workflow + - `is_default`: Apakah workflow default untuk client + - `is_active`: Status aktif workflow + - `client_id`: Client yang memiliki workflow + +#### **`approval_workflow_steps`** - Workflow Steps Definition +- **Purpose**: Mendefinisikan step-step dalam workflow +- **Key Fields**: + - `id`: Primary key + - `workflow_id`: Foreign key ke `approval_workflows` + - `step_order`: Urutan step (1, 2, 3, dst.) + - `step_name`: Nama step (e.g., "Level 2 Review", "Level 1 Final Approval") + - `required_user_level_id`: User level yang harus approve step ini + - `is_required`: Apakah step wajib atau optional + +### **2. Execution Modules** + +#### **`article_approval_flows`** - Active Approval Instances +- **Purpose**: Instance aktif dari workflow yang sedang berjalan +- **Key Fields**: + - `id`: Primary key + - `article_id`: Foreign key ke `articles` + - `workflow_id`: Foreign key ke `approval_workflows` + - `current_step`: Step saat ini yang sedang menunggu approval + - `status_id`: Status (1=pending, 2=approved, 3=rejected, 4=revision_requested) + - `submitted_by_id`: User yang submit artikel + - `submitted_at`: Waktu submit + - `completed_at`: Waktu selesai (jika approved/rejected) + +#### **`article_approval_step_logs`** - Step Execution History +- **Purpose**: Log setiap step yang telah dieksekusi +- **Key Fields**: + - `id`: Primary key + - `approval_flow_id`: Foreign key ke `article_approval_flows` + - `step_order`: Urutan step yang dieksekusi + - `step_name`: Nama step + - `approved_by_id`: User yang approve step ini + - `action`: Aksi yang dilakukan (approve, reject, auto_skip) + - `message`: Pesan dari approver + - `processed_at`: Waktu eksekusi + +### **3. Legacy & Configuration Modules** + +#### **`article_approvals`** - Legacy Approval System +- **Purpose**: Sistem approval legacy untuk backward compatibility +- **Key Fields**: + - `id`: Primary key + - `article_id`: Foreign key ke `articles` + - `approval_by`: User yang approve + - `status_id`: Status approval + - `approval_at_level`: Level yang approve + - `message`: Pesan approval + +#### **`client_approval_settings`** - Client Configuration +- **Purpose**: Konfigurasi approval untuk setiap client +- **Key Fields**: + - `id`: Primary key + - `client_id`: Foreign key ke `clients` + - `workflow_id`: Workflow default untuk client + - `auto_approve_levels`: Level yang auto-approve + - `notification_settings`: Konfigurasi notifikasi + +## ๐Ÿ”„ **Approval Workflow Process Flow** + +### **Phase 1: Setup & Configuration** + +```mermaid +graph TD + A[Client Setup] --> B[Create Approval Workflow] + B --> C[Define Workflow Steps] + C --> D[Set Required User Levels] + D --> E[Configure Client Settings] + E --> F[Activate Workflow] +``` + +**Steps:** +1. **Client Registration**: Client baru dibuat di sistem +2. **Workflow Creation**: Admin membuat workflow approval +3. **Step Definition**: Mendefinisikan step-step dengan user level requirement +4. **Client Configuration**: Set workflow default untuk client + +### **Phase 2: Article Submission** + +```mermaid +graph TD + A[User Creates Article] --> B{User Level Requires Approval?} + B -->|Yes| C[Create Article Approval Flow] + B -->|No| D[Auto Publish] + C --> E[Set Current Step = 1] + E --> F[Status = Pending] + F --> G[Create Legacy Approval Record] + G --> H[Notify Approvers] +``` + +**Database Changes:** +- `articles`: `workflow_id`, `current_approval_step = 1`, `status_id = 1` +- `article_approval_flows`: New record dengan `current_step = 1` +- `article_approvals`: Legacy record untuk backward compatibility + +### **Phase 3: Step-by-Step Approval** + +```mermaid +graph TD + A[Approver Reviews Article] --> B{Approve or Reject?} + B -->|Approve| C[Create Step Log] + B -->|Reject| D[Update Status to Rejected] + C --> E{More Steps?} + E -->|Yes| F[Move to Next Step] + E -->|No| G[Complete Approval] + F --> H[Update Current Step] + H --> I[Notify Next Approver] + G --> J[Update Article Status to Approved] + D --> K[Notify Submitter] +``` + +**Database Changes per Step:** +- `article_approval_step_logs`: New log record +- `article_approval_flows`: Update `current_step` dan `status_id` +- `articles`: Update `current_approval_step` + +### **Phase 4: Completion** + +```mermaid +graph TD + A[All Steps Approved] --> B[Update Final Status] + B --> C[Set Completed At] + C --> D[Publish Article] + D --> E[Send Notifications] + E --> F[Update Analytics] +``` + +## ๐Ÿ“Š **Module Relationships Diagram** + +```mermaid +erDiagram + CLIENTS ||--o{ APPROVAL_WORKFLOWS : "has" + CLIENTS ||--o{ CLIENT_APPROVAL_SETTINGS : "configures" + + APPROVAL_WORKFLOWS ||--o{ APPROVAL_WORKFLOW_STEPS : "contains" + APPROVAL_WORKFLOWS ||--o{ ARTICLE_APPROVAL_FLOWS : "instantiates" + + ARTICLES ||--o{ ARTICLE_APPROVAL_FLOWS : "has" + ARTICLES ||--o{ ARTICLE_APPROVALS : "has_legacy" + + ARTICLE_APPROVAL_FLOWS ||--o{ ARTICLE_APPROVAL_STEP_LOGS : "logs" + ARTICLE_APPROVAL_FLOWS }o--|| APPROVAL_WORKFLOWS : "uses" + + USERS ||--o{ ARTICLE_APPROVAL_FLOWS : "submits" + USERS ||--o{ ARTICLE_APPROVAL_STEP_LOGS : "approves" + + USER_LEVELS ||--o{ APPROVAL_WORKFLOW_STEPS : "requires" + USER_LEVELS ||--o{ USERS : "defines" +``` + +## ๐Ÿ”ง **Technical Implementation Details** + +### **1. Dynamic Workflow Assignment** + +```go +// Ketika artikel dibuat +if userLevel.RequiresApproval { + // 1. Cari workflow default untuk client + workflow := getDefaultWorkflow(clientId) + + // 2. Buat approval flow instance + approvalFlow := ArticleApprovalFlows{ + ArticleId: articleId, + WorkflowId: workflow.ID, + CurrentStep: 1, + StatusId: 1, // pending + } + + // 3. Buat legacy record + legacyApproval := ArticleApprovals{ + ArticleId: articleId, + ApprovalAtLevel: nextApprovalLevel, + } +} +``` + +### **2. Step Progression Logic** + +```go +// Ketika step di-approve +func ApproveStep(flowId, approvedById, message) { + // 1. Log step yang di-approve + stepLog := ArticleApprovalStepLogs{ + ApprovalFlowId: flowId, + StepOrder: currentStep, + ApprovedById: approvedById, + Action: "approve", + } + + // 2. Cek apakah ada next step + nextStep := getNextStep(workflowId, currentStep) + + if nextStep != nil { + // 3. Pindah ke step berikutnya + updateCurrentStep(flowId, nextStep.StepOrder) + } else { + // 4. Complete approval + completeApproval(flowId) + } +} +``` + +### **3. User Level Hierarchy** + +```go +// Level hierarchy (level_number field) +Level 1: Highest Authority (POLDAS) +Level 2: Mid Authority (POLDAS) +Level 3: Lower Authority (POLRES) + +// Approval flow +Level 3 โ†’ Level 2 โ†’ Level 1 โ†’ Approved +``` + +## ๐Ÿ“ˆ **Data Flow Examples** + +### **Example 1: Standard 3-Step Approval** + +``` +1. User Level 3 creates article + โ”œโ”€โ”€ article_approval_flows: {current_step: 1, status: pending} + โ”œโ”€โ”€ article_approvals: {approval_at_level: 2} + โ””โ”€โ”€ articles: {current_approval_step: 1, status: pending} + +2. User Level 2 approves + โ”œโ”€โ”€ article_approval_step_logs: {step_order: 1, action: approve} + โ”œโ”€โ”€ article_approval_flows: {current_step: 2, status: pending} + โ””โ”€โ”€ articles: {current_approval_step: 2} + +3. User Level 1 approves + โ”œโ”€โ”€ article_approval_step_logs: {step_order: 2, action: approve} + โ”œโ”€โ”€ article_approval_flows: {status: approved, completed_at: now} + โ””โ”€โ”€ articles: {status: approved, published: true} +``` + +### **Example 2: Auto-Skip Logic** + +``` +1. User Level 1 creates article (highest authority) + โ”œโ”€โ”€ Check: Can skip all steps? + โ”œโ”€โ”€ article_approval_flows: {status: approved, completed_at: now} + โ””โ”€โ”€ articles: {status: approved, published: true} +``` + +## ๐Ÿš€ **API Endpoints Flow** + +### **Article Creation** +``` +POST /api/articles +โ”œโ”€โ”€ Check user level +โ”œโ”€โ”€ Create article +โ”œโ”€โ”€ Assign workflow (if needed) +โ”œโ”€โ”€ Create approval flow +โ””โ”€โ”€ Return article data +``` + +### **Approval Process** +``` +PUT /api/article-approval-flows/{id}/approve +โ”œโ”€โ”€ Validate approver permissions +โ”œโ”€โ”€ Create step log +โ”œโ”€โ”€ Check for next step +โ”œโ”€โ”€ Update flow status +โ””โ”€โ”€ Send notifications +``` + +### **Status Checking** +``` +GET /api/articles/{id}/approval-status +โ”œโ”€โ”€ Get current flow +โ”œโ”€โ”€ Get step logs +โ”œโ”€โ”€ Get next step info +โ””โ”€โ”€ Return status data +``` + +## ๐Ÿ” **Debugging & Monitoring** + +### **Key Queries for Monitoring** + +```sql +-- Active approval flows +SELECT aaf.*, a.title, ul.name as current_approver_level +FROM article_approval_flows aaf +JOIN articles a ON aaf.article_id = a.id +JOIN approval_workflow_steps aws ON aaf.workflow_id = aws.workflow_id + AND aaf.current_step = aws.step_order +JOIN user_levels ul ON aws.required_user_level_id = ul.id +WHERE aaf.status_id = 1; + +-- Approval history +SELECT aasl.*, u.name as approver_name, ul.name as level_name +FROM article_approval_step_logs aasl +JOIN users u ON aasl.approved_by_id = u.id +JOIN user_levels ul ON aasl.user_level_id = ul.id +WHERE aasl.approval_flow_id = ?; +``` + +## โš ๏ธ **Common Issues & Solutions** + +### **Issue 1: Step Not Progressing** +- **Cause**: `getUserLevelId` returning wrong level +- **Solution**: Fix user level mapping logic + +### **Issue 2: Wrong Approval Level** +- **Cause**: `findNextApprovalLevel` logic incorrect +- **Solution**: Fix level hierarchy comparison + +### **Issue 3: Missing Step Logs** +- **Cause**: Step log not created during approval +- **Solution**: Ensure step log creation in `ApproveStep` + +## ๐Ÿ“ **Best Practices** + +1. **Always create step logs** for audit trail +2. **Validate user permissions** before approval +3. **Use transactions** for multi-table updates +4. **Implement proper error handling** for edge cases +5. **Log all approval actions** for debugging +6. **Test with different user level combinations** + +## ๐ŸŽฏ **Summary** + +Sistem approval workflow MEDOLS menggunakan arsitektur modular yang memisahkan: +- **Configuration** (workflows, steps, settings) +- **Execution** (flows, logs) +- **Legacy Support** (article_approvals) + +Setiap module memiliki tanggung jawab spesifik, dan mereka bekerja sama untuk menciptakan sistem approval yang fleksibel dan dapat di-audit. diff --git a/plan/approval-workflow-flow-diagram.md b/plan/approval-workflow-flow-diagram.md new file mode 100644 index 0000000..670a168 --- /dev/null +++ b/plan/approval-workflow-flow-diagram.md @@ -0,0 +1,255 @@ +# Approval Workflow Flow Diagram + +## ๐Ÿ”„ **Complete Approval Process Flow** + +### **1. System Setup Phase** + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ CLIENT โ”‚โ”€โ”€โ”€โ–ถโ”‚ APPROVAL_WORKFLOWS โ”‚โ”€โ”€โ”€โ–ถโ”‚ APPROVAL_WORKFLOW โ”‚ +โ”‚ CREATION โ”‚ โ”‚ (Master Template) โ”‚ โ”‚ STEPS โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ CLIENT_APPROVAL_ โ”‚ + โ”‚ SETTINGS โ”‚ + โ”‚ (Configuration) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### **2. Article Submission Phase** + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ USER LEVEL 3 โ”‚โ”€โ”€โ”€โ–ถโ”‚ CREATE ARTICLE โ”‚โ”€โ”€โ”€โ–ถโ”‚ CHECK USER LEVEL โ”‚ +โ”‚ (POLRES) โ”‚ โ”‚ โ”‚ โ”‚ REQUIRES APPROVAL? โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ YES - CREATE โ”‚ + โ”‚ APPROVAL FLOW โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ ARTICLE_APPROVAL_ โ”‚ + โ”‚ FLOWS โ”‚ + โ”‚ (current_step: 1) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### **3. Step-by-Step Approval Process** + +``` +STEP 1: Level 2 Approval +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ USER LEVEL 2 โ”‚โ”€โ”€โ”€โ–ถโ”‚ REVIEW ARTICLE โ”‚โ”€โ”€โ”€โ–ถโ”‚ APPROVE/REJECT โ”‚ +โ”‚ (POLDAS) โ”‚ โ”‚ (Step 1) โ”‚ โ”‚ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ CREATE STEP LOG โ”‚ + โ”‚ (ARTICLE_APPROVAL_ โ”‚ + โ”‚ STEP_LOGS) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ MOVE TO STEP 2 โ”‚ + โ”‚ (current_step: 2) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + +STEP 2: Level 1 Approval +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ USER LEVEL 1 โ”‚โ”€โ”€โ”€โ–ถโ”‚ REVIEW ARTICLE โ”‚โ”€โ”€โ”€โ–ถโ”‚ APPROVE/REJECT โ”‚ +โ”‚ (POLDAS) โ”‚ โ”‚ (Step 2) โ”‚ โ”‚ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ CREATE STEP LOG โ”‚ + โ”‚ (ARTICLE_APPROVAL_ โ”‚ + โ”‚ STEP_LOGS) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ COMPLETE APPROVAL โ”‚ + โ”‚ (status: approved) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +## ๐Ÿ“Š **Database State Changes** + +### **Initial State (Article Created)** +``` +ARTICLES: +โ”œโ”€โ”€ id: 101 +โ”œโ”€โ”€ title: "Sample Article" +โ”œโ”€โ”€ workflow_id: 1 +โ”œโ”€โ”€ current_approval_step: 1 +โ”œโ”€โ”€ status_id: 1 (pending) +โ””โ”€โ”€ created_by_id: 3 + +ARTICLE_APPROVAL_FLOWS: +โ”œโ”€โ”€ id: 1 +โ”œโ”€โ”€ article_id: 101 +โ”œโ”€โ”€ workflow_id: 1 +โ”œโ”€โ”€ current_step: 1 +โ”œโ”€โ”€ status_id: 1 (pending) +โ”œโ”€โ”€ submitted_by_id: 3 +โ””โ”€โ”€ submitted_at: 2025-01-15 10:00:00 + +ARTICLE_APPROVALS (Legacy): +โ”œโ”€โ”€ id: 1 +โ”œโ”€โ”€ article_id: 101 +โ”œโ”€โ”€ approval_at_level: 2 +โ”œโ”€โ”€ status_id: 1 (pending) +โ””โ”€โ”€ message: "Need Approval" +``` + +### **After Step 1 Approval (Level 2)** +``` +ARTICLES: +โ”œโ”€โ”€ current_approval_step: 2 โ† UPDATED +โ””โ”€โ”€ status_id: 1 (pending) + +ARTICLE_APPROVAL_FLOWS: +โ”œโ”€โ”€ current_step: 2 โ† UPDATED +โ””โ”€โ”€ status_id: 1 (pending) + +ARTICLE_APPROVAL_STEP_LOGS: โ† NEW RECORD +โ”œโ”€โ”€ id: 1 +โ”œโ”€โ”€ approval_flow_id: 1 +โ”œโ”€โ”€ step_order: 1 +โ”œโ”€โ”€ step_name: "Level 2 Review" +โ”œโ”€โ”€ approved_by_id: 2 +โ”œโ”€โ”€ action: "approve" +โ”œโ”€โ”€ message: "Approved by Level 2" +โ””โ”€โ”€ processed_at: 2025-01-15 11:00:00 +``` + +### **After Step 2 Approval (Level 1) - Final** +``` +ARTICLES: +โ”œโ”€โ”€ current_approval_step: null โ† UPDATED +โ”œโ”€โ”€ status_id: 2 (approved) โ† UPDATED +โ”œโ”€โ”€ is_publish: true โ† UPDATED +โ””โ”€โ”€ published_at: 2025-01-15 12:00:00 โ† UPDATED + +ARTICLE_APPROVAL_FLOWS: +โ”œโ”€โ”€ current_step: 2 +โ”œโ”€โ”€ status_id: 2 (approved) โ† UPDATED +โ””โ”€โ”€ completed_at: 2025-01-15 12:00:00 โ† UPDATED + +ARTICLE_APPROVAL_STEP_LOGS: โ† NEW RECORD +โ”œโ”€โ”€ id: 2 +โ”œโ”€โ”€ approval_flow_id: 1 +โ”œโ”€โ”€ step_order: 2 +โ”œโ”€โ”€ step_name: "Level 1 Final Approval" +โ”œโ”€โ”€ approved_by_id: 1 +โ”œโ”€โ”€ action: "approve" +โ”œโ”€โ”€ message: "Final approval by Level 1" +โ””โ”€โ”€ processed_at: 2025-01-15 12:00:00 +``` + +## ๐Ÿ”ง **Module Interaction Matrix** + +| Module | Purpose | Reads From | Writes To | Triggers | +|--------|---------|------------|-----------|----------| +| `articles` | Article Management | - | `articles` | Creates approval flow | +| `approval_workflows` | Workflow Templates | `approval_workflows` | - | Defines steps | +| `approval_workflow_steps` | Step Definitions | `approval_workflow_steps` | - | Defines requirements | +| `article_approval_flows` | Active Instances | `approval_workflows` | `article_approval_flows` | Manages progression | +| `article_approval_step_logs` | Audit Trail | `article_approval_flows` | `article_approval_step_logs` | Logs actions | +| `article_approvals` | Legacy Support | - | `article_approvals` | Backward compatibility | +| `client_approval_settings` | Configuration | `clients` | `client_approval_settings` | Sets defaults | + +## ๐Ÿšจ **Error Handling Flow** + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ ERROR โ”‚โ”€โ”€โ”€โ–ถโ”‚ LOG ERROR โ”‚โ”€โ”€โ”€โ–ถโ”‚ ROLLBACK โ”‚ +โ”‚ OCCURS โ”‚ โ”‚ (Zerolog) โ”‚ โ”‚ TRANSACTION โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ NOTIFY USER โ”‚ + โ”‚ (Error Response) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +## ๐Ÿ”„ **Auto-Skip Logic Flow** + +``` +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ USER LEVEL 1 โ”‚โ”€โ”€โ”€โ–ถโ”‚ CHECK CAN SKIP โ”‚โ”€โ”€โ”€โ–ถโ”‚ SKIP ALL STEPS โ”‚ +โ”‚ (HIGHEST) โ”‚ โ”‚ ALL STEPS? โ”‚ โ”‚ โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ + โ–ผ + โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ AUTO APPROVE โ”‚ + โ”‚ (status: approved) โ”‚ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +## ๐Ÿ“ˆ **Performance Considerations** + +### **Database Indexes Needed** +```sql +-- For fast approval flow lookups +CREATE INDEX idx_article_approval_flows_status ON article_approval_flows(status_id); +CREATE INDEX idx_article_approval_flows_current_step ON article_approval_flows(current_step); + +-- For step log queries +CREATE INDEX idx_article_approval_step_logs_flow_id ON article_approval_step_logs(approval_flow_id); +CREATE INDEX idx_article_approval_step_logs_processed_at ON article_approval_step_logs(processed_at); + +-- For user level queries +CREATE INDEX idx_users_user_level_id ON users(user_level_id); +CREATE INDEX idx_user_levels_level_number ON user_levels(level_number); +``` + +### **Caching Strategy** +``` +1. Workflow Templates โ†’ Cache in Redis +2. User Level Mappings โ†’ Cache in Memory +3. Active Approval Flows โ†’ Cache with TTL +4. Step Requirements โ†’ Cache per Workflow +``` + +## ๐ŸŽฏ **Key Success Metrics** + +1. **Approval Time**: Average time from submission to approval +2. **Step Completion Rate**: Percentage of steps completed successfully +3. **Error Rate**: Percentage of failed approval processes +4. **User Satisfaction**: Feedback on approval process +5. **System Performance**: Response times for approval actions + +## ๐Ÿ” **Debugging Checklist** + +- [ ] Check if workflow exists and is active +- [ ] Verify user level permissions +- [ ] Confirm step order is correct +- [ ] Validate foreign key relationships +- [ ] Check transaction rollback scenarios +- [ ] Monitor step log creation +- [ ] Verify notification delivery +- [ ] Test edge cases (auto-skip, rejection, etc.) + +## ๐Ÿ“ **Summary** + +Sistem approval workflow MEDOLS menggunakan pendekatan modular yang memungkinkan: + +1. **Fleksibilitas**: Workflow dapat dikonfigurasi per client +2. **Auditability**: Setiap action dicatat dalam step logs +3. **Scalability**: Dapat menangani multiple workflow types +4. **Backward Compatibility**: Legacy system tetap berfungsi +5. **User Experience**: Auto-skip untuk user level tinggi + +Dengan arsitektur ini, sistem dapat menangani berbagai skenario approval dengan efisien dan dapat diandalkan. diff --git a/plan/database-relationships-detailed.md b/plan/database-relationships-detailed.md new file mode 100644 index 0000000..86cb4ac --- /dev/null +++ b/plan/database-relationships-detailed.md @@ -0,0 +1,440 @@ +# Database Relationships & Entity Details + +## ๐Ÿ—„๏ธ **Entity Relationship Overview** + +### **Core Entities** + +#### **1. CLIENTS** +```sql +CREATE TABLE clients ( + id UUID PRIMARY KEY, + name VARCHAR NOT NULL, + is_active BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **2. USER_LEVELS** +```sql +CREATE TABLE user_levels ( + id SERIAL PRIMARY KEY, + name VARCHAR NOT NULL, + alias_name VARCHAR NOT NULL, + level_number INTEGER NOT NULL, -- 1=Highest, 2=Mid, 3=Lowest + parent_level_id INTEGER REFERENCES user_levels(id), + province_id INTEGER, + group VARCHAR, + is_approval_active BOOLEAN DEFAULT false, + client_id UUID REFERENCES clients(id), + is_active BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **3. USERS** +```sql +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + name VARCHAR NOT NULL, + email VARCHAR UNIQUE NOT NULL, + user_level_id INTEGER REFERENCES user_levels(id), + client_id UUID REFERENCES clients(id), + is_active BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +### **Workflow Configuration Entities** + +#### **4. APPROVAL_WORKFLOWS** +```sql +CREATE TABLE approval_workflows ( + id SERIAL PRIMARY KEY, + name VARCHAR NOT NULL, + description TEXT, + is_default BOOLEAN DEFAULT false, + is_active BOOLEAN DEFAULT true, + client_id UUID REFERENCES clients(id), + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **5. APPROVAL_WORKFLOW_STEPS** +```sql +CREATE TABLE approval_workflow_steps ( + id SERIAL PRIMARY KEY, + workflow_id INTEGER REFERENCES approval_workflows(id) ON DELETE CASCADE, + step_order INTEGER NOT NULL, -- 1, 2, 3, etc. + step_name VARCHAR NOT NULL, + required_user_level_id INTEGER REFERENCES user_levels(id), + is_required BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **6. CLIENT_APPROVAL_SETTINGS** +```sql +CREATE TABLE client_approval_settings ( + id SERIAL PRIMARY KEY, + client_id UUID REFERENCES clients(id), + workflow_id INTEGER REFERENCES approval_workflows(id), + auto_approve_levels JSONB, -- Array of level numbers + notification_settings JSONB, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +### **Article & Approval Execution Entities** + +#### **7. ARTICLES** +```sql +CREATE TABLE articles ( + id SERIAL PRIMARY KEY, + title VARCHAR NOT NULL, + slug VARCHAR UNIQUE, + description TEXT, + html_description TEXT, + workflow_id INTEGER REFERENCES approval_workflows(id), + current_approval_step INTEGER, + status_id INTEGER, -- 1=pending, 2=approved, 3=rejected + is_publish BOOLEAN DEFAULT false, + published_at TIMESTAMP, + created_by_id INTEGER REFERENCES users(id), + client_id UUID REFERENCES clients(id), + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **8. ARTICLE_APPROVAL_FLOWS** +```sql +CREATE TABLE article_approval_flows ( + id SERIAL PRIMARY KEY, + article_id INTEGER REFERENCES articles(id) ON DELETE CASCADE, + workflow_id INTEGER REFERENCES approval_workflows(id), + current_step INTEGER DEFAULT 1, + status_id INTEGER DEFAULT 1, -- 1=pending, 2=approved, 3=rejected, 4=revision_requested + submitted_by_id INTEGER REFERENCES users(id), + submitted_at TIMESTAMP DEFAULT NOW(), + completed_at TIMESTAMP, + rejection_reason TEXT, + revision_requested BOOLEAN DEFAULT false, + revision_message TEXT, + client_id UUID REFERENCES clients(id), + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **9. ARTICLE_APPROVAL_STEP_LOGS** +```sql +CREATE TABLE article_approval_step_logs ( + id SERIAL PRIMARY KEY, + approval_flow_id INTEGER REFERENCES article_approval_flows(id) ON DELETE CASCADE, + step_order INTEGER NOT NULL, + step_name VARCHAR NOT NULL, + approved_by_id INTEGER REFERENCES users(id), + action VARCHAR NOT NULL, -- approve, reject, auto_skip, request_revision + message TEXT, + processed_at TIMESTAMP DEFAULT NOW(), + user_level_id INTEGER REFERENCES user_levels(id), + created_at TIMESTAMP DEFAULT NOW() +); +``` + +#### **10. ARTICLE_APPROVALS (Legacy)** +```sql +CREATE TABLE article_approvals ( + id SERIAL PRIMARY KEY, + article_id INTEGER REFERENCES articles(id) ON DELETE CASCADE, + approval_by INTEGER REFERENCES users(id), + status_id INTEGER, -- 1=pending, 2=approved, 3=rejected + message TEXT, + approval_at_level INTEGER REFERENCES user_levels(id), + approval_at TIMESTAMP DEFAULT NOW(), + created_at TIMESTAMP DEFAULT NOW() +); +``` + +## ๐Ÿ”— **Relationship Details** + +### **One-to-Many Relationships** + +``` +CLIENTS (1) โ”€โ”€โ†’ (N) USER_LEVELS +CLIENTS (1) โ”€โ”€โ†’ (N) USERS +CLIENTS (1) โ”€โ”€โ†’ (N) APPROVAL_WORKFLOWS +CLIENTS (1) โ”€โ”€โ†’ (N) ARTICLES +CLIENTS (1) โ”€โ”€โ†’ (N) CLIENT_APPROVAL_SETTINGS + +USER_LEVELS (1) โ”€โ”€โ†’ (N) USERS +USER_LEVELS (1) โ”€โ”€โ†’ (N) APPROVAL_WORKFLOW_STEPS +USER_LEVELS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_STEP_LOGS + +APPROVAL_WORKFLOWS (1) โ”€โ”€โ†’ (N) APPROVAL_WORKFLOW_STEPS +APPROVAL_WORKFLOWS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_FLOWS +APPROVAL_WORKFLOWS (1) โ”€โ”€โ†’ (N) ARTICLES + +ARTICLES (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_FLOWS +ARTICLES (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVALS + +ARTICLE_APPROVAL_FLOWS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_STEP_LOGS + +USERS (1) โ”€โ”€โ†’ (N) ARTICLES (as creator) +USERS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_FLOWS (as submitter) +USERS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVAL_STEP_LOGS (as approver) +USERS (1) โ”€โ”€โ†’ (N) ARTICLE_APPROVALS (as approver) +``` + +### **Many-to-Many Relationships (Implicit)** + +``` +USERS โ†โ†’ USER_LEVELS (through user_level_id) +ARTICLES โ†โ†’ APPROVAL_WORKFLOWS (through workflow_id) +ARTICLE_APPROVAL_FLOWS โ†โ†’ APPROVAL_WORKFLOW_STEPS (through workflow_id and step_order) +``` + +## ๐Ÿ“Š **Data Flow Examples** + +### **Example 1: Complete Approval Process** + +#### **Step 1: Setup Data** +```sql +-- Client +INSERT INTO clients (id, name) VALUES ('b1ce6602-07ad-46c2-85eb-0cd6decfefa3', 'Test Client'); + +-- User Levels +INSERT INTO user_levels (name, alias_name, level_number, is_approval_active, client_id) VALUES +('POLDAS', 'Poldas', 1, true, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'), +('POLDAS', 'Poldas', 2, true, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'), +('POLRES', 'Polres', 3, true, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'); + +-- Users +INSERT INTO users (name, email, user_level_id, client_id) VALUES +('Admin Level 1', 'admin1@test.com', 1, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'), +('Admin Level 2', 'admin2@test.com', 2, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'), +('User Level 3', 'user3@test.com', 3, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'); + +-- Workflow +INSERT INTO approval_workflows (name, description, is_default, client_id) VALUES +('Standard Approval', 'Standard 3-step approval process', true, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'); + +-- Workflow Steps +INSERT INTO approval_workflow_steps (workflow_id, step_order, step_name, required_user_level_id) VALUES +(1, 1, 'Level 2 Review', 2), +(1, 2, 'Level 1 Final Approval', 1); +``` + +#### **Step 2: Article Creation** +```sql +-- Article created by User Level 3 +INSERT INTO articles (title, slug, workflow_id, current_approval_step, status_id, created_by_id, client_id) VALUES +('Test Article', 'test-article', 1, 1, 1, 3, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'); + +-- Approval Flow +INSERT INTO article_approval_flows (article_id, workflow_id, current_step, status_id, submitted_by_id, client_id) VALUES +(1, 1, 1, 1, 3, 'b1ce6602-07ad-46c2-85eb-0cd6decfefa3'); + +-- Legacy Approval +INSERT INTO article_approvals (article_id, approval_by, status_id, message, approval_at_level) VALUES +(1, 3, 1, 'Need Approval', 2); +``` + +#### **Step 3: Level 2 Approval** +```sql +-- Step Log +INSERT INTO article_approval_step_logs (approval_flow_id, step_order, step_name, approved_by_id, action, message, user_level_id) VALUES +(1, 1, 'Level 2 Review', 2, 'approve', 'Approved by Level 2', 2); + +-- Update Flow +UPDATE article_approval_flows SET current_step = 2 WHERE id = 1; + +-- Update Article +UPDATE articles SET current_approval_step = 2 WHERE id = 1; +``` + +#### **Step 4: Level 1 Final Approval** +```sql +-- Step Log +INSERT INTO article_approval_step_logs (approval_flow_id, step_order, step_name, approved_by_id, action, message, user_level_id) VALUES +(1, 2, 'Level 1 Final Approval', 1, 'approve', 'Final approval by Level 1', 1); + +-- Complete Flow +UPDATE article_approval_flows SET + status_id = 2, + completed_at = NOW() +WHERE id = 1; + +-- Publish Article +UPDATE articles SET + status_id = 2, + is_publish = true, + published_at = NOW(), + current_approval_step = NULL +WHERE id = 1; +``` + +## ๐Ÿ” **Key Queries for Monitoring** + +### **Active Approval Flows** +```sql +SELECT + aaf.id as flow_id, + a.title as article_title, + aaf.current_step, + aws.step_name as current_step_name, + ul.name as required_approver_level, + u.name as submitted_by, + aaf.submitted_at, + aaf.status_id +FROM article_approval_flows aaf +JOIN articles a ON aaf.article_id = a.id +JOIN approval_workflow_steps aws ON aaf.workflow_id = aws.workflow_id + AND aaf.current_step = aws.step_order +JOIN user_levels ul ON aws.required_user_level_id = ul.id +JOIN users u ON aaf.submitted_by_id = u.id +WHERE aaf.status_id = 1 -- pending +ORDER BY aaf.submitted_at DESC; +``` + +### **Approval History** +```sql +SELECT + a.title as article_title, + aasl.step_name, + aasl.action, + aasl.message, + u.name as approver_name, + ul.name as approver_level, + aasl.processed_at +FROM article_approval_step_logs aasl +JOIN article_approval_flows aaf ON aasl.approval_flow_id = aaf.id +JOIN articles a ON aaf.article_id = a.id +JOIN users u ON aasl.approved_by_id = u.id +JOIN user_levels ul ON aasl.user_level_id = ul.id +WHERE aaf.article_id = ? -- specific article +ORDER BY aasl.step_order, aasl.processed_at; +``` + +### **Workflow Performance** +```sql +SELECT + aw.name as workflow_name, + COUNT(aaf.id) as total_flows, + COUNT(CASE WHEN aaf.status_id = 2 THEN 1 END) as approved, + COUNT(CASE WHEN aaf.status_id = 3 THEN 1 END) as rejected, + AVG(EXTRACT(EPOCH FROM (aaf.completed_at - aaf.submitted_at))/3600) as avg_hours +FROM approval_workflows aw +LEFT JOIN article_approval_flows aaf ON aw.id = aaf.workflow_id +WHERE aw.client_id = ? +GROUP BY aw.id, aw.name; +``` + +## โš ๏ธ **Common Data Issues** + +### **Issue 1: Orphaned Records** +```sql +-- Find articles without approval flows +SELECT a.id, a.title +FROM articles a +LEFT JOIN article_approval_flows aaf ON a.id = aaf.article_id +WHERE aaf.id IS NULL AND a.workflow_id IS NOT NULL; + +-- Find approval flows without articles +SELECT aaf.id, aaf.article_id +FROM article_approval_flows aaf +LEFT JOIN articles a ON aaf.article_id = a.id +WHERE a.id IS NULL; +``` + +### **Issue 2: Inconsistent Step Data** +```sql +-- Find flows with invalid current_step +SELECT aaf.id, aaf.current_step, aws.step_order +FROM article_approval_flows aaf +JOIN approval_workflow_steps aws ON aaf.workflow_id = aws.workflow_id +WHERE aaf.current_step != aws.step_order; +``` + +### **Issue 3: Missing Step Logs** +```sql +-- Find approved flows without step logs +SELECT aaf.id, aaf.article_id, aaf.status_id +FROM article_approval_flows aaf +LEFT JOIN article_approval_step_logs aasl ON aaf.id = aasl.approval_flow_id +WHERE aaf.status_id = 2 AND aasl.id IS NULL; +``` + +## ๐Ÿš€ **Performance Optimization** + +### **Indexes** +```sql +-- Primary indexes +CREATE INDEX idx_article_approval_flows_status ON article_approval_flows(status_id); +CREATE INDEX idx_article_approval_flows_current_step ON article_approval_flows(current_step); +CREATE INDEX idx_article_approval_flows_client_id ON article_approval_flows(client_id); +CREATE INDEX idx_article_approval_step_logs_flow_id ON article_approval_step_logs(approval_flow_id); +CREATE INDEX idx_article_approval_step_logs_processed_at ON article_approval_step_logs(processed_at); +CREATE INDEX idx_articles_workflow_id ON articles(workflow_id); +CREATE INDEX idx_articles_status_id ON articles(status_id); +CREATE INDEX idx_users_user_level_id ON users(user_level_id); +CREATE INDEX idx_user_levels_level_number ON user_levels(level_number); + +-- Composite indexes +CREATE INDEX idx_article_approval_flows_status_step ON article_approval_flows(status_id, current_step); +CREATE INDEX idx_approval_workflow_steps_workflow_order ON approval_workflow_steps(workflow_id, step_order); +``` + +### **Partitioning (for large datasets)** +```sql +-- Partition article_approval_step_logs by month +CREATE TABLE article_approval_step_logs_2025_01 PARTITION OF article_approval_step_logs +FOR VALUES FROM ('2025-01-01') TO ('2025-02-01'); +``` + +## ๐Ÿ“ **Data Validation Rules** + +### **Business Rules** +1. **Workflow Steps**: Must be sequential (1, 2, 3, etc.) +2. **User Levels**: Level number must be unique per client +3. **Approval Flows**: Can only have one active flow per article +4. **Step Logs**: Must have corresponding workflow step +5. **Status Transitions**: Only valid transitions allowed + +### **Database Constraints** +```sql +-- Ensure step order is sequential +ALTER TABLE approval_workflow_steps +ADD CONSTRAINT chk_step_order_positive CHECK (step_order > 0); + +-- Ensure level number is positive +ALTER TABLE user_levels +ADD CONSTRAINT chk_level_number_positive CHECK (level_number > 0); + +-- Ensure status values are valid +ALTER TABLE article_approval_flows +ADD CONSTRAINT chk_status_valid CHECK (status_id IN (1, 2, 3, 4)); + +-- Ensure current step is valid +ALTER TABLE article_approval_flows +ADD CONSTRAINT chk_current_step_positive CHECK (current_step > 0); +``` + +## ๐ŸŽฏ **Summary** + +Database design untuk sistem approval workflow MEDOLS menggunakan: + +1. **Normalized Structure**: Memisahkan konfigurasi dari eksekusi +2. **Audit Trail**: Step logs untuk tracking lengkap +3. **Flexibility**: Workflow dapat dikonfigurasi per client +4. **Performance**: Indexes untuk query yang efisien +5. **Data Integrity**: Constraints dan validasi +6. **Scalability**: Partitioning untuk data besar + +Dengan struktur ini, sistem dapat menangani berbagai skenario approval dengan efisien dan dapat diandalkan. diff --git a/plan/dynamic-article-approval-system-plan.md b/plan/dynamic-article-approval-system-plan.md new file mode 100644 index 0000000..2116aa6 --- /dev/null +++ b/plan/dynamic-article-approval-system-plan.md @@ -0,0 +1,335 @@ +# Plan Implementasi Sistem Approval Artikel Dinamis + +## 1. Analisis Sistem Saat Ini + +### Struktur Database yang Sudah Ada: +- **Articles**: Memiliki field `NeedApprovalFrom`, `HasApprovedBy`, `StatusId` untuk tracking approval +- **ArticleApprovals**: Menyimpan history approval dengan `ApprovalAtLevel` +- **Users**: Terhubung dengan `UserLevels` dan `UserRoles` +- **UserLevels**: Memiliki `LevelNumber`, `ParentLevelId`, `IsApprovalActive` +- **UserRoles**: Terhubung dengan `UserLevels` melalui `UserRoleLevelDetails` +- **UserRoleAccesses**: Memiliki `IsApprovalEnabled` untuk kontrol akses approval +- **MasterApprovalStatuses**: Status approval (pending, approved, rejected) + +### Logika Approval Saat Ini: +- Hard-coded untuk 3 level (level 1, 2, 3) +- Approval naik ke parent level jika disetujui +- Kembali ke contributor jika ditolak +- Status: 1=Pending, 2=Approved, 3=Rejected + +## 2. Kebutuhan Sistem Baru + +### Functional Requirements: +1. **Dynamic Approval Levels**: Sistem harus mendukung 1-N level approval +2. **Flexible Workflow**: Approval flow bisa diubah sewaktu-waktu +3. **Role-based Access**: Approver dan Contributor dengan hak akses berbeda +4. **Revision Handling**: Artikel kembali ke contributor saat revisi diminta +5. **Audit Trail**: Tracking lengkap history approval + +### User Stories: +- Sebagai **Contributor**: Saya bisa membuat artikel dan submit untuk approval +- Sebagai **Approver Level N**: Saya bisa approve/reject/request revision artikel +- Sebagai **Admin**: Saya bisa mengatur approval workflow secara dinamis + +## 3. Desain Database Baru + +### 3.1 Tabel Baru yang Diperlukan: + +#### `approval_workflows` +```sql +CREATE TABLE approval_workflows ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + is_active BOOLEAN DEFAULT true, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### `approval_workflow_steps` +```sql +CREATE TABLE approval_workflow_steps ( + id SERIAL PRIMARY KEY, + workflow_id INT REFERENCES approval_workflows(id), + step_order INT NOT NULL, + user_level_id INT REFERENCES user_levels(id), + is_required BOOLEAN DEFAULT true, + can_skip BOOLEAN DEFAULT false, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### `article_approval_flows` +```sql +CREATE TABLE article_approval_flows ( + id SERIAL PRIMARY KEY, + article_id INT REFERENCES articles(id), + workflow_id INT REFERENCES approval_workflows(id), + current_step INT DEFAULT 1, + status_id INT DEFAULT 1, -- 1=In Progress, 2=Completed, 3=Rejected + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +#### `article_approval_step_logs` +```sql +CREATE TABLE article_approval_step_logs ( + id SERIAL PRIMARY KEY, + article_flow_id INT REFERENCES article_approval_flows(id), + step_order INT NOT NULL, + user_level_id INT REFERENCES user_levels(id), + approved_by INT REFERENCES users(id), + action VARCHAR(50) NOT NULL, -- 'approved', 'rejected', 'revision_requested' + message TEXT, + approved_at TIMESTAMP, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW() +); +``` + +### 3.2 Modifikasi Tabel Existing: + +#### `articles` - Tambah field: +```sql +ALTER TABLE articles ADD COLUMN workflow_id INT REFERENCES approval_workflows(id); +ALTER TABLE articles ADD COLUMN current_approval_step INT DEFAULT 0; +-- Keep existing fields: need_approval_from, has_approved_by, status_id untuk backward compatibility +``` + +#### `user_roles` - Tambah field: +```sql +ALTER TABLE user_roles ADD COLUMN role_type VARCHAR(50) DEFAULT 'contributor'; -- 'contributor', 'approver', 'admin' +``` + +## 4. Implementasi Backend + +### 4.1 Entities Baru: +- `ApprovalWorkflows` +- `ApprovalWorkflowSteps` +- `ArticleApprovalFlows` +- `ArticleApprovalStepLogs` + +### 4.2 Modules Baru: + +#### `approval_workflows` +- **Repository**: CRUD operations untuk workflow management +- **Service**: Business logic untuk workflow creation/modification +- **Controller**: API endpoints untuk workflow management +- **Request/Response**: DTOs untuk workflow operations + +#### `article_approval_flows` +- **Repository**: Tracking approval progress per artikel +- **Service**: Core approval logic, step progression +- **Controller**: API untuk approval actions +- **Request/Response**: DTOs untuk approval operations + +### 4.3 Modifikasi Modules Existing: + +#### `articles/service` +- Refactor `UpdateApproval()` method untuk menggunakan dynamic workflow +- Tambah method `InitiateApprovalFlow()` untuk memulai approval process +- Tambah method `ProcessApprovalStep()` untuk handle approval actions + +#### `article_approvals` +- Extend untuk support dynamic workflow +- Integrate dengan `ArticleApprovalStepLogs` + +## 5. API Design + +### 5.1 Workflow Management APIs: +``` +GET /api/approval-workflows # List all workflows +POST /api/approval-workflows # Create new workflow +GET /api/approval-workflows/{id} # Get workflow details +PUT /api/approval-workflows/{id} # Update workflow +DELETE /api/approval-workflows/{id} # Delete workflow + +GET /api/approval-workflows/{id}/steps # Get workflow steps +POST /api/approval-workflows/{id}/steps # Add workflow step +PUT /api/approval-workflow-steps/{id} # Update workflow step +DELETE /api/approval-workflow-steps/{id} # Delete workflow step +``` + +### 5.2 Article Approval APIs: +``` +POST /api/articles/{id}/submit-approval # Submit article for approval +POST /api/articles/{id}/approve # Approve current step +POST /api/articles/{id}/reject # Reject article +POST /api/articles/{id}/request-revision # Request revision +GET /api/articles/{id}/approval-history # Get approval history +GET /api/articles/pending-approval # Get articles pending approval for current user +``` + +### 5.3 Request/Response Models: + +#### Workflow Creation: +```json +{ + "name": "Standard Article Approval", + "description": "3-level approval process", + "steps": [ + { + "stepOrder": 1, + "userLevelId": 3, + "isRequired": true, + "canSkip": false + }, + { + "stepOrder": 2, + "userLevelId": 2, + "isRequired": true, + "canSkip": false + }, + { + "stepOrder": 3, + "userLevelId": 1, + "isRequired": true, + "canSkip": false + } + ] +} +``` + +#### Approval Action: +```json +{ + "action": "approved", // "approved", "rejected", "revision_requested" + "message": "Article looks good, approved for next level" +} +``` + +## 6. Business Logic Flow + +### 6.1 Article Submission Flow: +1. Contributor creates article (status: draft) +2. Contributor submits for approval +3. System creates `ArticleApprovalFlow` record +4. System sets article status to "pending approval" +5. System notifies first level approver + +### 6.2 Approval Process Flow: +1. Approver receives notification +2. Approver reviews article +3. Approver takes action: + - **Approve**: Move to next step or publish if final step + - **Reject**: Set article status to rejected, end flow + - **Request Revision**: Send back to contributor + +### 6.3 Revision Flow: +1. Article returns to contributor +2. Contributor makes revisions +3. Contributor resubmits +4. Approval flow restarts from step 1 + +## 7. Implementation Phases + +### Phase 1: Database & Core Entities +- [ ] Create new database tables +- [ ] Implement new entities +- [ ] Create migration scripts +- [ ] Update existing entities + +### Phase 2: Workflow Management +- [ ] Implement `approval_workflows` module +- [ ] Create workflow CRUD operations +- [ ] Implement workflow step management +- [ ] Create admin interface for workflow setup + +### Phase 3: Dynamic Approval Engine +- [ ] Implement `article_approval_flows` module +- [ ] Refactor articles service for dynamic approval +- [ ] Create approval processing logic +- [ ] Implement notification system + +### Phase 4: API & Integration +- [ ] Create approval APIs +- [ ] Update existing article APIs +- [ ] Implement role-based access control +- [ ] Create approval dashboard + +### Phase 5: Testing & Migration +- [ ] Unit tests for all new modules +- [ ] Integration tests for approval flows +- [ ] Data migration from old system +- [ ] Performance testing + +## 8. Backward Compatibility + +### Migration Strategy: +1. **Dual System**: Run old and new system parallel +2. **Default Workflow**: Create default workflow matching current 3-level system +3. **Gradual Migration**: Migrate existing articles to new system +4. **Fallback**: Keep old approval logic as fallback + +### Data Migration: +```sql +-- Create default workflow +INSERT INTO approval_workflows (name, description) +VALUES ('Legacy 3-Level Approval', 'Default 3-level approval system'); + +-- Create workflow steps +INSERT INTO approval_workflow_steps (workflow_id, step_order, user_level_id) +VALUES +(1, 1, 3), -- Level 3 approver +(1, 2, 2), -- Level 2 approver +(1, 3, 1); -- Level 1 approver + +-- Update existing articles +UPDATE articles SET workflow_id = 1 WHERE workflow_id IS NULL; +``` + +## 9. Security Considerations + +### Access Control: +- **Contributor**: Can only create and edit own articles +- **Approver**: Can only approve articles at their assigned level +- **Admin**: Can manage workflows and override approvals + +### Validation: +- Validate user has permission for approval level +- Prevent approval of own articles +- Validate workflow step sequence +- Audit all approval actions + +## 10. Performance Considerations + +### Optimization: +- Index on `article_approval_flows.article_id` +- Index on `article_approval_flows.workflow_id` +- Index on `article_approval_step_logs.article_flow_id` +- Cache active workflows +- Batch notification processing + +### Monitoring: +- Track approval processing time +- Monitor workflow bottlenecks +- Alert on stuck approvals +- Dashboard for approval metrics + +## 11. Future Enhancements + +### Possible Extensions: +1. **Conditional Workflows**: Different workflows based on article type/category +2. **Parallel Approvals**: Multiple approvers at same level +3. **Time-based Escalation**: Auto-escalate if approval takes too long +4. **External Integrations**: Email/Slack notifications +5. **Approval Templates**: Pre-defined approval messages +6. **Bulk Approvals**: Approve multiple articles at once + +--- + +**Estimasi Waktu Implementasi**: 4-6 minggu +**Kompleksitas**: Medium-High +**Risk Level**: Medium (karena perubahan core business logic) + +**Next Steps**: +1. Review dan approval plan ini +2. Setup development environment +3. Mulai implementasi Phase 1 +4. Regular progress review setiap minggu \ No newline at end of file diff --git a/plan/end-to-end-testing-scenarios.md b/plan/end-to-end-testing-scenarios.md new file mode 100644 index 0000000..f15e4e6 --- /dev/null +++ b/plan/end-to-end-testing-scenarios.md @@ -0,0 +1,785 @@ +# End-to-End Testing Scenarios - Approval Workflow System + +## Overview +Dokumentasi ini berisi skenario testing end-to-end lengkap untuk sistem approval workflow, mulai dari pembuatan client baru hingga pembuatan artikel dengan proses approval yang dinamis. + +## Base Configuration +```bash +# Base URL +BASE_URL="http://localhost:8800/api" + +# Headers +AUTH_HEADER="Authorization: Bearer YOUR_JWT_TOKEN" +CLIENT_HEADER="X-Client-Key: YOUR_CLIENT_KEY" +CONTENT_TYPE="Content-Type: application/json" +``` + +--- + +## ๐Ÿข Scenario 1: Complete Client Setup to Article Creation + +### Step 1: Create New Client +```bash +curl -X POST "${BASE_URL}/clients" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Test Media Company", + "is_active": true + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Client created successfully"], + "data": { + "id": "550e8400-e29b-41d4-a716-446655440000", + "name": "Test Media Company", + "is_active": true, + "created_at": "2024-01-15T10:00:00Z" + } +} +``` + +### Step 2: Create User Levels +```bash +# Create user levels for approval workflow +curl -X POST "${BASE_URL}/user-levels" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Editor", + "alias_name": "ED", + "level_number": 1, + "is_approval_active": true + }' + +curl -X POST "${BASE_URL}/user-levels" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Senior Editor", + "alias_name": "SED", + "level_number": 2, + "is_approval_active": true + }' + +curl -X POST "${BASE_URL}/user-levels" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Editor in Chief", + "alias_name": "EIC", + "level_number": 3, + "is_approval_active": true + }' +``` + +### Step 3: Create Approval Workflow +```bash +curl -X POST "${BASE_URL}/approval-workflows" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Standard 3-Level Editorial Review", + "description": "Complete editorial workflow with 3 approval levels", + "is_default": true, + "is_active": true, + "requires_approval": true, + "auto_publish": false, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +### Step 4: Create Workflow Steps +```bash +# Step 1: Editor Review +curl -X POST "${BASE_URL}/approval-workflow-steps" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "step_order": 1, + "step_name": "Editor Review", + "required_user_level_id": 1, + "can_skip": false, + "auto_approve_after_hours": 24, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' + +# Step 2: Senior Editor Review +curl -X POST "${BASE_URL}/approval-workflow-steps" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "step_order": 2, + "step_name": "Senior Editor Review", + "required_user_level_id": 2, + "can_skip": false, + "auto_approve_after_hours": 48, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' + +# Step 3: Editor in Chief +curl -X POST "${BASE_URL}/approval-workflow-steps" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "step_order": 3, + "step_name": "Editor in Chief Approval", + "required_user_level_id": 3, + "can_skip": false, + "auto_approve_after_hours": 72, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +### Step 5: Configure Client Approval Settings +```bash +curl -X POST "${BASE_URL}/client-approval-settings" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "client_id": "550e8400-e29b-41d4-a716-446655440000", + "requires_approval": true, + "default_workflow_id": 1, + "auto_publish_articles": false, + "approval_exempt_users": [], + "approval_exempt_roles": [], + "approval_exempt_categories": [], + "require_approval_for": ["article", "news", "review"], + "skip_approval_for": ["announcement", "update"], + "is_active": true + }' +``` + +### Step 6: Create Article Category +```bash +curl -X POST "${BASE_URL}/article-categories" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "title": "Technology News", + "description": "Latest technology news and updates", + "slug": "technology-news", + "status_id": 1, + "is_publish": true, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +### Step 7: Create Article +```bash +curl -X POST "${BASE_URL}/articles" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "title": "Revolutionary AI Technology Breakthrough", + "slug": "revolutionary-ai-technology-breakthrough", + "description": "A comprehensive look at the latest AI breakthrough that could change everything", + "html_description": "

A comprehensive look at the latest AI breakthrough that could change everything

", + "category_id": 1, + "type_id": 1, + "tags": "AI, Technology, Innovation, Breakthrough", + "created_by_id": 1, + "status_id": 1, + "is_draft": false, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article created successfully"], + "data": { + "id": 1, + "title": "Revolutionary AI Technology Breakthrough", + "status_id": 1, + "is_draft": false, + "approval_required": true, + "workflow_id": 1, + "created_at": "2024-01-15T10:30:00Z" + } +} +``` + +--- + +## ๐Ÿ“ Scenario 2: Complete Approval Process + +### Step 1: Submit Article for Approval +```bash +curl -X POST "${BASE_URL}/articles/1/submit-approval" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "message": "Article ready for editorial review process" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article submitted for approval successfully"], + "data": { + "id": 1, + "article_id": 1, + "workflow_id": 1, + "current_step": 1, + "status_id": 1, + "submitted_at": "2024-01-15T10:35:00Z" + } +} +``` + +### Step 2: Check Approval Status +```bash +curl -X GET "${BASE_URL}/articles/1/approval-status" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Approval status retrieved successfully"], + "data": { + "article_id": 1, + "current_status": "pending_approval", + "current_step": 1, + "total_steps": 3, + "workflow_name": "Standard 3-Level Editorial Review", + "current_step_name": "Editor Review", + "next_step_name": "Senior Editor Review", + "waiting_since": "2024-01-15T10:35:00Z" + } +} +``` + +### Step 3: Editor Approves (Step 1) +```bash +curl -X POST "${BASE_URL}/articles/1/approve" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Content quality meets editorial standards, approved for next level" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article approved successfully"], + "data": { + "current_step": 2, + "status": "moved_to_next_level", + "next_approver_level": 2, + "approved_at": "2024-01-15T11:00:00Z" + } +} +``` + +### Step 4: Senior Editor Approves (Step 2) +```bash +curl -X POST "${BASE_URL}/articles/1/approve" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Excellent content quality and structure, ready for final approval" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article approved successfully"], + "data": { + "current_step": 3, + "status": "moved_to_next_level", + "next_approver_level": 3, + "approved_at": "2024-01-15T12:00:00Z" + } +} +``` + +### Step 5: Editor in Chief Approves (Step 3 - Final) +```bash +curl -X POST "${BASE_URL}/articles/1/approve" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Final approval granted, content ready for publication" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article approved and published successfully"], + "data": { + "status": "approved", + "article_status": "published", + "is_publish": true, + "published_at": "2024-01-15T13:00:00Z", + "completion_date": "2024-01-15T13:00:00Z" + } +} +``` + +--- + +## โŒ Scenario 3: Article Rejection and Revision + +### Step 1: Submit Another Article +```bash +curl -X POST "${BASE_URL}/articles" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "title": "Product Review: New Smartphone", + "slug": "product-review-new-smartphone", + "description": "Comprehensive review of the latest smartphone", + "html_description": "

Comprehensive review of the latest smartphone

", + "category_id": 1, + "type_id": 1, + "tags": "Review, Smartphone, Technology", + "created_by_id": 1, + "status_id": 1, + "is_draft": false, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +### Step 2: Submit for Approval +```bash +curl -X POST "${BASE_URL}/articles/2/submit-approval" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "message": "Product review ready for approval" + }' +``` + +### Step 3: Editor Approves (Step 1) +```bash +curl -X POST "${BASE_URL}/articles/2/approve" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Initial review passed, good structure" + }' +``` + +### Step 4: Senior Editor Rejects (Step 2) +```bash +curl -X POST "${BASE_URL}/articles/2/reject" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Insufficient technical details and benchmark comparisons needed" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article rejected successfully"], + "data": { + "status": "rejected", + "article_status": "draft", + "rejection_reason": "Insufficient technical details and benchmark comparisons needed", + "rejected_at": "2024-01-15T14:00:00Z" + } +} +``` + +### Step 5: Request Revision +```bash +curl -X POST "${BASE_URL}/articles/2/request-revision" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Please add detailed technical specifications, benchmark comparisons, and more comprehensive testing results" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Revision requested successfully"], + "data": { + "status": "revision_requested", + "revision_message": "Please add detailed technical specifications, benchmark comparisons, and more comprehensive testing results", + "requested_at": "2024-01-15T14:15:00Z" + } +} +``` + +### Step 6: Resubmit After Revision +```bash +curl -X POST "${BASE_URL}/articles/2/resubmit" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "message": "Article revised with additional technical details and benchmark comparisons" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article resubmitted successfully"], + "data": { + "status": "pending_approval", + "current_step": 1, + "resubmitted_at": "2024-01-15T15:00:00Z" + } +} +``` + +--- + +## โšก Scenario 4: Dynamic Approval Toggle + +### Step 1: Check Current Settings +```bash +curl -X GET "${BASE_URL}/client-approval-settings" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 2: Disable Approval System +```bash +curl -X PUT "${BASE_URL}/client-approval-settings/1" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "requires_approval": false, + "auto_publish_articles": true, + "reason": "Breaking news mode - immediate publishing required" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Approval settings updated successfully"], + "data": { + "requires_approval": false, + "auto_publish_articles": true, + "updated_at": "2024-01-15T16:00:00Z" + } +} +``` + +### Step 3: Create Article (Should Auto-Publish) +```bash +curl -X POST "${BASE_URL}/articles" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "title": "BREAKING: Major Tech Acquisition", + "slug": "breaking-major-tech-acquisition", + "description": "Breaking news about major technology acquisition", + "html_description": "

Breaking news about major technology acquisition

", + "category_id": 1, + "type_id": 1, + "tags": "Breaking, News, Acquisition, Technology", + "created_by_id": 1, + "status_id": 1, + "is_draft": false, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +**Expected Response:** +```json +{ + "success": true, + "messages": ["Article created and published successfully"], + "data": { + "id": 3, + "title": "BREAKING: Major Tech Acquisition", + "status": "published", + "is_publish": true, + "published_at": "2024-01-15T16:05:00Z", + "approval_bypassed": true, + "bypass_reason": "approval_disabled" + } +} +``` + +### Step 4: Re-enable Approval System +```bash +curl -X PUT "${BASE_URL}/client-approval-settings/1" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "requires_approval": true, + "auto_publish_articles": false, + "default_workflow_id": 1, + "reason": "Returning to normal approval process" + }' +``` + +--- + +## ๐Ÿ“Š Scenario 5: Approval Dashboard and Monitoring + +### Step 1: Get Pending Approvals +```bash +curl -X GET "${BASE_URL}/approvals/pending?page=1&limit=10" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 2: Get My Approval Queue +```bash +curl -X GET "${BASE_URL}/approvals/my-queue?page=1&limit=10" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 3: Get Approval History for Article +```bash +curl -X GET "${BASE_URL}/articles/1/approval-history" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 4: Get My Approval Statistics +```bash +curl -X GET "${BASE_URL}/approvals/my-stats" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +--- + +## ๐Ÿ”ง Scenario 6: Workflow Management + +### Step 1: Get All Workflows +```bash +curl -X GET "${BASE_URL}/approval-workflows?page=1&limit=10" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 2: Get Workflow by ID +```bash +curl -X GET "${BASE_URL}/approval-workflows/1" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" +``` + +### Step 3: Update Workflow +```bash +curl -X PUT "${BASE_URL}/approval-workflows/1" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "name": "Updated 3-Level Editorial Review", + "description": "Updated workflow with improved efficiency", + "is_active": true + }' +``` + +### Step 4: Add New Workflow Step +```bash +curl -X POST "${BASE_URL}/approval-workflow-steps" \ + -H "${AUTH_HEADER}" \ + -H "${CLIENT_HEADER}" \ + -H "${CONTENT_TYPE}" \ + -d '{ + "workflow_id": 1, + "step_order": 2, + "step_name": "Legal Review", + "required_user_level_id": 4, + "can_skip": true, + "auto_approve_after_hours": 24, + "client_id": "550e8400-e29b-41d4-a716-446655440000" + }' +``` + +--- + +## ๐Ÿงช Test Data Setup Script + +```bash +#!/bin/bash + +# Set environment variables +BASE_URL="http://localhost:8800/api" +AUTH_HEADER="Authorization: Bearer YOUR_JWT_TOKEN" +CLIENT_HEADER="X-Client-Key: YOUR_CLIENT_KEY" +CONTENT_TYPE="Content-Type: application/json" + +# Function to make API calls +make_request() { + local method=$1 + local endpoint=$2 + local data=$3 + + if [ -n "$data" ]; then + curl -X "$method" "${BASE_URL}${endpoint}" \ + -H "$AUTH_HEADER" \ + -H "$CLIENT_HEADER" \ + -H "$CONTENT_TYPE" \ + -d "$data" + else + curl -X "$method" "${BASE_URL}${endpoint}" \ + -H "$AUTH_HEADER" \ + -H "$CLIENT_HEADER" + fi +} + +echo "Setting up test data..." + +# 1. Create client +echo "Creating client..." +make_request "POST" "/clients" '{ + "name": "Test Media Company", + "is_active": true +}' + +# 2. Create user levels +echo "Creating user levels..." +make_request "POST" "/user-levels" '{ + "name": "Editor", + "alias_name": "ED", + "level_number": 1, + "is_approval_active": true +}' + +make_request "POST" "/user-levels" '{ + "name": "Senior Editor", + "alias_name": "SED", + "level_number": 2, + "is_approval_active": true +}' + +make_request "POST" "/user-levels" '{ + "name": "Editor in Chief", + "alias_name": "EIC", + "level_number": 3, + "is_approval_active": true +}' + +# 3. Create approval workflow +echo "Creating approval workflow..." +make_request "POST" "/approval-workflows" '{ + "name": "Standard 3-Level Editorial Review", + "description": "Complete editorial workflow with 3 approval levels", + "is_default": true, + "is_active": true, + "requires_approval": true, + "auto_publish": false +}' + +echo "Test data setup completed!" +``` + +--- + +## ๐Ÿ“‹ Test Validation Checklist + +### โœ… Functional Testing +- [ ] Client creation and configuration +- [ ] User level management +- [ ] Approval workflow creation and modification +- [ ] Article creation and submission +- [ ] Complete approval process flow +- [ ] Article rejection and revision process +- [ ] Dynamic approval toggle functionality +- [ ] Approval dashboard and monitoring +- [ ] Multi-step workflow progression +- [ ] Auto-publish functionality + +### โœ… Error Handling +- [ ] Invalid client key handling +- [ ] Invalid JWT token handling +- [ ] Missing required fields validation +- [ ] Workflow step validation +- [ ] User permission validation +- [ ] Article status validation + +### โœ… Performance Testing +- [ ] Response time < 500ms for all endpoints +- [ ] Concurrent approval processing +- [ ] Large dataset pagination +- [ ] Database query optimization + +### โœ… Security Testing +- [ ] Client isolation +- [ ] User authorization +- [ ] Data validation and sanitization +- [ ] SQL injection prevention + +--- + +## ๐Ÿš€ Running the Tests + +### Prerequisites +1. Ensure the backend server is running on `http://localhost:8800` +2. Obtain valid JWT token for authentication +3. Set up client key for multi-tenant support +4. Database should be clean and ready for testing + +### Execution Steps +1. Run the test data setup script +2. Execute each scenario sequentially +3. Validate responses against expected outputs +4. Check database state after each scenario +5. Clean up test data after completion + +### Monitoring +- Monitor server logs during testing +- Check database performance metrics +- Validate all audit trails are created +- Ensure proper error handling and logging + +--- + +*This documentation provides comprehensive end-to-end testing scenarios for the approval workflow system. Each scenario includes detailed curl commands and expected responses for complete testing coverage.* diff --git a/plan/implementation-examples.md b/plan/implementation-examples.md new file mode 100644 index 0000000..4fc12ea --- /dev/null +++ b/plan/implementation-examples.md @@ -0,0 +1,1091 @@ +# Contoh Implementasi Kode - Sistem Approval Artikel Dinamis + +## 1. Database Entities + +### ApprovalWorkflows Entity +```go +// app/database/entity/approval_workflows.entity.go +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type ApprovalWorkflows struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + Name string `json:"name" gorm:"type:varchar;not null"` + Description *string `json:"description" gorm:"type:text"` + IsActive *bool `json:"is_active" gorm:"type:bool;default:true"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Steps []ApprovalWorkflowSteps `json:"steps" gorm:"foreignKey:WorkflowId;references:ID"` +} +``` + +### ApprovalWorkflowSteps Entity +```go +// app/database/entity/approval_workflow_steps.entity.go +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type ApprovalWorkflowSteps struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + WorkflowId uint `json:"workflow_id" gorm:"type:int4;not null"` + StepOrder int `json:"step_order" gorm:"type:int4;not null"` + UserLevelId uint `json:"user_level_id" gorm:"type:int4;not null"` + IsRequired *bool `json:"is_required" gorm:"type:bool;default:true"` + CanSkip *bool `json:"can_skip" gorm:"type:bool;default:false"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Workflow *ApprovalWorkflows `json:"workflow" gorm:"foreignKey:WorkflowId;references:ID"` + UserLevel *UserLevels `json:"user_level" gorm:"foreignKey:UserLevelId;references:ID"` +} +``` + +### ArticleApprovalFlows Entity +```go +// app/database/entity/article_approval_flows.entity.go +package entity + +import ( + "github.com/google/uuid" + "time" +) + +type ArticleApprovalFlows struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + ArticleId uint `json:"article_id" gorm:"type:int4;not null"` + WorkflowId uint `json:"workflow_id" gorm:"type:int4;not null"` + CurrentStep int `json:"current_step" gorm:"type:int4;default:1"` + StatusId int `json:"status_id" gorm:"type:int4;default:1"` // 1=In Progress, 2=Completed, 3=Rejected + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` + + // Relations + Article *Articles `json:"article" gorm:"foreignKey:ArticleId;references:ID"` + Workflow *ApprovalWorkflows `json:"workflow" gorm:"foreignKey:WorkflowId;references:ID"` + StepLogs []ArticleApprovalStepLogs `json:"step_logs" gorm:"foreignKey:ArticleFlowId;references:ID"` +} +``` + +### ArticleApprovalStepLogs Entity +```go +// app/database/entity/article_approval_step_logs.entity.go +package entity + +import ( + "github.com/google/uuid" + "time" + users "web-medols-be/app/database/entity/users" +) + +type ArticleApprovalStepLogs struct { + ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"` + ArticleFlowId uint `json:"article_flow_id" gorm:"type:int4;not null"` + StepOrder int `json:"step_order" gorm:"type:int4;not null"` + UserLevelId uint `json:"user_level_id" gorm:"type:int4;not null"` + ApprovedBy uint `json:"approved_by" gorm:"type:int4;not null"` + Action string `json:"action" gorm:"type:varchar(50);not null"` // 'approved', 'rejected', 'revision_requested' + Message *string `json:"message" gorm:"type:text"` + ApprovedAt *time.Time `json:"approved_at" gorm:"type:timestamp"` + ClientId *uuid.UUID `json:"client_id" gorm:"type:UUID"` + CreatedAt time.Time `json:"created_at" gorm:"default:now()"` + + // Relations + ArticleFlow *ArticleApprovalFlows `json:"article_flow" gorm:"foreignKey:ArticleFlowId;references:ID"` + UserLevel *UserLevels `json:"user_level" gorm:"foreignKey:UserLevelId;references:ID"` + Approver *users.Users `json:"approver" gorm:"foreignKey:ApprovedBy;references:ID"` +} +``` + +## 2. Service Layer Implementation + +### ApprovalWorkflowService +```go +// app/module/approval_workflows/service/approval_workflows.service.go +package service + +import ( + "errors" + "github.com/google/uuid" + "github.com/rs/zerolog" + "web-medols-be/app/database/entity" + "web-medols-be/app/module/approval_workflows/repository" + "web-medols-be/app/module/approval_workflows/request" + "web-medols-be/app/module/approval_workflows/response" + "web-medols-be/utils/paginator" +) + +type approvalWorkflowService struct { + Repo repository.ApprovalWorkflowRepository + Log zerolog.Logger +} + +type ApprovalWorkflowService interface { + All(clientId *uuid.UUID, req request.ApprovalWorkflowQueryRequest) ([]*response.ApprovalWorkflowResponse, paginator.Pagination, error) + Show(clientId *uuid.UUID, id uint) (*response.ApprovalWorkflowResponse, error) + Save(clientId *uuid.UUID, req request.ApprovalWorkflowCreateRequest) (*entity.ApprovalWorkflows, error) + Update(clientId *uuid.UUID, id uint, req request.ApprovalWorkflowUpdateRequest) error + Delete(clientId *uuid.UUID, id uint) error + GetActiveWorkflow(clientId *uuid.UUID) (*entity.ApprovalWorkflows, error) + ValidateWorkflow(workflowId uint) error +} + +func NewApprovalWorkflowService(repo repository.ApprovalWorkflowRepository, log zerolog.Logger) ApprovalWorkflowService { + return &approvalWorkflowService{ + Repo: repo, + Log: log, + } +} + +func (s *approvalWorkflowService) Save(clientId *uuid.UUID, req request.ApprovalWorkflowCreateRequest) (*entity.ApprovalWorkflows, error) { + // Validate workflow steps + if len(req.Steps) == 0 { + return nil, errors.New("workflow must have at least one step") + } + + // Validate step order sequence + for i, step := range req.Steps { + if step.StepOrder != i+1 { + return nil, errors.New("step order must be sequential starting from 1") + } + } + + workflow := req.ToEntity() + workflow.ClientId = clientId + + return s.Repo.Create(workflow) +} + +func (s *approvalWorkflowService) ValidateWorkflow(workflowId uint) error { + workflow, err := s.Repo.FindOneWithSteps(workflowId) + if err != nil { + return err + } + + if workflow.IsActive == nil || !*workflow.IsActive { + return errors.New("workflow is not active") + } + + if len(workflow.Steps) == 0 { + return errors.New("workflow has no steps defined") + } + + return nil +} +``` + +### Dynamic Article Approval Service +```go +// app/module/article_approval_flows/service/article_approval_flows.service.go +package service + +import ( + "errors" + "fmt" + "github.com/google/uuid" + "github.com/rs/zerolog" + "time" + "web-medols-be/app/database/entity" + users "web-medols-be/app/database/entity/users" + "web-medols-be/app/module/article_approval_flows/repository" + "web-medols-be/app/module/articles/repository" as articlesRepo + "web-medols-be/app/module/approval_workflows/service" as workflowService +) + +type articleApprovalFlowService struct { + Repo repository.ArticleApprovalFlowRepository + ArticlesRepo articlesRepo.ArticlesRepository + WorkflowService workflowService.ApprovalWorkflowService + Log zerolog.Logger +} + +type ArticleApprovalFlowService interface { + InitiateApprovalFlow(clientId *uuid.UUID, articleId uint, workflowId uint) (*entity.ArticleApprovalFlows, error) + ProcessApprovalStep(clientId *uuid.UUID, articleId uint, action string, message *string, approver *users.Users) error + GetPendingApprovals(clientId *uuid.UUID, userLevelId uint, filters ApprovalFilters) ([]*entity.ArticleApprovalFlows, paginator.Pagination, error) + GetMyApprovalQueue(clientId *uuid.UUID, userLevelId uint, filters ApprovalFilters) ([]*DetailedApprovalFlow, paginator.Pagination, error) + GetApprovalHistory(clientId *uuid.UUID, articleId uint) ([]*entity.ArticleApprovalStepLogs, error) + GetApprovalStatistics(clientId *uuid.UUID, userLevelId uint) (*ApprovalStatistics, error) + GetWorkloadDistribution(clientId *uuid.UUID, userLevelId uint) (*WorkloadDistribution, error) + BulkApprovalAction(clientId *uuid.UUID, articleIds []uint, action string, message *string, approver *users.Users) (*BulkActionResult, error) +} + +// Supporting structs for enhanced approver dashboard +type ApprovalFilters struct { + Page int + Limit int + Priority *string + CategoryId *uint + Search *string + DateFrom *time.Time + DateTo *time.Time + SortBy string + SortOrder string + WorkflowId *uint + UrgencyOnly bool + IncludePreview bool +} + +type DetailedApprovalFlow struct { + ID uint `json:"id"` + Article DetailedArticleInfo `json:"article"` + ApprovalContext ApprovalContext `json:"approval_context"` + WorkflowProgress WorkflowProgress `json:"workflow_progress"` +} + +type DetailedArticleInfo struct { + ID uint `json:"id"` + Title string `json:"title"` + ContentPreview *string `json:"content_preview"` + FullContentAvailable bool `json:"full_content_available"` + Author AuthorInfo `json:"author"` + Category CategoryInfo `json:"category"` + SubmissionNotes *string `json:"submission_notes"` + Tags []string `json:"tags"` + WordCount int `json:"word_count"` + EstimatedReadTime string `json:"estimated_read_time"` + SEOScore int `json:"seo_score"` + ReadabilityScore string `json:"readability_score"` + CreatedAt time.Time `json:"created_at"` + SubmittedAt time.Time `json:"submitted_at"` +} + +type AuthorInfo struct { + ID uint `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + ProfilePicture *string `json:"profile_picture"` + ReputationScore float64 `json:"reputation_score"` + ArticlesPublished int `json:"articles_published"` + ApprovalSuccessRate float64 `json:"approval_success_rate"` +} + +type CategoryInfo struct { + ID uint `json:"id"` + Name string `json:"name"` + Color string `json:"color"` +} + +type ApprovalContext struct { + MyRoleInWorkflow string `json:"my_role_in_workflow"` + StepDescription string `json:"step_description"` + ExpectedAction string `json:"expected_action"` + Deadline *time.Time `json:"deadline"` + IsOverdue bool `json:"is_overdue"` + EscalationAvailable bool `json:"escalation_available"` +} + +type WorkflowProgress struct { + CompletedSteps int `json:"completed_steps"` + TotalSteps int `json:"total_steps"` + ProgressPercentage float64 `json:"progress_percentage"` + NextApprover string `json:"next_approver"` +} + +type ApprovalStatistics struct { + PendingCount int `json:"pending_count"` + OverdueCount int `json:"overdue_count"` + ApprovedToday int `json:"approved_today"` + ApprovedThisWeek int `json:"approved_this_week"` + ApprovedThisMonth int `json:"approved_this_month"` + RejectedThisMonth int `json:"rejected_this_month"` + RevisionRequestsThisMonth int `json:"revision_requests_this_month"` + AverageApprovalTimeHours float64 `json:"average_approval_time_hours"` + FastestApprovalMinutes int `json:"fastest_approval_minutes"` + SlowestApprovalHours int `json:"slowest_approval_hours"` + ApprovalRatePercentage float64 `json:"approval_rate_percentage"` + CategoriesBreakdown []CategoryBreakdown `json:"categories_breakdown"` +} + +type CategoryBreakdown struct { + CategoryName string `json:"category_name"` + Pending int `json:"pending"` + ApprovedThisMonth int `json:"approved_this_month"` +} + +type WorkloadDistribution struct { + MyLevel LevelWorkload `json:"my_level"` + TeamComparison []TeamMember `json:"team_comparison"` + Bottlenecks []BottleneckInfo `json:"bottlenecks"` +} + +type LevelWorkload struct { + LevelName string `json:"level_name"` + LevelNumber int `json:"level_number"` + PendingArticles int `json:"pending_articles"` + AvgDailyApprovals float64 `json:"avg_daily_approvals"` +} + +type TeamMember struct { + ApproverName string `json:"approver_name"` + LevelName string `json:"level_name"` + PendingArticles int `json:"pending_articles"` + AvgResponseTimeHours float64 `json:"avg_response_time_hours"` +} + +type BottleneckInfo struct { + LevelName string `json:"level_name"` + PendingCount int `json:"pending_count"` + AvgWaitingTimeHours float64 `json:"avg_waiting_time_hours"` + IsBottleneck bool `json:"is_bottleneck"` +} + +type BulkActionResult struct { + ProcessedCount int `json:"processed_count"` + SuccessfulCount int `json:"successful_count"` + FailedCount int `json:"failed_count"` + Results []BulkActionItemResult `json:"results"` +} + +type BulkActionItemResult struct { + ArticleId uint `json:"article_id"` + Status string `json:"status"` + NextStep string `json:"next_step"` + Error *string `json:"error,omitempty"` +} + +func NewArticleApprovalFlowService( + repo repository.ArticleApprovalFlowRepository, + articlesRepo articlesRepo.ArticlesRepository, + workflowService workflowService.ApprovalWorkflowService, + log zerolog.Logger, +) ArticleApprovalFlowService { + return &articleApprovalFlowService{ + Repo: repo, + ArticlesRepo: articlesRepo, + WorkflowService: workflowService, + Log: log, + } +} + +func (s *articleApprovalFlowService) InitiateApprovalFlow(clientId *uuid.UUID, articleId uint, workflowId uint) (*entity.ArticleApprovalFlows, error) { + // Validate workflow + err := s.WorkflowService.ValidateWorkflow(workflowId) + if err != nil { + return nil, fmt.Errorf("invalid workflow: %v", err) + } + + // Check if article already has active approval flow + existingFlow, _ := s.Repo.FindActiveByArticleId(articleId) + if existingFlow != nil { + return nil, errors.New("article already has active approval flow") + } + + // Create new approval flow + approvalFlow := &entity.ArticleApprovalFlows{ + ArticleId: articleId, + WorkflowId: workflowId, + CurrentStep: 1, + StatusId: 1, // In Progress + ClientId: clientId, + } + + // Update article status + statusId := 1 // Pending approval + err = s.ArticlesRepo.UpdateSkipNull(clientId, articleId, &entity.Articles{ + StatusId: &statusId, + WorkflowId: &workflowId, + CurrentApprovalStep: &[]int{1}[0], + }) + if err != nil { + return nil, fmt.Errorf("failed to update article status: %v", err) + } + + return s.Repo.Create(approvalFlow) +} + +func (s *articleApprovalFlowService) ProcessApprovalStep(clientId *uuid.UUID, articleId uint, action string, message *string, approver *users.Users) error { + // Get active approval flow + approvalFlow, err := s.Repo.FindActiveByArticleId(articleId) + if err != nil { + return fmt.Errorf("approval flow not found: %v", err) + } + + // Get workflow with steps + workflow, err := s.WorkflowService.GetWorkflowWithSteps(approvalFlow.WorkflowId) + if err != nil { + return fmt.Errorf("workflow not found: %v", err) + } + + // Find current step + var currentStep *entity.ApprovalWorkflowSteps + for _, step := range workflow.Steps { + if step.StepOrder == approvalFlow.CurrentStep { + currentStep = &step + break + } + } + + if currentStep == nil { + return errors.New("current step not found in workflow") + } + + // Validate approver has permission for this step + if approver.UserLevelId != currentStep.UserLevelId { + return errors.New("approver does not have permission for this approval step") + } + + // Create step log + now := time.Now() + stepLog := &entity.ArticleApprovalStepLogs{ + ArticleFlowId: approvalFlow.ID, + StepOrder: approvalFlow.CurrentStep, + UserLevelId: currentStep.UserLevelId, + ApprovedBy: approver.ID, + Action: action, + Message: message, + ApprovedAt: &now, + ClientId: clientId, + } + + err = s.Repo.CreateStepLog(stepLog) + if err != nil { + return fmt.Errorf("failed to create step log: %v", err) + } + + // Process action + switch action { + case "approved": + return s.processApproval(clientId, approvalFlow, workflow) + case "rejected": + return s.processRejection(clientId, approvalFlow) + case "revision_requested": + return s.processRevisionRequest(clientId, approvalFlow) + default: + return errors.New("invalid action") + } +} + +func (s *articleApprovalFlowService) processApproval(clientId *uuid.UUID, approvalFlow *entity.ArticleApprovalFlows, workflow *entity.ApprovalWorkflows) error { + // Check if this is the last step + maxStep := 0 + for _, step := range workflow.Steps { + if step.StepOrder > maxStep { + maxStep = step.StepOrder + } + } + + if approvalFlow.CurrentStep >= maxStep { + // Final approval - publish article + return s.finalizeApproval(clientId, approvalFlow) + } else { + // Move to next step + return s.moveToNextStep(clientId, approvalFlow) + } +} + +func (s *articleApprovalFlowService) finalizeApproval(clientId *uuid.UUID, approvalFlow *entity.ArticleApprovalFlows) error { + // Update approval flow status + approvalFlow.StatusId = 2 // Completed + err := s.Repo.Update(approvalFlow.ID, approvalFlow) + if err != nil { + return err + } + + // Update article status to published + isPublish := true + statusId := 2 // Published + now := time.Now() + + err = s.ArticlesRepo.UpdateSkipNull(clientId, approvalFlow.ArticleId, &entity.Articles{ + StatusId: &statusId, + IsPublish: &isPublish, + PublishedAt: &now, + CurrentApprovalStep: nil, // Clear approval step + }) + + return err +} + +func (s *articleApprovalFlowService) moveToNextStep(clientId *uuid.UUID, approvalFlow *entity.ArticleApprovalFlows) error { + // Move to next step + approvalFlow.CurrentStep++ + err := s.Repo.Update(approvalFlow.ID, approvalFlow) + if err != nil { + return err + } + + // Update article current step + err = s.ArticlesRepo.UpdateSkipNull(clientId, approvalFlow.ArticleId, &entity.Articles{ + CurrentApprovalStep: &approvalFlow.CurrentStep, + }) + + return err +} + +func (s *articleApprovalFlowService) processRejection(clientId *uuid.UUID, approvalFlow *entity.ArticleApprovalFlows) error { + // Update approval flow status + approvalFlow.StatusId = 3 // Rejected + err := s.Repo.Update(approvalFlow.ID, approvalFlow) + if err != nil { + return err + } + + // Update article status + statusId := 3 // Rejected + err = s.ArticlesRepo.UpdateSkipNull(clientId, approvalFlow.ArticleId, &entity.Articles{ + StatusId: &statusId, + CurrentApprovalStep: nil, + }) + + return err +} + +func (s *articleApprovalFlowService) processRevisionRequest(clientId *uuid.UUID, approvalFlow *entity.ArticleApprovalFlows) error { + // Reset approval flow to step 0 (back to contributor) + approvalFlow.CurrentStep = 0 + approvalFlow.StatusId = 4 // Revision Requested + err := s.Repo.Update(approvalFlow.ID, approvalFlow) + if err != nil { + return err + } + + // Update article status + statusId := 4 // Revision Requested + err = s.ArticlesRepo.UpdateSkipNull(clientId, approvalFlow.ArticleId, &entity.Articles{ + StatusId: &statusId, + CurrentApprovalStep: &[]int{0}[0], + }) + + return err +} + +// Enhanced methods for approver dashboard +func (s *articleApprovalFlowService) GetMyApprovalQueue(clientId *uuid.UUID, userLevelId uint, filters ApprovalFilters) ([]*DetailedApprovalFlow, paginator.Pagination, error) { + // Build query with filters + query := s.Repo.BuildApprovalQueueQuery(clientId, userLevelId, filters) + + // Get paginated results + approvalFlows, pagination, err := s.Repo.GetPaginatedApprovalQueue(query, filters.Page, filters.Limit) + if err != nil { + return nil, paginator.Pagination{}, err + } + + // Transform to detailed approval flows + detailedFlows := make([]*DetailedApprovalFlow, 0, len(approvalFlows)) + for _, flow := range approvalFlows { + detailedFlow, err := s.transformToDetailedFlow(flow, filters.IncludePreview) + if err != nil { + s.Log.Error().Err(err).Uint("flow_id", flow.ID).Msg("Failed to transform approval flow") + continue + } + detailedFlows = append(detailedFlows, detailedFlow) + } + + return detailedFlows, pagination, nil +} + +func (s *articleApprovalFlowService) GetApprovalStatistics(clientId *uuid.UUID, userLevelId uint) (*ApprovalStatistics, error) { + stats := &ApprovalStatistics{} + + // Get pending count + pendingCount, err := s.Repo.GetPendingCountByLevel(clientId, userLevelId) + if err != nil { + return nil, err + } + stats.PendingCount = pendingCount + + // Get overdue count + overdueCount, err := s.Repo.GetOverdueCountByLevel(clientId, userLevelId) + if err != nil { + return nil, err + } + stats.OverdueCount = overdueCount + + // Get approval counts by time period + now := time.Now() + startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) + startOfWeek := startOfDay.AddDate(0, 0, -int(now.Weekday())) + startOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()) + + stats.ApprovedToday, _ = s.Repo.GetApprovedCountByPeriod(clientId, userLevelId, startOfDay, now) + stats.ApprovedThisWeek, _ = s.Repo.GetApprovedCountByPeriod(clientId, userLevelId, startOfWeek, now) + stats.ApprovedThisMonth, _ = s.Repo.GetApprovedCountByPeriod(clientId, userLevelId, startOfMonth, now) + stats.RejectedThisMonth, _ = s.Repo.GetRejectedCountByPeriod(clientId, userLevelId, startOfMonth, now) + stats.RevisionRequestsThisMonth, _ = s.Repo.GetRevisionRequestCountByPeriod(clientId, userLevelId, startOfMonth, now) + + // Get timing statistics + timingStats, err := s.Repo.GetApprovalTimingStats(clientId, userLevelId) + if err == nil { + stats.AverageApprovalTimeHours = timingStats.AverageHours + stats.FastestApprovalMinutes = timingStats.FastestMinutes + stats.SlowestApprovalHours = timingStats.SlowestHours + } + + // Calculate approval rate + totalProcessed := stats.ApprovedThisMonth + stats.RejectedThisMonth + if totalProcessed > 0 { + stats.ApprovalRatePercentage = float64(stats.ApprovedThisMonth) / float64(totalProcessed) * 100 + } + + // Get categories breakdown + categoriesBreakdown, err := s.Repo.GetCategoriesBreakdown(clientId, userLevelId) + if err == nil { + stats.CategoriesBreakdown = categoriesBreakdown + } + + return stats, nil +} + +func (s *articleApprovalFlowService) GetWorkloadDistribution(clientId *uuid.UUID, userLevelId uint) (*WorkloadDistribution, error) { + distribution := &WorkloadDistribution{} + + // Get my level workload + myLevel, err := s.Repo.GetLevelWorkload(clientId, userLevelId) + if err != nil { + return nil, err + } + distribution.MyLevel = *myLevel + + // Get team comparison (same level users) + teamMembers, err := s.Repo.GetTeamWorkloadComparison(clientId, userLevelId) + if err == nil { + distribution.TeamComparison = teamMembers + } + + // Identify bottlenecks + bottlenecks, err := s.Repo.GetWorkflowBottlenecks(clientId) + if err == nil { + distribution.Bottlenecks = bottlenecks + } + + return distribution, nil +} + +func (s *articleApprovalFlowService) BulkApprovalAction(clientId *uuid.UUID, articleIds []uint, action string, message *string, approver *users.Users) (*BulkActionResult, error) { + result := &BulkActionResult{ + ProcessedCount: len(articleIds), + Results: make([]BulkActionItemResult, 0, len(articleIds)), + } + + for _, articleId := range articleIds { + itemResult := BulkActionItemResult{ + ArticleId: articleId, + } + + err := s.ProcessApprovalStep(clientId, articleId, action, message, approver) + if err != nil { + itemResult.Status = "failed" + errorMsg := err.Error() + itemResult.Error = &errorMsg + result.FailedCount++ + } else { + itemResult.Status = "success" + + // Get next step info + approvalFlow, err := s.Repo.FindActiveByArticleId(articleId) + if err == nil { + if approvalFlow.StatusId == 2 { + itemResult.NextStep = "published" + } else { + itemResult.NextStep = fmt.Sprintf("%d", approvalFlow.CurrentStep) + } + } + + result.SuccessfulCount++ + } + + result.Results = append(result.Results, itemResult) + } + + return result, nil +} + +func (s *articleApprovalFlowService) transformToDetailedFlow(flow *entity.ArticleApprovalFlows, includePreview bool) (*DetailedApprovalFlow, error) { + // This method would transform the basic approval flow to detailed view + // Implementation would include: + // 1. Fetch article details with author info + // 2. Calculate approval context (deadlines, role description) + // 3. Build workflow progress information + // 4. Add content preview if requested + + detailedFlow := &DetailedApprovalFlow{ + ID: flow.ID, + // Article details would be populated from database joins + // ApprovalContext would be calculated based on workflow step + // WorkflowProgress would show current position in workflow + } + + return detailedFlow, nil +} +``` + +## 3. Controller Implementation + +### Article Approval Controller +```go +// app/module/articles/controller/articles_approval.controller.go +package controller + +import ( + "github.com/gofiber/fiber/v2" + "github.com/rs/zerolog" + "strconv" + "web-medols-be/app/middleware" + "web-medols-be/app/module/article_approval_flows/service" + "web-medols-be/app/module/articles/request" + usersRepository "web-medols-be/app/module/users/repository" + utilRes "web-medols-be/utils/response" + utilSvc "web-medols-be/utils/service" + utilVal "web-medols-be/utils/validator" +) + +type articleApprovalController struct { + approvalFlowService service.ArticleApprovalFlowService + usersRepo usersRepository.UsersRepository + log zerolog.Logger +} + +type ArticleApprovalController interface { + SubmitForApproval(c *fiber.Ctx) error + ApproveStep(c *fiber.Ctx) error + RejectArticle(c *fiber.Ctx) error + RequestRevision(c *fiber.Ctx) error + GetPendingApprovals(c *fiber.Ctx) error + GetApprovalHistory(c *fiber.Ctx) error +} + +func NewArticleApprovalController( + approvalFlowService service.ArticleApprovalFlowService, + usersRepo usersRepository.UsersRepository, + log zerolog.Logger, +) ArticleApprovalController { + return &articleApprovalController{ + approvalFlowService: approvalFlowService, + usersRepo: usersRepo, + log: log, + } +} + +// SubmitForApproval submit article for approval +// @Summary Submit article for approval +// @Description API for submitting article for approval workflow +// @Tags Articles +// @Security Bearer +// @Param id path int true "Article ID" +// @Param payload body request.SubmitApprovalRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /articles/{id}/submit-approval [post] +func (ctrl *articleApprovalController) SubmitForApproval(c *fiber.Ctx) error { + clientId := middleware.GetClientId(c) + + id, err := strconv.ParseUint(c.Params("id"), 10, 0) + if err != nil { + return err + } + + req := new(request.SubmitApprovalRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + approvalFlow, err := ctrl.approvalFlowService.InitiateApprovalFlow(clientId, uint(id), req.WorkflowId) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Article submitted for approval successfully"}, + Data: approvalFlow, + }) +} + +// ApproveStep approve current approval step +// @Summary Approve article step +// @Description API for approving current approval step +// @Tags Articles +// @Security Bearer +// @Param id path int true "Article ID" +// @Param payload body request.ApprovalActionRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /articles/{id}/approve [post] +func (ctrl *articleApprovalController) ApproveStep(c *fiber.Ctx) error { + clientId := middleware.GetClientId(c) + authToken := c.Get("Authorization") + + id, err := strconv.ParseUint(c.Params("id"), 10, 0) + if err != nil { + return err + } + + req := new(request.ApprovalActionRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get current user info + approver := utilSvc.GetUserInfo(ctrl.log, ctrl.usersRepo, authToken) + + err = ctrl.approvalFlowService.ProcessApprovalStep(clientId, uint(id), "approved", req.Message, approver) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Article approved successfully"}, + }) +} + +// RequestRevision request revision for article +// @Summary Request article revision +// @Description API for requesting article revision +// @Tags Articles +// @Security Bearer +// @Param id path int true "Article ID" +// @Param payload body request.ApprovalActionRequest true "Required payload" +// @Success 200 {object} response.Response +// @Failure 400 {object} response.BadRequestError +// @Failure 401 {object} response.UnauthorizedError +// @Failure 500 {object} response.InternalServerError +// @Router /articles/{id}/request-revision [post] +func (ctrl *articleApprovalController) RequestRevision(c *fiber.Ctx) error { + clientId := middleware.GetClientId(c) + authToken := c.Get("Authorization") + + id, err := strconv.ParseUint(c.Params("id"), 10, 0) + if err != nil { + return err + } + + req := new(request.ApprovalActionRequest) + if err := utilVal.ParseAndValidate(c, req); err != nil { + return err + } + + // Get current user info + approver := utilSvc.GetUserInfo(ctrl.log, ctrl.usersRepo, authToken) + + err = ctrl.approvalFlowService.ProcessApprovalStep(clientId, uint(id), "revision_requested", req.Message, approver) + if err != nil { + return err + } + + return utilRes.Resp(c, utilRes.Response{ + Success: true, + Messages: utilRes.Messages{"Revision requested successfully"}, + }) +} +``` + +## 4. Request/Response Models + +### Request Models +```go +// app/module/articles/request/approval.request.go +package request + +type SubmitApprovalRequest struct { + WorkflowId uint `json:"workflowId" validate:"required"` +} + +type ApprovalActionRequest struct { + Message *string `json:"message"` +} + +// app/module/approval_workflows/request/approval_workflows.request.go +package request + +import "web-medols-be/app/database/entity" + +type ApprovalWorkflowCreateRequest struct { + Name string `json:"name" validate:"required"` + Description *string `json:"description"` + Steps []ApprovalWorkflowStepRequest `json:"steps" validate:"required,min=1"` +} + +type ApprovalWorkflowStepRequest struct { + StepOrder int `json:"stepOrder" validate:"required,min=1"` + UserLevelId uint `json:"userLevelId" validate:"required"` + IsRequired bool `json:"isRequired"` + CanSkip bool `json:"canSkip"` +} + +func (req ApprovalWorkflowCreateRequest) ToEntity() *entity.ApprovalWorkflows { + workflow := &entity.ApprovalWorkflows{ + Name: req.Name, + Description: req.Description, + IsActive: &[]bool{true}[0], + } + + for _, stepReq := range req.Steps { + step := entity.ApprovalWorkflowSteps{ + StepOrder: stepReq.StepOrder, + UserLevelId: stepReq.UserLevelId, + IsRequired: &stepReq.IsRequired, + CanSkip: &stepReq.CanSkip, + } + workflow.Steps = append(workflow.Steps, step) + } + + return workflow +} +``` + +## 5. Migration Scripts + +### Database Migration +```sql +-- migrations/001_create_approval_system_tables.sql + +-- Create approval_workflows table +CREATE TABLE approval_workflows ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + description TEXT, + is_active BOOLEAN DEFAULT true, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); + +-- Create approval_workflow_steps table +CREATE TABLE approval_workflow_steps ( + id SERIAL PRIMARY KEY, + workflow_id INT NOT NULL REFERENCES approval_workflows(id) ON DELETE CASCADE, + step_order INT NOT NULL, + user_level_id INT NOT NULL REFERENCES user_levels(id), + is_required BOOLEAN DEFAULT true, + can_skip BOOLEAN DEFAULT false, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW(), + UNIQUE(workflow_id, step_order) +); + +-- Create article_approval_flows table +CREATE TABLE article_approval_flows ( + id SERIAL PRIMARY KEY, + article_id INT NOT NULL REFERENCES articles(id) ON DELETE CASCADE, + workflow_id INT NOT NULL REFERENCES approval_workflows(id), + current_step INT DEFAULT 1, + status_id INT DEFAULT 1, -- 1=In Progress, 2=Completed, 3=Rejected, 4=Revision Requested + client_id UUID, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); + +-- Create article_approval_step_logs table +CREATE TABLE article_approval_step_logs ( + id SERIAL PRIMARY KEY, + article_flow_id INT NOT NULL REFERENCES article_approval_flows(id) ON DELETE CASCADE, + step_order INT NOT NULL, + user_level_id INT NOT NULL REFERENCES user_levels(id), + approved_by INT NOT NULL REFERENCES users(id), + action VARCHAR(50) NOT NULL CHECK (action IN ('approved', 'rejected', 'revision_requested')), + message TEXT, + approved_at TIMESTAMP, + client_id UUID, + created_at TIMESTAMP DEFAULT NOW() +); + +-- Add indexes for performance +CREATE INDEX idx_approval_workflows_client_id ON approval_workflows(client_id); +CREATE INDEX idx_approval_workflows_is_active ON approval_workflows(is_active); +CREATE INDEX idx_approval_workflow_steps_workflow_id ON approval_workflow_steps(workflow_id); +CREATE INDEX idx_article_approval_flows_article_id ON article_approval_flows(article_id); +CREATE INDEX idx_article_approval_flows_status_id ON article_approval_flows(status_id); +CREATE INDEX idx_article_approval_step_logs_article_flow_id ON article_approval_step_logs(article_flow_id); +CREATE INDEX idx_article_approval_step_logs_approved_by ON article_approval_step_logs(approved_by); + +-- Modify articles table +ALTER TABLE articles ADD COLUMN workflow_id INT REFERENCES approval_workflows(id); +ALTER TABLE articles ADD COLUMN current_approval_step INT DEFAULT 0; + +-- Create default workflow for backward compatibility +INSERT INTO approval_workflows (name, description, is_active) +VALUES ('Legacy 3-Level Approval', 'Default 3-level approval system for backward compatibility', true); + +-- Get the workflow ID (assuming it's 1 for the first insert) +INSERT INTO approval_workflow_steps (workflow_id, step_order, user_level_id, is_required, can_skip) +VALUES +(1, 1, 3, true, false), -- Level 3 approver (first step) +(1, 2, 2, true, false), -- Level 2 approver (second step) +(1, 3, 1, true, false); -- Level 1 approver (final step) + +-- Update existing articles to use default workflow +UPDATE articles SET workflow_id = 1 WHERE workflow_id IS NULL; +``` + +## 6. Usage Examples + +### Creating a Custom Workflow +```bash +# Create a 2-level approval workflow +curl -X POST http://localhost:8800/api/approval-workflows \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "name": "Simple 2-Level Approval", + "description": "Quick approval for simple articles", + "steps": [ + { + "stepOrder": 1, + "userLevelId": 2, + "isRequired": true, + "canSkip": false + }, + { + "stepOrder": 2, + "userLevelId": 1, + "isRequired": true, + "canSkip": false + } + ] + }' +``` + +### Submitting Article for Approval +```bash +# Submit article ID 123 for approval using workflow ID 2 +curl -X POST http://localhost:8800/api/articles/123/submit-approval \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "workflowId": 2 + }' +``` + +### Approving an Article +```bash +# Approve article ID 123 +curl -X POST http://localhost:8800/api/articles/123/approve \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "message": "Article looks good, approved for next level" + }' +``` + +### Requesting Revision +```bash +# Request revision for article ID 123 +curl -X POST http://localhost:8800/api/articles/123/request-revision \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{ + "message": "Please fix the grammar issues in paragraph 2" + }' +``` + +Dengan implementasi ini, sistem approval artikel menjadi sangat fleksibel dan dapat disesuaikan dengan kebutuhan organisasi yang berbeda-beda. Workflow dapat dibuat, dimodifikasi, dan dinonaktifkan tanpa mengubah kode aplikasi. \ No newline at end of file diff --git a/utils/response/index.response.go b/utils/response/index.response.go index 2a194e3..4e09194 100644 --- a/utils/response/index.response.go +++ b/utils/response/index.response.go @@ -101,3 +101,12 @@ func Unauthorized() *Response { }, } } + +func ErrorBadRequest(c *fiber.Ctx, message string) error { + return c.Status(fiber.StatusBadRequest).JSON(Response{ + Success: false, + Code: 400, + Messages: Messages{message}, + }) +} +