Przeglądaj źródła

feat: implements pagination DTO to read marketplace catalog items route

Matheus Marques Polillo 9 miesięcy temu
rodzic
commit
9aac05423e

+ 4 - 1
src/domain/repository/marketplaceQueryRepo.go

@@ -1,12 +1,15 @@
 package repository
 package repository
 
 
 import (
 import (
+	"github.com/goinfinite/os/src/domain/dto"
 	"github.com/goinfinite/os/src/domain/entity"
 	"github.com/goinfinite/os/src/domain/entity"
 	"github.com/goinfinite/os/src/domain/valueObject"
 	"github.com/goinfinite/os/src/domain/valueObject"
 )
 )
 
 
 type MarketplaceQueryRepo interface {
 type MarketplaceQueryRepo interface {
-	ReadCatalogItems() ([]entity.MarketplaceCatalogItem, error)
+	ReadCatalogItems(
+		readDto dto.ReadMarketplaceCatalogItemsRequest,
+	) (dto.ReadMarketplaceCatalogItemsResponse, error)
 	ReadCatalogItemById(
 	ReadCatalogItemById(
 		catalogId valueObject.MarketplaceItemId,
 		catalogId valueObject.MarketplaceItemId,
 	) (entity.MarketplaceCatalogItem, error)
 	) (entity.MarketplaceCatalogItem, error)

+ 11 - 5
src/domain/useCase/readMarketplaceCatalog.go

@@ -4,18 +4,24 @@ import (
 	"errors"
 	"errors"
 	"log/slog"
 	"log/slog"
 
 
-	"github.com/goinfinite/os/src/domain/entity"
+	"github.com/goinfinite/os/src/domain/dto"
 	"github.com/goinfinite/os/src/domain/repository"
 	"github.com/goinfinite/os/src/domain/repository"
 )
 )
 
 
+var MarketplaceDefaultPagination dto.Pagination = dto.Pagination{
+	PageNumber:   0,
+	ItemsPerPage: 10,
+}
+
 func ReadMarketplaceCatalog(
 func ReadMarketplaceCatalog(
 	marketplaceQueryRepo repository.MarketplaceQueryRepo,
 	marketplaceQueryRepo repository.MarketplaceQueryRepo,
-) ([]entity.MarketplaceCatalogItem, error) {
-	catalogItems, err := marketplaceQueryRepo.ReadCatalogItems()
+	readDto dto.ReadMarketplaceCatalogItemsRequest,
+) (dto.ReadMarketplaceCatalogItemsResponse, error) {
+	responseDto, err := marketplaceQueryRepo.ReadCatalogItems(readDto)
 	if err != nil {
 	if err != nil {
 		slog.Error("ReadMarketplaceCatalogItemsError", slog.Any("error", err))
 		slog.Error("ReadMarketplaceCatalogItemsError", slog.Any("error", err))
-		return nil, errors.New("ReadMarketplaceCatalogItemsInfraError")
+		return responseDto, errors.New("ReadMarketplaceCatalogItemsInfraError")
 	}
 	}
 
 
-	return catalogItems, nil
+	return responseDto, nil
 }
 }

+ 92 - 32
src/infra/marketplace/marketplaceQueryRepo.go

@@ -7,6 +7,7 @@ import (
 	"slices"
 	"slices"
 	"strings"
 	"strings"
 
 
+	"github.com/goinfinite/os/src/domain/dto"
 	"github.com/goinfinite/os/src/domain/entity"
 	"github.com/goinfinite/os/src/domain/entity"
 	"github.com/goinfinite/os/src/domain/valueObject"
 	"github.com/goinfinite/os/src/domain/valueObject"
 	voHelper "github.com/goinfinite/os/src/domain/valueObject/helper"
 	voHelper "github.com/goinfinite/os/src/domain/valueObject/helper"
@@ -389,7 +390,9 @@ func (repo *MarketplaceQueryRepo) catalogItemFactory(
 
 
 	itemInstallCmdSteps := []valueObject.UnixCommand{}
 	itemInstallCmdSteps := []valueObject.UnixCommand{}
 	if itemMap["installCmdSteps"] != nil {
 	if itemMap["installCmdSteps"] != nil {
-		itemInstallCmdSteps, err = repo.catalogItemCmdStepsFactory(itemMap["installCmdSteps"])
+		itemInstallCmdSteps, err = repo.catalogItemCmdStepsFactory(
+			itemMap["installCmdSteps"],
+		)
 		if err != nil {
 		if err != nil {
 			return catalogItem, err
 			return catalogItem, err
 		}
 		}
@@ -397,7 +400,9 @@ func (repo *MarketplaceQueryRepo) catalogItemFactory(
 
 
 	itemUninstallCmdSteps := []valueObject.UnixCommand{}
 	itemUninstallCmdSteps := []valueObject.UnixCommand{}
 	if itemMap["uninstallCmdSteps"] != nil {
 	if itemMap["uninstallCmdSteps"] != nil {
-		itemUninstallCmdSteps, err = repo.catalogItemCmdStepsFactory(itemMap["uninstallCmdSteps"])
+		itemUninstallCmdSteps, err = repo.catalogItemCmdStepsFactory(
+			itemMap["uninstallCmdSteps"],
+		)
 		if err != nil {
 		if err != nil {
 			return catalogItem, err
 			return catalogItem, err
 		}
 		}
@@ -428,41 +433,30 @@ func (repo *MarketplaceQueryRepo) catalogItemFactory(
 
 
 	itemScreenshotUrls := []valueObject.Url{}
 	itemScreenshotUrls := []valueObject.Url{}
 	if itemMap["screenshotUrls"] != nil {
 	if itemMap["screenshotUrls"] != nil {
-		itemScreenshotUrls, err = repo.catalogItemScreenshotUrlsFactory(itemMap["screenshotUrls"])
+		itemScreenshotUrls, err = repo.catalogItemScreenshotUrlsFactory(
+			itemMap["screenshotUrls"],
+		)
 		if err != nil {
 		if err != nil {
 			return catalogItem, err
 			return catalogItem, err
 		}
 		}
 	}
 	}
 
 
 	return entity.NewMarketplaceCatalogItem(
 	return entity.NewMarketplaceCatalogItem(
-		itemId,
-		itemSlugs,
-		itemName,
-		itemType,
-		itemDescription,
-		itemServices,
-		itemMappings,
-		itemDataFields,
-		itemInstallCmdSteps,
-		itemUninstallCmdSteps,
-		itemUninstallFileNames,
-		estimatedSizeBytes,
-		itemAvatarUrl,
-		itemScreenshotUrls,
+		itemId, itemSlugs, itemName, itemType, itemDescription, itemServices,
+		itemMappings, itemDataFields, itemInstallCmdSteps, itemUninstallCmdSteps,
+		itemUninstallFileNames, estimatedSizeBytes, itemAvatarUrl, itemScreenshotUrls,
 	), nil
 	), nil
 }
 }
 
 
-func (repo *MarketplaceQueryRepo) ReadCatalogItems() (
-	[]entity.MarketplaceCatalogItem, error,
-) {
-	catalogItems := []entity.MarketplaceCatalogItem{}
-
-	_, err := os.Stat(infraEnvs.MarketplaceItemsDir)
+func (repo *MarketplaceQueryRepo) ReadCatalogItems(
+	readDto dto.ReadMarketplaceCatalogItemsRequest,
+) (catalogItemsDto dto.ReadMarketplaceCatalogItemsResponse, err error) {
+	_, err = os.Stat(infraEnvs.MarketplaceItemsDir)
 	if err != nil {
 	if err != nil {
 		marketplaceCmdRepo := NewMarketplaceCmdRepo(repo.persistentDbSvc)
 		marketplaceCmdRepo := NewMarketplaceCmdRepo(repo.persistentDbSvc)
 		err = marketplaceCmdRepo.RefreshItems()
 		err = marketplaceCmdRepo.RefreshItems()
 		if err != nil {
 		if err != nil {
-			return catalogItems, errors.New(
+			return catalogItemsDto, errors.New(
 				"RefreshMarketplaceItemsError: " + err.Error(),
 				"RefreshMarketplaceItemsError: " + err.Error(),
 			)
 			)
 		}
 		}
@@ -474,18 +468,19 @@ func (repo *MarketplaceQueryRepo) ReadCatalogItems() (
 			"-not -path '*/.*' -not -name '.*'",
 			"-not -path '*/.*' -not -name '.*'",
 	)
 	)
 	if err != nil {
 	if err != nil {
-		return catalogItems, errors.New("ReadMarketplaceFilesError: " + err.Error())
+		return catalogItemsDto, errors.New("ReadMarketplaceFilesError: " + err.Error())
 	}
 	}
 
 
 	if len(rawCatalogFilesList) == 0 {
 	if len(rawCatalogFilesList) == 0 {
-		return catalogItems, errors.New("NoMarketplaceFilesFound")
+		return catalogItemsDto, errors.New("NoMarketplaceFilesFound")
 	}
 	}
 
 
 	rawCatalogFilesListParts := strings.Split(rawCatalogFilesList, "\n")
 	rawCatalogFilesListParts := strings.Split(rawCatalogFilesList, "\n")
 	if len(rawCatalogFilesListParts) == 0 {
 	if len(rawCatalogFilesListParts) == 0 {
-		return catalogItems, errors.New("NoMarketplaceFilesFound")
+		return catalogItemsDto, errors.New("NoMarketplaceFilesFound")
 	}
 	}
 
 
+	catalogItems := []entity.MarketplaceCatalogItem{}
 	catalogItemsIdsMap := map[uint16]struct{}{}
 	catalogItemsIdsMap := map[uint16]struct{}{}
 	for _, rawFilePath := range rawCatalogFilesListParts {
 	for _, rawFilePath := range rawCatalogFilesListParts {
 		itemFilePath, err := valueObject.NewUnixFilePath(rawFilePath)
 		itemFilePath, err := valueObject.NewUnixFilePath(rawFilePath)
@@ -509,6 +504,28 @@ func (repo *MarketplaceQueryRepo) ReadCatalogItems() (
 			catalogItem.Id, _ = valueObject.NewMarketplaceItemId(0)
 			catalogItem.Id, _ = valueObject.NewMarketplaceItemId(0)
 		}
 		}
 
 
+		if len(catalogItems) >= int(readDto.Pagination.ItemsPerPage) {
+			break
+		}
+
+		if readDto.ItemId != nil && catalogItem.Id != *readDto.ItemId {
+			continue
+		}
+
+		if readDto.ItemSlug != nil {
+			if !slices.Contains(catalogItem.Slugs, *readDto.ItemSlug) {
+				continue
+			}
+		}
+
+		if readDto.ItemName != nil && catalogItem.Name != *readDto.ItemName {
+			continue
+		}
+
+		if readDto.ItemType != nil && catalogItem.Type != *readDto.ItemType {
+			continue
+		}
+
 		catalogItems = append(catalogItems, catalogItem)
 		catalogItems = append(catalogItems, catalogItem)
 
 
 		if catalogItem.Id.Uint16() != 0 {
 		if catalogItem.Id.Uint16() != 0 {
@@ -546,18 +563,61 @@ func (repo *MarketplaceQueryRepo) ReadCatalogItems() (
 		itemsIdsSlice = append(itemsIdsSlice, nextAvailableId.Uint16())
 		itemsIdsSlice = append(itemsIdsSlice, nextAvailableId.Uint16())
 	}
 	}
 
 
-	return catalogItems, nil
+	sortDirectionStr := "asc"
+	if readDto.Pagination.SortDirection != nil {
+		sortDirectionStr = readDto.Pagination.SortDirection.String()
+	}
+
+	if readDto.Pagination.SortBy != nil {
+		slices.SortStableFunc(catalogItems, func(a, b entity.MarketplaceCatalogItem) int {
+			firstElement := a
+			secondElement := b
+			if sortDirectionStr != "asc" {
+				firstElement = b
+				secondElement = a
+			}
+
+			switch readDto.Pagination.SortBy.String() {
+			case "id":
+				if firstElement.Id.Uint16() < secondElement.Id.Uint16() {
+					return -1
+				}
+				if firstElement.Id.Uint16() > secondElement.Id.Uint16() {
+					return 1
+				}
+				return 0
+			case "name":
+				return strings.Compare(firstElement.Name.String(), secondElement.Name.String())
+			case "type":
+				return strings.Compare(firstElement.Type.String(), secondElement.Type.String())
+			default:
+				return 0
+			}
+		})
+	}
+
+	itemsTotal := uint64(len(catalogItems))
+	pagesTotal := uint32(itemsTotal / uint64(readDto.Pagination.ItemsPerPage))
+
+	paginationDto := readDto.Pagination
+	paginationDto.ItemsTotal = &itemsTotal
+	paginationDto.PagesTotal = &pagesTotal
+
+	return dto.ReadMarketplaceCatalogItemsResponse{
+		Pagination: paginationDto,
+		Items:      catalogItems,
+	}, nil
 }
 }
 
 
 func (repo *MarketplaceQueryRepo) ReadCatalogItemById(
 func (repo *MarketplaceQueryRepo) ReadCatalogItemById(
 	catalogId valueObject.MarketplaceItemId,
 	catalogId valueObject.MarketplaceItemId,
 ) (catalogItem entity.MarketplaceCatalogItem, err error) {
 ) (catalogItem entity.MarketplaceCatalogItem, err error) {
-	catalogItems, err := repo.ReadCatalogItems()
+	catalogItems, err := repo.ReadCatalogItems(dto.ReadMarketplaceCatalogItemsRequest{})
 	if err != nil {
 	if err != nil {
 		return catalogItem, err
 		return catalogItem, err
 	}
 	}
 
 
-	for _, catalogItem := range catalogItems {
+	for _, catalogItem := range catalogItems.Items {
 		if catalogItem.Id.Uint16() != catalogId.Uint16() {
 		if catalogItem.Id.Uint16() != catalogId.Uint16() {
 			continue
 			continue
 		}
 		}
@@ -571,12 +631,12 @@ func (repo *MarketplaceQueryRepo) ReadCatalogItemById(
 func (repo *MarketplaceQueryRepo) ReadCatalogItemBySlug(
 func (repo *MarketplaceQueryRepo) ReadCatalogItemBySlug(
 	slug valueObject.MarketplaceItemSlug,
 	slug valueObject.MarketplaceItemSlug,
 ) (catalogItem entity.MarketplaceCatalogItem, err error) {
 ) (catalogItem entity.MarketplaceCatalogItem, err error) {
-	catalogItems, err := repo.ReadCatalogItems()
+	catalogItems, err := repo.ReadCatalogItems(dto.ReadMarketplaceCatalogItemsRequest{})
 	if err != nil {
 	if err != nil {
 		return catalogItem, err
 		return catalogItem, err
 	}
 	}
 
 
-	for _, catalogItem := range catalogItems {
+	for _, catalogItem := range catalogItems.Items {
 		for _, catalogItemSlug := range catalogItem.Slugs {
 		for _, catalogItemSlug := range catalogItem.Slugs {
 			if catalogItemSlug.String() != slug.String() {
 			if catalogItemSlug.String() != slug.String() {
 				continue
 				continue

+ 22 - 5
src/infra/marketplace/marketplaceQueryRepo_test.go

@@ -4,6 +4,9 @@ import (
 	"testing"
 	"testing"
 
 
 	testHelpers "github.com/goinfinite/os/src/devUtils"
 	testHelpers "github.com/goinfinite/os/src/devUtils"
+	"github.com/goinfinite/os/src/domain/dto"
+	"github.com/goinfinite/os/src/domain/useCase"
+	"github.com/goinfinite/os/src/domain/valueObject"
 	internalDbInfra "github.com/goinfinite/os/src/infra/internalDatabase"
 	internalDbInfra "github.com/goinfinite/os/src/infra/internalDatabase"
 )
 )
 
 
@@ -12,14 +15,28 @@ func TestVirtualHostQueryRepo(t *testing.T) {
 	marketplaceQueryRepo := NewMarketplaceQueryRepo(persistentDbSvc)
 	marketplaceQueryRepo := NewMarketplaceQueryRepo(persistentDbSvc)
 	testHelpers.LoadEnvVars()
 	testHelpers.LoadEnvVars()
 
 
-	t.Run("ReadCatalogItems", func(t *testing.T) {
-		catalogItems, err := marketplaceQueryRepo.ReadCatalogItems()
+	t.Run("Read", func(t *testing.T) {
+		itemType, _ := valueObject.NewMarketplaceItemType("app")
+
+		paginationDto := useCase.MarketplaceDefaultPagination
+		sortBy, _ := valueObject.NewPaginationSortBy("id")
+		sortDirection, _ := valueObject.NewPaginationSortDirection("desc")
+		paginationDto.SortBy = &sortBy
+		paginationDto.SortDirection = &sortDirection
+
+		readDto := dto.ReadMarketplaceCatalogItemsRequest{
+			Pagination: paginationDto,
+			ItemType:   &itemType,
+		}
+
+		responseDto, err := marketplaceQueryRepo.ReadCatalogItems(readDto)
 		if err != nil {
 		if err != nil {
-			t.Errorf("ExpectingNoErrorButGot: %v", err)
+			t.Errorf("ReadMarketplaceItemsError: %v", err)
+			return
 		}
 		}
 
 
-		if len(catalogItems) == 0 {
-			t.Errorf("ExpectingEmptySliceButGot: %v", catalogItems)
+		if len(responseDto.Items) == 0 {
+			t.Errorf("NoItemsFound")
 		}
 		}
 	})
 	})
 }
 }

+ 17 - 3
src/presentation/api/controller/marketplace.go

@@ -35,11 +35,25 @@ func NewMarketplaceController(
 // @Security     Bearer
 // @Security     Bearer
 // @Accept       json
 // @Accept       json
 // @Produce      json
 // @Produce      json
-// @Success      200 {array} entity.MarketplaceCatalogItem
+// @Param        itemId query  uint  false  "Id"
+// @Param        itemSlug query  string  false  "Slug"
+// @Param        itemName query  string  false  "Name"
+// @Param        itemType query  string  false  "Type"
+// @Param        pageNumber query  uint  false  "PageNumber (Pagination)"
+// @Param        itemsPerPage query  uint  false  "ItemsPerPage (Pagination)"
+// @Param        sortBy query  string  false  "SortBy (Pagination)"
+// @Param        sortDirection query  string  false  "SortDirection (Pagination)"
+// @Param        lastSeenId query  string  false  "LastSeenId (Pagination)"
+// @Success      200 {array} dto.ReadMarketplaceItemsResponse
 // @Router       /v1/marketplace/catalog/ [get]
 // @Router       /v1/marketplace/catalog/ [get]
 func (controller *MarketplaceController) ReadCatalog(c echo.Context) error {
 func (controller *MarketplaceController) ReadCatalog(c echo.Context) error {
+	requestBody, err := apiHelper.ReadRequestBody(c)
+	if err != nil {
+		return err
+	}
+
 	return apiHelper.ServiceResponseWrapper(
 	return apiHelper.ServiceResponseWrapper(
-		c, controller.marketplaceService.ReadCatalog(),
+		c, controller.marketplaceService.ReadCatalog(requestBody),
 	)
 	)
 }
 }
 
 
@@ -221,7 +235,7 @@ func (controller *MarketplaceController) DeleteInstalledItem(c echo.Context) err
 }
 }
 
 
 func (controller *MarketplaceController) AutoRefreshMarketplaceItems() {
 func (controller *MarketplaceController) AutoRefreshMarketplaceItems() {
-	taskInterval := time.Duration(24) * time.Hour
+	taskInterval := time.Duration(2) * time.Minute
 	timer := time.NewTicker(taskInterval)
 	timer := time.NewTicker(taskInterval)
 	defer timer.Stop()
 	defer timer.Stop()
 
 

+ 87 - 10
src/presentation/cli/controller/marketplace.go

@@ -27,14 +27,91 @@ func NewMarketplaceController(
 }
 }
 
 
 func (controller *MarketplaceController) ReadCatalog() *cobra.Command {
 func (controller *MarketplaceController) ReadCatalog() *cobra.Command {
+	var catalogItemIdUint uint64
+	var catalogItemSlugStr, catalogItemNameStr, catalogItemTypeStr string
+	var paginationPageNumberUint32 uint32
+	var paginationItemsPerPageUint16 uint16
+	var paginationSortByStr, paginationSortDirectionStr string
+	var paginationLastSeenIdStr string
+
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
 		Use:   "list-catalog",
 		Use:   "list-catalog",
 		Short: "ReadCatalogItems",
 		Short: "ReadCatalogItems",
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
-			cliHelper.ServiceResponseWrapper(controller.marketplaceService.ReadCatalog())
+			requestBody := map[string]interface{}{}
+
+			if catalogItemIdUint != 0 {
+				requestBody["id"] = catalogItemIdUint
+			}
+
+			if catalogItemSlugStr != "" {
+				requestBody["slug"] = catalogItemSlugStr
+			}
+
+			if catalogItemNameStr != "" {
+				requestBody["name"] = catalogItemNameStr
+			}
+
+			if catalogItemTypeStr != "" {
+				requestBody["type"] = catalogItemTypeStr
+			}
+
+			if paginationPageNumberUint32 != 0 {
+				requestBody["pageNumber"] = paginationPageNumberUint32
+			}
+
+			if paginationItemsPerPageUint16 != 0 {
+				requestBody["itemsPerPage"] = paginationItemsPerPageUint16
+			}
+
+			if paginationSortByStr != "" {
+				requestBody["sortBy"] = paginationSortByStr
+			}
+
+			if paginationSortDirectionStr != "" {
+				requestBody["sortDirection"] = paginationSortDirectionStr
+			}
+
+			if paginationLastSeenIdStr != "" {
+				requestBody["lastSeenId"] = paginationLastSeenIdStr
+			}
+
+			cliHelper.ServiceResponseWrapper(
+				controller.marketplaceService.ReadCatalog(requestBody),
+			)
 		},
 		},
 	}
 	}
 
 
+	cmd.Flags().Uint64VarP(
+		&catalogItemIdUint, "catalog-item-id", "i", 0, "CatalogItemId",
+	)
+	cmd.Flags().StringVarP(
+		&catalogItemSlugStr, "catalog-item-slug", "s", "", "CatalogItemSlug",
+	)
+	cmd.Flags().StringVarP(
+		&catalogItemNameStr, "catalog-item-name", "n", "", "CatalogItemName",
+	)
+	cmd.Flags().StringVarP(
+		&catalogItemTypeStr, "catalog-item-type", "t", "", "CatalogItemType",
+	)
+	cmd.Flags().Uint32VarP(
+		&paginationPageNumberUint32, "page-number", "p", 0, "PageNumber (Pagination)",
+	)
+	cmd.Flags().Uint16VarP(
+		&paginationItemsPerPageUint16, "items-per-page", "m", 0,
+		"ItemsPerPage (Pagination)",
+	)
+	cmd.Flags().StringVarP(
+		&paginationSortByStr, "sort-by", "y", "", "SortBy (Pagination)",
+	)
+	cmd.Flags().StringVarP(
+		&paginationSortDirectionStr, "sort-direction", "r", "",
+		"SortDirection (Pagination)",
+	)
+	cmd.Flags().StringVarP(
+		&paginationLastSeenIdStr, "last-seen-id", "l", "", "LastSeenId (Pagination)",
+	)
+
 	return cmd
 	return cmd
 }
 }
 
 
@@ -77,8 +154,7 @@ func (controller *MarketplaceController) parseDataFields(
 func (controller *MarketplaceController) InstallCatalogItem() *cobra.Command {
 func (controller *MarketplaceController) InstallCatalogItem() *cobra.Command {
 	var hostnameStr string
 	var hostnameStr string
 	var catalogIdInt int
 	var catalogIdInt int
-	var slugStr string
-	var urlPath string
+	var slugStr, urlPathStr string
 	var dataFieldsStr []string
 	var dataFieldsStr []string
 
 
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
@@ -99,8 +175,8 @@ func (controller *MarketplaceController) InstallCatalogItem() *cobra.Command {
 				requestBody["slug"] = slugStr
 				requestBody["slug"] = slugStr
 			}
 			}
 
 
-			if urlPath != "" {
-				requestBody["urlPath"] = urlPath
+			if urlPathStr != "" {
+				requestBody["urlPath"] = urlPathStr
 			}
 			}
 
 
 			dataFields, err := controller.parseDataFields(dataFieldsStr)
 			dataFields, err := controller.parseDataFields(dataFieldsStr)
@@ -118,9 +194,10 @@ func (controller *MarketplaceController) InstallCatalogItem() *cobra.Command {
 	cmd.Flags().StringVarP(&hostnameStr, "hostname", "n", "", "VirtualHostName")
 	cmd.Flags().StringVarP(&hostnameStr, "hostname", "n", "", "VirtualHostName")
 	cmd.Flags().IntVarP(&catalogIdInt, "id", "i", 0, "CatalogItemId")
 	cmd.Flags().IntVarP(&catalogIdInt, "id", "i", 0, "CatalogItemId")
 	cmd.Flags().StringVarP(&slugStr, "slug", "s", "", "CatalogItemSlug")
 	cmd.Flags().StringVarP(&slugStr, "slug", "s", "", "CatalogItemSlug")
-	cmd.Flags().StringVarP(&urlPath, "url-path", "d", "", "UrlPath")
+	cmd.Flags().StringVarP(&urlPathStr, "url-path", "d", "", "UrlPath")
 	cmd.Flags().StringSliceVarP(
 	cmd.Flags().StringSliceVarP(
-		&dataFieldsStr, "data-fields", "f", []string{}, "InstallationDataFields (key:value)",
+		&dataFieldsStr, "data-fields", "f", []string{},
+		"InstallationDataFields (key:value)",
 	)
 	)
 	return cmd
 	return cmd
 }
 }
@@ -141,7 +218,7 @@ func (controller *MarketplaceController) ReadInstalledItems() *cobra.Command {
 
 
 func (controller *MarketplaceController) DeleteInstalledItem() *cobra.Command {
 func (controller *MarketplaceController) DeleteInstalledItem() *cobra.Command {
 	var installedIdInt int
 	var installedIdInt int
-	var shouldUninstallServices string
+	var shouldUninstallServicesStr string
 
 
 	cmd := &cobra.Command{
 	cmd := &cobra.Command{
 		Use:   "delete",
 		Use:   "delete",
@@ -149,7 +226,7 @@ func (controller *MarketplaceController) DeleteInstalledItem() *cobra.Command {
 		Run: func(cmd *cobra.Command, args []string) {
 		Run: func(cmd *cobra.Command, args []string) {
 			requestBody := map[string]interface{}{
 			requestBody := map[string]interface{}{
 				"installedId":             installedIdInt,
 				"installedId":             installedIdInt,
-				"shouldUninstallServices": shouldUninstallServices,
+				"shouldUninstallServices": shouldUninstallServicesStr,
 			}
 			}
 
 
 			cliHelper.ServiceResponseWrapper(
 			cliHelper.ServiceResponseWrapper(
@@ -161,7 +238,7 @@ func (controller *MarketplaceController) DeleteInstalledItem() *cobra.Command {
 	cmd.Flags().IntVarP(&installedIdInt, "installed-id", "i", 0, "InstalledItemId")
 	cmd.Flags().IntVarP(&installedIdInt, "installed-id", "i", 0, "InstalledItemId")
 	cmd.MarkFlagRequired("installed-id")
 	cmd.MarkFlagRequired("installed-id")
 	cmd.Flags().StringVarP(
 	cmd.Flags().StringVarP(
-		&shouldUninstallServices, "should-uninstall-services", "s", "true",
+		&shouldUninstallServicesStr, "should-uninstall-services", "s", "true",
 		"ShouldUninstallUnusedServices",
 		"ShouldUninstallUnusedServices",
 	)
 	)
 	return cmd
 	return cmd

+ 90 - 2
src/presentation/service/marketplace.go

@@ -1,6 +1,7 @@
 package service
 package service
 
 
 import (
 import (
+	"errors"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 
 
@@ -30,9 +31,96 @@ func NewMarketplaceService(
 	}
 	}
 }
 }
 
 
-func (service *MarketplaceService) ReadCatalog() ServiceOutput {
+func (service *MarketplaceService) ReadCatalog(
+	input map[string]interface{},
+) ServiceOutput {
+	var idPtr *valueObject.MarketplaceItemId
+	if input["id"] != nil {
+		id, err := valueObject.NewMarketplaceItemId(input["id"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		idPtr = &id
+	}
+
+	var slugPtr *valueObject.MarketplaceItemSlug
+	if input["slug"] != nil {
+		slug, err := valueObject.NewMarketplaceItemSlug(input["slug"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		slugPtr = &slug
+	}
+
+	var namePtr *valueObject.MarketplaceItemName
+	if input["name"] != nil {
+		name, err := valueObject.NewMarketplaceItemName(input["name"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		namePtr = &name
+	}
+
+	var typePtr *valueObject.MarketplaceItemType
+	if input["type"] != nil {
+		itemType, err := valueObject.NewMarketplaceItemType(input["type"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		typePtr = &itemType
+	}
+
+	paginationDto := useCase.MarketplaceDefaultPagination
+	if input["pageNumber"] != nil {
+		pageNumber, err := voHelper.InterfaceToUint32(input["pageNumber"])
+		if err != nil {
+			return NewServiceOutput(UserError, errors.New("InvalidPageNumber"))
+		}
+		paginationDto.PageNumber = pageNumber
+	}
+
+	if input["itemsPerPage"] != nil {
+		itemsPerPage, err := voHelper.InterfaceToUint16(input["itemsPerPage"])
+		if err != nil {
+			return NewServiceOutput(UserError, errors.New("InvalidItemsPerPage"))
+		}
+		paginationDto.ItemsPerPage = itemsPerPage
+	}
+
+	if input["sortBy"] != nil {
+		sortBy, err := valueObject.NewPaginationSortBy(input["sortBy"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		paginationDto.SortBy = &sortBy
+	}
+
+	if input["sortDirection"] != nil {
+		sortDirection, err := valueObject.NewPaginationSortDirection(input["sortDirection"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		paginationDto.SortDirection = &sortDirection
+	}
+
+	if input["lastSeenId"] != nil {
+		lastSeenId, err := valueObject.NewPaginationLastSeenId(input["lastSeenId"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		paginationDto.LastSeenId = &lastSeenId
+	}
+
+	readDto := dto.ReadMarketplaceCatalogItemsRequest{
+		Pagination: paginationDto,
+		ItemId:     idPtr,
+		ItemSlug:   slugPtr,
+		ItemName:   namePtr,
+		ItemType:   typePtr,
+	}
+
 	marketplaceQueryRepo := marketplaceInfra.NewMarketplaceQueryRepo(service.persistentDbSvc)
 	marketplaceQueryRepo := marketplaceInfra.NewMarketplaceQueryRepo(service.persistentDbSvc)
-	itemsList, err := useCase.ReadMarketplaceCatalog(marketplaceQueryRepo)
+	itemsList, err := useCase.ReadMarketplaceCatalog(marketplaceQueryRepo, readDto)
 	if err != nil {
 	if err != nil {
 		return NewServiceOutput(InfraError, err.Error())
 		return NewServiceOutput(InfraError, err.Error())
 	}
 	}

+ 3 - 1
src/presentation/ui/presenter/marketplace.go

@@ -91,7 +91,9 @@ func (presenter *MarketplacePresenter) marketplaceOverviewFactory(listType strin
 
 
 	catalogItemsList := []entity.MarketplaceCatalogItem{}
 	catalogItemsList := []entity.MarketplaceCatalogItem{}
 	if listType == "catalog" {
 	if listType == "catalog" {
-		responseOutput := presenter.marketplaceService.ReadCatalog()
+		responseOutput := presenter.marketplaceService.ReadCatalog(
+			map[string]interface{}{},
+		)
 		if responseOutput.Status != service.Success {
 		if responseOutput.Status != service.Success {
 			return overview, errors.New("FailedToReadCatalogItems")
 			return overview, errors.New("FailedToReadCatalogItems")
 		}
 		}