kontenhumas-be/app/module/clients/controller/clients.controller.go

818 lines
26 KiB
Go

package controller
import (
"netidhub-saas-be/app/module/clients/request"
"netidhub-saas-be/app/module/clients/service"
"netidhub-saas-be/utils/paginator"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog"
utilRes "netidhub-saas-be/utils/response"
utilVal "netidhub-saas-be/utils/validator"
)
type clientsController struct {
clientsService service.ClientsService
Log zerolog.Logger
}
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
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
UpdateWithAuth(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
// New hierarchy endpoints
GetHierarchy(c *fiber.Ctx) error
GetSubClients(c *fiber.Ctx) error
CreateSubClient(c *fiber.Ctx) error
MoveClient(c *fiber.Ctx) error
GetClientStats(c *fiber.Ctx) error
BulkCreateSubClients(c *fiber.Ctx) error
// Client with user creation
CreateClientWithUser(c *fiber.Ctx) error
// Logo upload endpoints
UploadLogo(c *fiber.Ctx) error
DeleteLogo(c *fiber.Ctx) error
GetLogoURL(c *fiber.Ctx) error
ViewLogo(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 with hierarchy filtering
// @Tags Clients
// @Security Bearer
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param name query string false "Filter by client name"
// @Param clientType query string false "Filter by client type (parent_client, sub_client, standalone)"
// @Param parentClientId query string false "Filter by parent client ID"
// @Param includeSubClients query boolean false "Include all descendants"
// @Param onlyParentClients query boolean false "Only clients with children"
// @Param onlyStandalone query boolean false "Only standalone clients"
// @Param onlyRootClients query boolean false "Only root level clients"
// @Param isActive query boolean false "Filter by active status"
// @Param createdById query string false "Filter by creator ID"
// @Param page query int false "Page number"
// @Param limit query int false "Items per page"
// @Param sort query string false "Sort field"
// @Param sortBy query string false "Sort direction (asc, desc)"
// @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"),
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
// Get Authorization token from header
authToken := c.Get("Authorization")
_i.Log.Info().Str("authToken", authToken).Msg("")
clientsData, paging, err := _i.clientsService.All(authToken, 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,
})
}
// 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
// @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,
})
}
// ShowWithAuth get Clients detail using auth token
// @Summary Get Clients detail with auth token
// @Description API for getting Clients detail using client ID from auth token
// @Tags Clients
// @Security Bearer
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/profile [get]
func (_i *clientsController) ShowWithAuth(c *fiber.Ctx) error {
// Get Authorization token from header
authToken := c.Get("Authorization")
_i.Log.Info().Str("authToken", authToken).Msg("")
clientsData, err := _i.clientsService.ShowWithAuth(authToken)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client profile successfully retrieved"},
Data: clientsData,
})
}
// CheckClientNameExists check if client name exists
// @Summary Check if client name exists
// @Description API for checking if client name exists (returns only exist status)
// @Tags Clients
// @Param name path string true "Client name to check"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/check-name/{name} [get]
func (_i *clientsController) CheckClientNameExists(c *fiber.Ctx) error {
name := c.Params("name")
exists, err := _i.clientsService.CheckClientNameExists(name)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
message := "Client name is available"
if exists {
message = "Name has been used"
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{message},
Data: map[string]interface{}{
"name": name,
"exists": exists,
},
})
}
// 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 <Add access token here>)
// @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"},
})
}
// UpdateWithAuth update Clients using auth token
// @Summary update Clients with auth token
// @Description API for update Clients using client ID from auth token
// @Tags Clients
// @Security Bearer
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param payload body request.ClientsUpdateRequest 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/update [put]
func (_i *clientsController) UpdateWithAuth(c *fiber.Ctx) error {
// Get Authorization token from header
authToken := c.Get("Authorization")
_i.Log.Info().Str("authToken", authToken).Msg("")
req := new(request.ClientsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err := _i.clientsService.UpdateWithAuth(authToken, *req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
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"},
})
}
// =====================================================================
// NEW HIERARCHY ENDPOINTS
// =====================================================================
// GetHierarchy gets client tree structure
// @Summary Get client hierarchy
// @Description API for getting client tree structure
// @Tags Clients
// @Security Bearer
// @Param id path string true "Client ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/{id}/hierarchy [get]
func (_i *clientsController) GetHierarchy(c *fiber.Ctx) error {
clientId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid client ID"},
})
}
hierarchy, err := _i.clientsService.GetHierarchy(clientId)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Client not found"},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client hierarchy successfully retrieved"},
Data: hierarchy,
})
}
// GetSubClients gets direct children
// @Summary Get sub-clients
// @Description API for getting direct children of a client
// @Tags Clients
// @Security Bearer
// @Param id path string true "Parent Client ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/{id}/sub-clients [get]
func (_i *clientsController) GetSubClients(c *fiber.Ctx) error {
parentId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid parent client ID"},
})
}
// For now, use GetAll with parent filter
req := request.ClientsQueryRequest{
ParentClientId: &parentId,
Pagination: &paginator.Pagination{Page: 1, Limit: 100},
}
subClients, _, err := _i.clientsService.All("", req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Failed to get sub-clients"},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Sub-clients successfully retrieved"},
Data: subClients,
})
}
// CreateSubClient creates client under parent
// @Summary Create sub-client
// @Description API for creating a client under a parent
// @Tags Clients
// @Security Bearer
// @Param id path string true "Parent Client ID"
// @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/{id}/sub-clients [post]
func (_i *clientsController) CreateSubClient(c *fiber.Ctx) error {
parentId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid parent client ID"},
})
}
req := new(request.ClientsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
client, err := _i.clientsService.CreateSubClient(parentId, *req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Sub-client successfully created"},
Data: client,
})
}
// MoveClient moves client to different parent
// @Summary Move client
// @Description API for moving a client to different parent
// @Tags Clients
// @Security Bearer
// @Param id path string true "Client ID"
// @Param payload body request.MoveClientRequest 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/{id}/move [put]
func (_i *clientsController) MoveClient(c *fiber.Ctx) error {
clientId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid client ID"},
})
}
req := new(request.MoveClientRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
err = _i.clientsService.MoveClient(clientId, *req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client moved successfully"},
})
}
// GetClientStats gets statistics
// @Summary Get client statistics
// @Description API for getting client statistics
// @Tags Clients
// @Security Bearer
// @Param id path string true "Client ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/{id}/stats [get]
func (_i *clientsController) GetClientStats(c *fiber.Ctx) error {
clientId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid client ID"},
})
}
stats, err := _i.clientsService.GetClientStats(clientId)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Client not found"},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client statistics successfully retrieved"},
Data: stats,
})
}
// BulkCreateSubClients creates multiple sub-clients
// @Summary Bulk create sub-clients
// @Description API for creating multiple sub-clients at once
// @Tags Clients
// @Security Bearer
// @Param payload body request.BulkCreateSubClientsRequest 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/bulk-sub-clients [post]
func (_i *clientsController) BulkCreateSubClients(c *fiber.Ctx) error {
req := new(request.BulkCreateSubClientsRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
result, err := _i.clientsService.BulkCreateSubClients(*req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Bulk operation completed"},
Data: result,
})
}
// CreateClientWithUser creates a client and admin user in one request
// @Summary Create client with admin user
// @Description API for creating a client and its admin user in a single request (Public endpoint)
// @Tags Clients
// @Param payload body request.ClientWithUserCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/with-user [post]
func (_i *clientsController) CreateClientWithUser(c *fiber.Ctx) error {
req := new(request.ClientWithUserCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
result, err := _i.clientsService.CreateClientWithUser(*req)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{result.Message},
Data: result,
})
}
// =====================================================================
// LOGO UPLOAD ENDPOINTS
// =====================================================================
// UploadLogo uploads client logo
// @Summary Upload client logo
// @Description API for uploading client logo image to MinIO (uses client ID from auth token)
// @Tags Clients
// @Security Bearer
// @Param Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param logo formData file true "Logo image file (jpg, jpeg, png, gif, webp, max 5MB)"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/logo [post]
func (_i *clientsController) UploadLogo(c *fiber.Ctx) error {
// Get Authorization token from header
authToken := c.Get("Authorization")
_i.Log.Info().Str("authToken", authToken).Msg("")
imagePath, err := _i.clientsService.UploadLogo(authToken, c)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client logo uploaded successfully"},
Data: map[string]string{
"imagePath": imagePath,
},
})
}
// DeleteLogo deletes client logo
// @Summary Delete client logo
// @Description API for deleting client logo from MinIO
// @Tags Clients
// @Security Bearer
// @Param id path string true "Client ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/{id}/logo [delete]
func (_i *clientsController) DeleteLogo(c *fiber.Ctx) error {
clientId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid client ID"},
})
}
// Get current client to find image path
client, err := _i.clientsService.Show(clientId)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Client not found"},
})
}
if client.LogoImagePath == nil || *client.LogoImagePath == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"No logo found for this client"},
})
}
err = _i.clientsService.DeleteLogo(clientId, *client.LogoImagePath)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Client logo deleted successfully"},
})
}
// GetLogoURL generates presigned URL for client logo
// @Summary Get client logo URL
// @Description API for generating presigned URL for client logo
// @Tags Clients
// @Security Bearer
// @Param id path string true "Client ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/{id}/logo/url [get]
func (_i *clientsController) GetLogoURL(c *fiber.Ctx) error {
clientId, err := uuid.Parse(c.Params("id"))
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Invalid client ID"},
})
}
// Get current client to find image path
client, err := _i.clientsService.Show(clientId)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"Client not found"},
})
}
if client.LogoImagePath == nil || *client.LogoImagePath == "" {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{"No logo found for this client"},
})
}
url, err := _i.clientsService.GetLogoURL(*client.LogoImagePath)
if err != nil {
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Logo URL generated successfully"},
Data: map[string]string{
"url": url,
},
})
}
// ViewLogo serves client logo file
// @Summary View client logo
// @Description API for viewing client logo file by filename
// @Tags Clients
// @Param filename path string true "Logo filename"
// @Success 200 {file} file
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /clients/logo/{filename} [get]
func (_i *clientsController) ViewLogo(c *fiber.Ctx) error {
filename := c.Params("filename")
_i.Log.Info().Str("filename", filename).Msg("Viewing client logo")
// Get logo file from MinIO
data, contentType, err := _i.clientsService.ViewLogo(filename)
if err != nil {
_i.Log.Error().Err(err).Str("filename", filename).Msg("Failed to get logo file")
return utilRes.Resp(c, utilRes.Response{
Success: false,
Messages: utilRes.Messages{err.Error()},
})
}
// Set content type and serve file
c.Set("Content-Type", contentType)
c.Set("Cache-Control", "public, max-age=3600") // Cache for 1 hour
return c.Send(data)
}