Преглед изворни кода

feat: using pagination and new method for read items, a big game change

Matheus Marques Polillo пре 9 месеци
родитељ
комит
f9ef022947

+ 4 - 4
src/domain/dto/readMarketplaceCatalogItems.go

@@ -7,10 +7,10 @@ import (
 
 type ReadMarketplaceCatalogItemsRequest struct {
 	Pagination Pagination                       `json:"pagination"`
-	ItemId     *valueObject.MarketplaceItemId   `json:"itemId,omitempty"`
-	ItemSlug   *valueObject.MarketplaceItemSlug `json:"itemSlug,omitempty"`
-	ItemName   *valueObject.MarketplaceItemName `json:"itemName,omitempty"`
-	ItemType   *valueObject.MarketplaceItemType `json:"itemType,omitempty"`
+	Id         *valueObject.MarketplaceItemId   `json:"id,omitempty"`
+	Slug       *valueObject.MarketplaceItemSlug `json:"slug,omitempty"`
+	Name       *valueObject.MarketplaceItemName `json:"name,omitempty"`
+	Type       *valueObject.MarketplaceItemType `json:"type,omitempty"`
 }
 
 type ReadMarketplaceCatalogItemsResponse struct {

+ 6 - 3
src/domain/dto/readMarketplaceInstalledItems.go

@@ -6,9 +6,12 @@ import (
 )
 
 type ReadMarketplaceInstalledItemsRequest struct {
-	Pagination Pagination                       `json:"pagination"`
-	ItemId     *valueObject.MarketplaceItemId   `json:"itemId,omitempty"`
-	ItemType   *valueObject.MarketplaceItemType `json:"itemType,omitempty"`
+	Pagination       Pagination                                `json:"pagination"`
+	Id               *valueObject.MarketplaceItemId            `json:"id,omitempty"`
+	Hostname         *valueObject.Fqdn                         `json:"hostname,omitempty"`
+	Type             *valueObject.MarketplaceItemType          `json:"type,omitempty"`
+	InstallationUuid *valueObject.MarketplaceInstalledItemUuid `json:"installationUuid,omitempty"`
+	InstalledAt      *valueObject.UnixTime                     `json:"installedAt,omitempty"`
 }
 
 type ReadMarketplaceInstalledItemsResponse struct {

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

@@ -13,7 +13,9 @@ type MarketplaceQueryRepo interface {
 	ReadUniqueCatalogItem(
 		readDto dto.ReadMarketplaceCatalogItemsRequest,
 	) (entity.MarketplaceCatalogItem, error)
-	ReadInstalledItems() ([]entity.MarketplaceInstalledItem, error)
+	ReadInstalledItems(
+		readDto dto.ReadMarketplaceInstalledItemsRequest,
+	) (dto.ReadMarketplaceInstalledItemsResponse, error)
 	ReadInstalledItemById(
 		installedId valueObject.MarketplaceItemId,
 	) (entity.MarketplaceInstalledItem, error)

+ 2 - 2
src/domain/useCase/installMarketplaceCatalogItem.go

@@ -63,11 +63,11 @@ func MarketplaceCatalogItemLookup(
 
 	readDto := dto.ReadMarketplaceCatalogItemsRequest{}
 	if itemId != nil {
-		readDto.ItemId = itemId
+		readDto.Id = itemId
 		return marketplaceQueryRepo.ReadUniqueCatalogItem(readDto)
 	}
 
-	readDto.ItemSlug = itemSlug
+	readDto.Slug = itemSlug
 	return marketplaceQueryRepo.ReadUniqueCatalogItem(readDto)
 }
 

+ 4 - 5
src/domain/useCase/readMarketplaceInstalledItems.go

@@ -5,19 +5,18 @@ import (
 	"log/slog"
 
 	"github.com/goinfinite/os/src/domain/dto"
-	"github.com/goinfinite/os/src/domain/entity"
 	"github.com/goinfinite/os/src/domain/repository"
 )
 
 func ReadMarketplaceInstalledItems(
 	marketplaceQueryRepo repository.MarketplaceQueryRepo,
 	readDto dto.ReadMarketplaceInstalledItemsRequest,
-) ([]entity.MarketplaceInstalledItem, error) {
-	installedItems, err := marketplaceQueryRepo.ReadInstalledItems()
+) (dto.ReadMarketplaceInstalledItemsResponse, error) {
+	responseDto, err := marketplaceQueryRepo.ReadInstalledItems(readDto)
 	if err != nil {
 		slog.Error("ReadMarketplaceInstalledItemsError", slog.Any("error", err))
-		return nil, errors.New("ReadMarketplaceInstalledItemsInfraError")
+		return responseDto, errors.New("ReadMarketplaceInstalledItemsInfraError")
 	}
 
-	return installedItems, nil
+	return responseDto, nil
 }

+ 1 - 0
src/infra/helper/embedSerializedDataToMap.go

@@ -9,6 +9,7 @@ import (
 	"gopkg.in/yaml.v3"
 )
 
+// TODO: remover isso aqui quando acabar de mudar o services
 func EmbedSerializedDataToMap(
 	embed *embed.FS,
 	filePath valueObject.UnixFilePath,

+ 11 - 4
src/infra/marketplace/marketplaceCmdRepo.go

@@ -354,7 +354,7 @@ func (repo *MarketplaceCmdRepo) InstallItem(
 	installDto dto.InstallMarketplaceCatalogItem,
 ) error {
 	readDto := dto.ReadMarketplaceCatalogItemsRequest{
-		ItemId: installDto.Id,
+		Id: installDto.Id,
 	}
 	catalogItem, err := repo.marketplaceQueryRepo.ReadUniqueCatalogItem(readDto)
 	if err != nil {
@@ -624,13 +624,20 @@ func (repo *MarketplaceCmdRepo) uninstallUnusedServices(
 		serviceNamesToUninstallMap[serviceNameWithVersion.Name.String()] = nil
 	}
 
-	installedItems, err := repo.marketplaceQueryRepo.ReadInstalledItems()
+	readDto := dto.ReadMarketplaceInstalledItemsRequest{
+		Pagination: dto.Pagination{
+			ItemsPerPage: 100,
+		},
+	}
+	installedItemsResponseDto, err := repo.marketplaceQueryRepo.ReadInstalledItems(
+		readDto,
+	)
 	if err != nil {
 		return errors.New("ReadInstalledItemsError: " + err.Error())
 	}
 
 	serviceNamesInUseMap := map[string]interface{}{}
-	for _, installedItem := range installedItems {
+	for _, installedItem := range installedItemsResponseDto.Items {
 		for _, serviceNameWithVersion := range installedItem.Services {
 			serviceNamesInUseMap[serviceNameWithVersion.Name.String()] = nil
 		}
@@ -682,7 +689,7 @@ func (repo *MarketplaceCmdRepo) UninstallItem(
 	}
 
 	readDto := dto.ReadMarketplaceCatalogItemsRequest{
-		ItemSlug: &installedItem.Slug,
+		Slug: &installedItem.Slug,
 	}
 	catalogItem, err := repo.marketplaceQueryRepo.ReadUniqueCatalogItem(readDto)
 	if err != nil {

+ 91 - 23
src/infra/marketplace/marketplaceQueryRepo.go

@@ -3,6 +3,7 @@ package marketplaceInfra
 import (
 	"errors"
 	"log/slog"
+	"math"
 	"os"
 	"slices"
 	"strings"
@@ -16,6 +17,7 @@ import (
 	infraHelper "github.com/goinfinite/os/src/infra/helper"
 	internalDbInfra "github.com/goinfinite/os/src/infra/internalDatabase"
 	dbModel "github.com/goinfinite/os/src/infra/internalDatabase/model"
+	"github.com/iancoleman/strcase"
 )
 
 type MarketplaceQueryRepo struct {
@@ -548,18 +550,26 @@ func (repo *MarketplaceQueryRepo) ReadCatalogItems(
 			break
 		}
 
-		if readDto.ItemSlug != nil {
-			if !slices.Contains(catalogItem.Slugs, *readDto.ItemSlug) {
+		if readDto.Id != nil && catalogItem.Id != *readDto.Id {
+			continue
+		}
+
+		if readDto.Slug != nil {
+			if !slices.Contains(catalogItem.Slugs, *readDto.Slug) {
 				continue
 			}
 		}
 
-		if readDto.ItemName != nil && catalogItem.Name != *readDto.ItemName {
-			continue
+		if readDto.Name != nil {
+			if !strings.EqualFold(catalogItem.Name.String(), readDto.Name.String()) {
+				continue
+			}
 		}
 
-		if readDto.ItemType != nil && catalogItem.Type != *readDto.ItemType {
-			continue
+		if readDto.Type != nil && catalogItem.Type != *readDto.Type {
+			if !strings.EqualFold(catalogItem.Type.String(), readDto.Type.String()) {
+				continue
+			}
 		}
 
 		filteredCatalogItems = append(filteredCatalogItems, catalogItem)
@@ -629,36 +639,94 @@ func (repo *MarketplaceQueryRepo) ReadUniqueCatalogItem(
 	return foundCatalogItem, nil
 }
 
-func (repo *MarketplaceQueryRepo) ReadInstalledItems() (
-	[]entity.MarketplaceInstalledItem, error,
-) {
-	entities := []entity.MarketplaceInstalledItem{}
+func (repo *MarketplaceQueryRepo) ReadInstalledItems(
+	readDto dto.ReadMarketplaceInstalledItemsRequest,
+) (installedItemsDto dto.ReadMarketplaceInstalledItemsResponse, err error) {
+	model := dbModel.MarketplaceInstalledItem{}
+	if readDto.Id != nil {
+		model.ID = uint(readDto.Id.Uint16())
+	}
+	if readDto.Hostname != nil {
+		model.Hostname = readDto.Hostname.String()
+	}
+	if readDto.Type != nil {
+		model.Type = readDto.Type.String()
+	}
+	if readDto.InstallationUuid != nil {
+		model.InstallUuid = readDto.InstallationUuid.String()
+	}
+
+	dbQuery := repo.persistentDbSvc.Handler.Where(&model)
+	if readDto.InstalledAt != nil {
+		dbQuery = dbQuery.Where("created_at = ?", readDto.InstalledAt.GetAsGoTime())
+	}
+
+	dbQuery = dbQuery.Limit(int(readDto.Pagination.ItemsPerPage))
+	if readDto.Pagination.LastSeenId == nil {
+		offset := int(readDto.Pagination.PageNumber) * int(readDto.Pagination.ItemsPerPage)
+		dbQuery = dbQuery.Offset(offset)
+	} else {
+		dbQuery = dbQuery.Where("id > ?", readDto.Pagination.LastSeenId.String())
+	}
+	if readDto.Pagination.SortBy != nil {
+		orderStatement := readDto.Pagination.SortBy.String()
+		orderStatement = strcase.ToSnake(orderStatement)
+		if orderStatement == "id" {
+			orderStatement = "ID"
+		}
+
+		if readDto.Pagination.SortDirection != nil {
+			orderStatement += " " + readDto.Pagination.SortDirection.String()
+		}
+
+		dbQuery = dbQuery.Order(orderStatement)
+	}
 
 	models := []dbModel.MarketplaceInstalledItem{}
-	err := repo.persistentDbSvc.Handler.
-		Model(&dbModel.MarketplaceInstalledItem{}).
-		Preload("Mappings").
-		Find(&models).Error
+	err = dbQuery.Preload("Mappings").Find(&models).Error
 	if err != nil {
-		return entities, errors.New("ReadDatabaseEntriesError")
+		return installedItemsDto, errors.New("ReadMarketplaceInstalledItemsError")
 	}
 
-	for _, installedItemModel := range models {
-		entity, err := installedItemModel.ToEntity()
+	var itemsTotal int64
+	err = dbQuery.Count(&itemsTotal).Error
+	if err != nil {
+		return installedItemsDto, errors.New(
+			"CountMarketplaceInstalledItemsTotalError: " + err.Error(),
+		)
+	}
+
+	entities := []entity.MarketplaceInstalledItem{}
+	for _, model := range models {
+		entity, err := model.ToEntity()
 		if err != nil {
 			slog.Error(
-				"MarketplaceInstalledItemModelToEntityError", slog.Any("error", err),
+				"MarketplaceInstalledItemModelToEntityError",
+				slog.Uint64("id", uint64(model.ID)), slog.Any("error", err),
 			)
 			continue
 		}
 
-		entities = append(
-			entities,
-			entity,
-		)
+		entities = append(entities, entity)
 	}
 
-	return entities, nil
+	itemsTotalUint := uint64(itemsTotal)
+	pagesTotal := uint32(
+		math.Ceil(float64(itemsTotal) / float64(readDto.Pagination.ItemsPerPage)),
+	)
+	responsePagination := dto.Pagination{
+		PageNumber:    readDto.Pagination.PageNumber,
+		ItemsPerPage:  readDto.Pagination.ItemsPerPage,
+		SortBy:        readDto.Pagination.SortBy,
+		SortDirection: readDto.Pagination.SortDirection,
+		PagesTotal:    &pagesTotal,
+		ItemsTotal:    &itemsTotalUint,
+	}
+
+	return dto.ReadMarketplaceInstalledItemsResponse{
+		Pagination: responsePagination,
+		Items:      entities,
+	}, nil
 }
 
 func (repo *MarketplaceQueryRepo) ReadInstalledItemById(

+ 1 - 1
src/infra/marketplace/marketplaceQueryRepo_test.go

@@ -26,7 +26,7 @@ func TestVirtualHostQueryRepo(t *testing.T) {
 
 		readDto := dto.ReadMarketplaceCatalogItemsRequest{
 			Pagination: paginationDto,
-			ItemType:   &itemType,
+			Type:       &itemType,
 		}
 
 		responseDto, err := marketplaceQueryRepo.ReadCatalogItems(readDto)

+ 9 - 8
src/presentation/api/controller/marketplace.go

@@ -35,10 +35,10 @@ func NewMarketplaceController(
 // @Security     Bearer
 // @Accept       json
 // @Produce      json
-// @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        id query  uint  false  "Id"
+// @Param        slug query  string  false  "Slug"
+// @Param        name query  string  false  "Name"
+// @Param        type 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)"
@@ -201,10 +201,11 @@ func (controller *MarketplaceController) InstallCatalogItem(c echo.Context) erro
 // @Security     Bearer
 // @Accept       json
 // @Produce      json
-// @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        id query  uint  false  "Id"
+// @Param        hostname query  string  false  "Hostname"
+// @Param        type query  string  false  "Type"
+// @Param        installationUuid query  string  false  "InstallUuid"
+// @Param        installedAt query  string  false  "CreatedAt"
 // @Param        pageNumber query  uint  false  "PageNumber (Pagination)"
 // @Param        itemsPerPage query  uint  false  "ItemsPerPage (Pagination)"
 // @Param        sortBy query  string  false  "SortBy (Pagination)"

+ 1 - 1
src/presentation/api/controller/services.go

@@ -263,7 +263,7 @@ func (controller *ServicesController) Delete(c echo.Context) error {
 }
 
 func (controller *ServicesController) AutoRefreshServicesItems() {
-	taskInterval := time.Duration(24) * time.Hour
+	taskInterval := time.Duration(2) * time.Minute
 	timer := time.NewTicker(taskInterval)
 	defer timer.Stop()
 

+ 24 - 1
src/presentation/cli/controller/marketplace.go

@@ -203,7 +203,8 @@ func (controller *MarketplaceController) InstallCatalogItem() *cobra.Command {
 
 func (controller *MarketplaceController) ReadInstalledItems() *cobra.Command {
 	var installedItemIdUint uint64
-	var installedItemTypeStr string
+	var installedItemHostnameStr, installedItemTypeStr, installedItemUuidStr string
+	var itemInstalledAt int64
 	var paginationPageNumberUint32 uint32
 	var paginationItemsPerPageUint16 uint16
 	var paginationSortByStr, paginationSortDirectionStr, paginationLastSeenIdStr string
@@ -218,10 +219,22 @@ func (controller *MarketplaceController) ReadInstalledItems() *cobra.Command {
 				requestBody["id"] = installedItemIdUint
 			}
 
+			if installedItemHostnameStr != "" {
+				requestBody["hostname"] = installedItemHostnameStr
+			}
+
 			if installedItemTypeStr != "" {
 				requestBody["type"] = installedItemTypeStr
 			}
 
+			if installedItemUuidStr != "" {
+				requestBody["installId"] = installedItemUuidStr
+			}
+
+			if itemInstalledAt != 0 {
+				requestBody["installedAt"] = itemInstalledAt
+			}
+
 			if paginationPageNumberUint32 != 0 {
 				requestBody["pageNumber"] = paginationPageNumberUint32
 			}
@@ -251,9 +264,19 @@ func (controller *MarketplaceController) ReadInstalledItems() *cobra.Command {
 	cmd.Flags().Uint64VarP(
 		&installedItemIdUint, "installed-item-id", "i", 0, "InstalledItemId",
 	)
+	cmd.Flags().StringVarP(
+		&installedItemHostnameStr, "installed-item-hostname", "n", "",
+		"InstalledItemHostname",
+	)
 	cmd.Flags().StringVarP(
 		&installedItemTypeStr, "installed-item-type", "t", "", "InstalledItemType",
 	)
+	cmd.Flags().StringVarP(
+		&installedItemUuidStr, "installed-item-uuid", "u", "", "InstalledItemUuidStr",
+	)
+	cmd.Flags().Int64VarP(
+		&itemInstalledAt, "item-installed-at", "b", 0, "ItemInstalledAt (UnixTime)",
+	)
 	cmd.Flags().Uint32VarP(
 		&paginationPageNumberUint32, "page-number", "p", 0, "PageNumber (Pagination)",
 	)

+ 39 - 7
src/presentation/service/marketplace.go

@@ -115,10 +115,10 @@ func (service *MarketplaceService) ReadCatalog(
 
 	readDto := dto.ReadMarketplaceCatalogItemsRequest{
 		Pagination: paginationDto,
-		ItemId:     idPtr,
-		ItemSlug:   slugPtr,
-		ItemName:   namePtr,
-		ItemType:   typePtr,
+		Id:         idPtr,
+		Slug:       slugPtr,
+		Name:       namePtr,
+		Type:       typePtr,
 	}
 
 	marketplaceQueryRepo := marketplaceInfra.NewMarketplaceQueryRepo(
@@ -259,6 +259,15 @@ func (service *MarketplaceService) ReadInstalledItems(
 		idPtr = &id
 	}
 
+	var hostnamePtr *valueObject.Fqdn
+	if input["hostname"] != nil {
+		hostname, err := valueObject.NewFqdn(input["hostname"])
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		hostnamePtr = &hostname
+	}
+
 	var typePtr *valueObject.MarketplaceItemType
 	if input["type"] != nil {
 		itemType, err := valueObject.NewMarketplaceItemType(input["type"])
@@ -268,6 +277,26 @@ func (service *MarketplaceService) ReadInstalledItems(
 		typePtr = &itemType
 	}
 
+	var installationUuidPtr *valueObject.MarketplaceInstalledItemUuid
+	if input["installationUuid"] != nil {
+		installationUuid, err := valueObject.NewMarketplaceInstalledItemUuid(
+			input["installationUuid"],
+		)
+		if err != nil {
+			return NewServiceOutput(UserError, err)
+		}
+		installationUuidPtr = &installationUuid
+	}
+
+	var installedAtPtr *valueObject.UnixTime
+	if input["installedAt"] != nil {
+		installedAt, err := valueObject.NewUnixTime(input["installedAt"])
+		if err != nil {
+			return NewServiceOutput(UserError, errors.New("InvalidInstalledAt"))
+		}
+		installedAtPtr = &installedAt
+	}
+
 	paginationDto := useCase.MarketplaceDefaultPagination
 	if input["pageNumber"] != nil {
 		pageNumber, err := voHelper.InterfaceToUint32(input["pageNumber"])
@@ -312,9 +341,12 @@ func (service *MarketplaceService) ReadInstalledItems(
 	}
 
 	readDto := dto.ReadMarketplaceInstalledItemsRequest{
-		Pagination: paginationDto,
-		ItemId:     idPtr,
-		ItemType:   typePtr,
+		Pagination:       paginationDto,
+		Id:               idPtr,
+		Hostname:         hostnamePtr,
+		Type:             typePtr,
+		InstallationUuid: installationUuidPtr,
+		InstalledAt:      installedAtPtr,
 	}
 
 	marketplaceQueryRepo := marketplaceInfra.NewMarketplaceQueryRepo(

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

@@ -75,8 +75,6 @@ func (presenter *MarketplacePresenter) catalogItemsGroupedByTypeFactory(
 func (presenter *MarketplacePresenter) marketplaceOverviewFactory(listType string) (
 	overview page.MarketplaceOverview, err error,
 ) {
-	var assertOk bool
-
 	installedItemsList := []entity.MarketplaceInstalledItem{}
 	if listType == "installed" {
 		responseOutput := presenter.marketplaceService.ReadInstalledItems(
@@ -86,10 +84,11 @@ func (presenter *MarketplacePresenter) marketplaceOverviewFactory(listType strin
 			return overview, errors.New("FailedToReadInstalledItems")
 		}
 
-		installedItemsList, assertOk = responseOutput.Body.([]entity.MarketplaceInstalledItem)
+		typedOutputBody, assertOk := responseOutput.Body.(dto.ReadMarketplaceInstalledItemsResponse)
 		if !assertOk {
 			return overview, errors.New("FailedToReadInstalledItems")
 		}
+		installedItemsList = typedOutputBody.Items
 	}
 
 	catalogItemsList := []entity.MarketplaceCatalogItem{}