fix: update clients list articles

This commit is contained in:
hanif salafi 2025-10-12 19:04:52 +07:00
parent 7220375a69
commit 1e641bc3e6
13 changed files with 453 additions and 0 deletions

View File

@ -77,6 +77,7 @@ func (_i *articlesController) All(c *fiber.Ctx) error {
IsPublish: c.Query("isPublish"),
IsDraft: c.Query("isDraft"),
IsBanner: c.Query("isBanner"),
ClientSlug: c.Query("clientSlug"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate

View File

@ -24,6 +24,7 @@ type ArticlesQueryRequest struct {
IsBanner *bool `json:"isBanner"`
IsPublish *bool `json:"isPublish"`
IsDraft *bool `json:"isDraft"`
ClientSlug *string `json:"clientSlug"`
Pagination *paginator.Pagination `json:"pagination"`
}
@ -119,6 +120,7 @@ type ArticlesQueryRequestContext struct {
IsPublish string `json:"isPublish"`
IsDraft string `json:"isDraft"`
StatusId string `json:"statusId"`
ClientSlug string `json:"clientSlug"`
}
func (req ArticlesQueryRequestContext) ToParamRequest() ArticlesQueryRequest {
@ -179,6 +181,9 @@ func (req ArticlesQueryRequestContext) ToParamRequest() ArticlesQueryRequest {
request.CreatedById = &createdById
}
}
if clientSlug := req.ClientSlug; clientSlug != "" {
request.ClientSlug = &clientSlug
}
return request
}

View File

@ -152,6 +152,19 @@ func (_i *articlesService) All(authToken string, req request.ArticlesQueryReques
req.CategoryId = &findCategory.ID
}
// Handle clientSlug filter - find client by slug and set clientId
if req.ClientSlug != nil {
findClient, err := _i.ClientsRepo.FindBySlug(*req.ClientSlug)
if err != nil {
_i.Log.Error().Err(err).Str("clientSlug", *req.ClientSlug).Msg("Failed to find client by slug")
return nil, paging, err
}
if findClient != nil {
clientId = &findClient.ID
_i.Log.Info().Str("clientSlug", *req.ClientSlug).Str("clientId", findClient.ID.String()).Msg("Found client by slug")
}
}
results, paging, err := _i.Repo.GetAll(clientId, userLevelId, userId, req)
if err != nil {
return

View File

@ -49,6 +49,7 @@ func (_i *ClientsRouter) RegisterClientsRoutes() {
// define routes
_i.App.Route("/clients", func(router fiber.Router) {
router.Get("/", clientsController.All)
router.Get("/public", clientsController.PublicAll)
router.Get("/profile", clientsController.ShowWithAuth)
router.Get("/check-name/:name", clientsController.CheckClientNameExists)
router.Get("/:id", clientsController.Show)

View File

@ -20,6 +20,7 @@ type clientsController struct {
type ClientsController interface {
All(c *fiber.Ctx) error
PublicAll(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
ShowWithAuth(c *fiber.Ctx) error
CheckClientNameExists(c *fiber.Ctx) error
@ -113,6 +114,50 @@ func (_i *clientsController) All(c *fiber.Ctx) error {
})
}
// PublicAll get all Clients for public consumption
// @Summary Get all Clients (Public)
// @Description API for getting all Clients for public consumption without sensitive data
// @Tags Clients
// @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 500 {object} response.InternalServerError
// @Router /clients/public [get]
func (_i *clientsController) PublicAll(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.ClientsQueryRequestContext{
Name: c.Query("name"),
ClientType: c.Query("clientType"),
ParentClientId: c.Query("parentClientId"),
IncludeSubClients: c.Query("includeSubClients"),
OnlyParentClients: c.Query("onlyParentClients"),
OnlyStandalone: c.Query("onlyStandalone"),
IsActive: c.Query("isActive"),
CreatedById: c.Query("createdById"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
_i.Log.Info().Interface("req", req).Msg("Getting public clients list")
clientsData, paging, err := _i.clientsService.PublicAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Public clients list successfully retrieved"},
Data: clientsData,
Meta: paging,
})
}
// Show get one Clients
// @Summary Get one Clients
// @Description API for getting one Clients

View File

@ -30,3 +30,21 @@ func ClientsResponseMapper(clientsReq *entity.Clients) (clientsRes *res.ClientsR
}
return clientsRes
}
func PublicClientsResponseMapper(clientsReq *entity.Clients) (clientsRes *res.PublicClientsResponse) {
if clientsReq != nil {
clientsRes = &res.PublicClientsResponse{
Name: clientsReq.Name,
Slug: clientsReq.Slug,
Description: clientsReq.Description,
ClientType: clientsReq.ClientType,
LogoUrl: clientsReq.LogoUrl,
Address: clientsReq.Address,
PhoneNumber: clientsReq.PhoneNumber,
Website: clientsReq.Website,
IsActive: clientsReq.IsActive,
CreatedAt: clientsReq.CreatedAt,
}
}
return clientsRes
}

View File

@ -25,6 +25,7 @@ type ClientsRepository interface {
FindOne(id uuid.UUID) (clients *entity.Clients, err error)
FindOneByClientId(clientId *uuid.UUID) (clients *entity.Clients, err error)
FindByName(name string) (clients *entity.Clients, err error)
FindBySlug(slug string) (clients *entity.Clients, err error)
FindByImagePathName(name string) (clients *entity.Clients, err error)
Create(clients *entity.Clients) (clientsReturn *entity.Clients, err error)
Update(id uuid.UUID, clients *entity.Clients) (err error)
@ -160,6 +161,14 @@ func (_i *clientsRepository) FindByName(name string) (clients *entity.Clients, e
return clients, nil
}
func (_i *clientsRepository) FindBySlug(slug string) (clients *entity.Clients, err error) {
if err := _i.DB.DB.Where("slug = ?", slug).First(&clients).Error; err != nil {
return nil, err
}
return clients, nil
}
func (_i *clientsRepository) FindByImagePathName(name string) (clients *entity.Clients, err error) {
if err := _i.DB.DB.Where("logo_image_path like ?", "%"+name+"%").First(&clients).Error; err != nil {
return nil, err

View File

@ -10,6 +10,23 @@ import (
// RESPONSE STRUCTS - Updated for Multi-Client Hierarchy Support (camelCase)
// ========================================================================
// PublicClientsResponse for public consumption without sensitive data
type PublicClientsResponse struct {
Name string `json:"name"`
Slug string `json:"slug"`
Description *string `json:"description"`
ClientType string `json:"clientType"`
// Additional tenant information fields
LogoUrl *string `json:"logoUrl"` // Logo tenant URL
Address *string `json:"address"` // Alamat
PhoneNumber *string `json:"phoneNumber"` // Nomor telepon
Website *string `json:"website"` // Website resmi
IsActive *bool `json:"isActive"`
CreatedAt time.Time `json:"createdAt"`
}
// ClientResponse for single client with hierarchy info
type ClientsResponse struct {
ID uuid.UUID `json:"id"`

View File

@ -36,6 +36,7 @@ type clientsService struct {
// ClientsService define interface of IClientsService
type ClientsService interface {
All(authToken string, req request.ClientsQueryRequest) (clients []*response.ClientsResponse, paging paginator.Pagination, err error)
PublicAll(req request.ClientsQueryRequest) (clients []*response.PublicClientsResponse, paging paginator.Pagination, err error)
Show(id uuid.UUID) (clients *response.ClientsResponse, err error)
CheckClientNameExists(name string) (exists bool, err error)
ShowWithAuth(authToken string) (clients *response.ClientsResponse, err error)
@ -98,6 +99,26 @@ func (_i *clientsService) All(authToken string, req request.ClientsQueryRequest)
return
}
func (_i *clientsService) PublicAll(req request.ClientsQueryRequest) (clientss []*response.PublicClientsResponse, paging paginator.Pagination, err error) {
_i.Log.Info().Interface("data", req).Msg("Getting public clients list")
// Only return active clients for public consumption
isActive := true
req.IsActive = &isActive
results, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
for _, result := range results {
clientss = append(clientss, mapper.PublicClientsResponseMapper(result))
}
_i.Log.Info().Int("count", len(clientss)).Msg("Public clients retrieved successfully")
return
}
func (_i *clientsService) Show(id uuid.UUID) (clients *response.ClientsResponse, err error) {
result, err := _i.Repo.FindOne(id)
if err != nil {

View File

@ -7005,6 +7005,11 @@ const docTemplate = `{
"name": "categoryId",
"in": "query"
},
{
"type": "string",
"name": "clientSlug",
"in": "query"
},
{
"type": "integer",
"name": "createdById",
@ -9931,6 +9936,123 @@ const docTemplate = `{
}
}
},
"/clients/public": {
"get": {
"description": "API for getting all Clients for public consumption without sensitive data",
"tags": [
"Clients"
],
"summary": "Get all Clients (Public)",
"parameters": [
{
"enum": [
"parent_client",
"sub_client",
"standalone"
],
"type": "string",
"name": "clientType",
"in": "query"
},
{
"type": "boolean",
"description": "Include all descendants",
"name": "includeSubClients",
"in": "query"
},
{
"type": "boolean",
"description": "Status filter",
"name": "isActive",
"in": "query"
},
{
"type": "string",
"description": "Search filters",
"name": "name",
"in": "query"
},
{
"type": "boolean",
"description": "Only clients with children",
"name": "onlyParentClients",
"in": "query"
},
{
"type": "boolean",
"description": "Only standalone clients",
"name": "onlyStandalone",
"in": "query"
},
{
"type": "string",
"description": "Hierarchy filters",
"name": "parentClientId",
"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"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.InternalServerError"
}
}
}
}
},
"/clients/update": {
"put": {
"security": [

View File

@ -6994,6 +6994,11 @@
"name": "categoryId",
"in": "query"
},
{
"type": "string",
"name": "clientSlug",
"in": "query"
},
{
"type": "integer",
"name": "createdById",
@ -9920,6 +9925,123 @@
}
}
},
"/clients/public": {
"get": {
"description": "API for getting all Clients for public consumption without sensitive data",
"tags": [
"Clients"
],
"summary": "Get all Clients (Public)",
"parameters": [
{
"enum": [
"parent_client",
"sub_client",
"standalone"
],
"type": "string",
"name": "clientType",
"in": "query"
},
{
"type": "boolean",
"description": "Include all descendants",
"name": "includeSubClients",
"in": "query"
},
{
"type": "boolean",
"description": "Status filter",
"name": "isActive",
"in": "query"
},
{
"type": "string",
"description": "Search filters",
"name": "name",
"in": "query"
},
{
"type": "boolean",
"description": "Only clients with children",
"name": "onlyParentClients",
"in": "query"
},
{
"type": "boolean",
"description": "Only standalone clients",
"name": "onlyStandalone",
"in": "query"
},
{
"type": "string",
"description": "Hierarchy filters",
"name": "parentClientId",
"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"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/response.InternalServerError"
}
}
}
}
},
"/clients/update": {
"put": {
"security": [

View File

@ -6157,6 +6157,9 @@ paths:
- in: query
name: categoryId
type: integer
- in: query
name: clientSlug
type: string
- in: query
name: createdById
type: integer
@ -8362,6 +8365,82 @@ paths:
summary: Get Clients detail with auth token
tags:
- Clients
/clients/public:
get:
description: API for getting all Clients for public consumption without sensitive
data
parameters:
- enum:
- parent_client
- sub_client
- standalone
in: query
name: clientType
type: string
- description: Include all descendants
in: query
name: includeSubClients
type: boolean
- description: Status filter
in: query
name: isActive
type: boolean
- description: Search filters
in: query
name: name
type: string
- description: Only clients with children
in: query
name: onlyParentClients
type: boolean
- description: Only standalone clients
in: query
name: onlyStandalone
type: boolean
- description: Hierarchy filters
in: query
name: parentClientId
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'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/response.InternalServerError'
summary: Get all Clients (Public)
tags:
- Clients
/clients/update:
put:
description: API for update Clients using client ID from auth token

Binary file not shown.