Skip to content

Commit

Permalink
Merge pull request #355 from LerianStudio/feature/MIDAZ-349
Browse files Browse the repository at this point in the history
Feature/MIDAZ-349
  • Loading branch information
qnen authored Dec 3, 2024
2 parents 0309595 + fdd5971 commit 42940b2
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 44 deletions.
64 changes: 32 additions & 32 deletions components/ledger/internal/adapters/postgres/asset/asset.mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
//go:generate mockgen --destination=asset.mock.go --package=asset . Repository
type Repository interface {
Create(ctx context.Context, asset *mmodel.Asset) (*mmodel.Asset, error)
FindAll(ctx context.Context, organizationID, ledgerID uuid.UUID, limit, page int) ([]*mmodel.Asset, error)
FindAllWithDeleted(ctx context.Context, organizationID, ledgerID uuid.UUID, limit, page int) ([]*mmodel.Asset, error)
ListByIDs(ctx context.Context, organizationID, ledgerID uuid.UUID, ids []uuid.UUID) ([]*mmodel.Asset, error)
Find(ctx context.Context, organizationID, ledgerID, id uuid.UUID) (*mmodel.Asset, error)
FindByNameOrCode(ctx context.Context, organizationID, ledgerID uuid.UUID, name, code string) (bool, error)
Expand Down Expand Up @@ -164,8 +164,8 @@ func (r *AssetPostgreSQLRepository) FindByNameOrCode(ctx context.Context, organi
return false, nil
}

// FindAll retrieves Asset entities from the database.
func (r *AssetPostgreSQLRepository) FindAll(ctx context.Context, organizationID, ledgerID uuid.UUID, limit, page int) ([]*mmodel.Asset, error) {
// FindAllWithDeleted retrieves Asset entities from the database with soft-deleted records.
func (r *AssetPostgreSQLRepository) FindAllWithDeleted(ctx context.Context, organizationID, ledgerID uuid.UUID, limit, page int) ([]*mmodel.Asset, error) {
tracer := pkg.NewTracerFromContext(ctx)

ctx, span := tracer.Start(ctx, "postgres.find_all_assets")
Expand All @@ -184,7 +184,6 @@ func (r *AssetPostgreSQLRepository) FindAll(ctx context.Context, organizationID,
From(r.tableName).
Where(squirrel.Expr("organization_id = ?", organizationID)).
Where(squirrel.Expr("ledger_id = ?", ledgerID)).
Where(squirrel.Eq{"deleted_at": nil}).
OrderBy("created_at DESC").
Limit(pkg.SafeIntToUint64(limit)).
Offset(pkg.SafeIntToUint64((page - 1) * limit)).
Expand Down
3 changes: 2 additions & 1 deletion components/ledger/internal/services/command/create-asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package command

import (
"context"
"github.com/LerianStudio/midaz/pkg/constant"
"reflect"
"time"

Expand Down Expand Up @@ -94,7 +95,7 @@ func (uc *UseCase) CreateAsset(ctx context.Context, organizationID, ledgerID uui

inst.Metadata = metadata

aAlias := "@external/" + cii.Code
aAlias := constant.DefaultExternalAccountAliasPrefix + cii.Code
aStatusDescription := "Account external created by asset: " + cii.Code

account, err := uc.AccountRepo.ListAccountsByAlias(ctx, organizationID, ledgerID, []string{aAlias})
Expand Down
35 changes: 35 additions & 0 deletions components/ledger/internal/services/command/delete-asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,41 @@ func (uc *UseCase) DeleteAssetByID(ctx context.Context, organizationID, ledgerID

logger.Infof("Remove asset for id: %s", id)

asset, err := uc.AssetRepo.Find(ctx, organizationID, ledgerID, id)
if err != nil {
mopentelemetry.HandleSpanError(&span, "Failed to get asset on repo by id", err)

logger.Errorf("Error getting asset on repo by id: %v", err)

if errors.Is(err, services.ErrDatabaseItemNotFound) {
return pkg.ValidateBusinessError(constant.ErrAssetIDNotFound, reflect.TypeOf(mmodel.Asset{}).Name(), id)
}

return err
}

aAlias := constant.DefaultExternalAccountAliasPrefix + asset.Code

acc, err := uc.AccountRepo.ListAccountsByAlias(ctx, organizationID, ledgerID, []string{aAlias})
if err != nil {
mopentelemetry.HandleSpanError(&span, "Failed to retrieve asset external account", err)

logger.Errorf("Error retrieving asset external account: %v", err)

return err
}

if len(acc) > 0 {
err := uc.AccountRepo.Delete(ctx, organizationID, ledgerID, nil, uuid.MustParse(acc[0].ID))
if err != nil {
mopentelemetry.HandleSpanError(&span, "Failed to delete asset external account", err)

logger.Errorf("Error deleting asset external account: %v", err)

return err
}
}

if err := uc.AssetRepo.Delete(ctx, organizationID, ledgerID, id); err != nil {
mopentelemetry.HandleSpanError(&span, "Failed to delete asset on repo by id", err)

Expand Down
2 changes: 1 addition & 1 deletion components/ledger/internal/services/query/get-all-asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (uc *UseCase) GetAllAssets(ctx context.Context, organizationID, ledgerID uu

logger.Infof("Retrieving assets")

assets, err := uc.AssetRepo.FindAll(ctx, organizationID, ledgerID, filter.Limit, filter.Page)
assets, err := uc.AssetRepo.FindAllWithDeleted(ctx, organizationID, ledgerID, filter.Limit, filter.Page)
if err != nil {
mopentelemetry.HandleSpanError(&span, "Failed to get assets on repo", err)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ func TestGetAllAssets(t *testing.T) {
assets := []*mmodel.Asset{{}}
mockAssetRepo.
EXPECT().
FindAll(gomock.Any(), organizationID, ledgerID, page, limit).
FindAllWithDeleted(gomock.Any(), organizationID, ledgerID, page, limit).
Return(assets, nil).
Times(1)
res, err := uc.AssetRepo.FindAll(context.TODO(), organizationID, ledgerID, page, limit)
res, err := uc.AssetRepo.FindAllWithDeleted(context.TODO(), organizationID, ledgerID, page, limit)

assert.NoError(t, err)
assert.Len(t, res, 1)
Expand All @@ -46,10 +46,10 @@ func TestGetAllAssets(t *testing.T) {
errMsg := "errDatabaseItemNotFound"
mockAssetRepo.
EXPECT().
FindAll(gomock.Any(), organizationID, ledgerID, page, limit).
FindAllWithDeleted(gomock.Any(), organizationID, ledgerID, page, limit).
Return(nil, errors.New(errMsg)).
Times(1)
res, err := uc.AssetRepo.FindAll(context.TODO(), organizationID, ledgerID, page, limit)
res, err := uc.AssetRepo.FindAllWithDeleted(context.TODO(), organizationID, ledgerID, page, limit)

assert.EqualError(t, err, errMsg)
assert.Nil(t, res)
Expand Down
5 changes: 5 additions & 0 deletions pkg/constant/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package constant

const (
DefaultExternalAccountAliasPrefix = "@external/"
)
4 changes: 2 additions & 2 deletions pkg/mmodel/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type CreateAccountInput struct {
AssetCode string `json:"assetCode" validate:"required,max=100" example:"BRL"`
Name string `json:"name" validate:"max=256" example:"My Account"`
Alias *string `json:"alias" validate:"max=100,excludes=@external/" example:"@person1"`
Alias *string `json:"alias" validate:"max=100,prohibitedexternalaccountprefix" example:"@person1"`
Type string `json:"type" validate:"required" example:"creditCard"`
ParentAccountID *string `json:"parentAccountId" validate:"omitempty,uuid" example:"00000000-0000-0000-0000-000000000000"`
ProductID *string `json:"productId" validate:"omitempty,uuid" example:"00000000-0000-0000-0000-000000000000"`
Expand All @@ -34,7 +34,7 @@ type UpdateAccountInput struct {
Status Status `json:"status"`
AllowSending *bool `json:"allowSending" example:"true"`
AllowReceiving *bool `json:"allowReceiving" example:"true"`
Alias *string `json:"alias" validate:"max=100,excludes=@external/" example:"@person1"`
Alias *string `json:"alias" validate:"max=100,prohibitedexternalaccountprefix" example:"@person1"`
ProductID *string `json:"productId" validate:"uuid" example:"00000000-0000-0000-0000-000000000000"`
Metadata map[string]any `json:"metadata" validate:"dive,keys,keymax=100,endkeys,nonested,valuemax=2000"`
} // @name UpdateAccountInput
Expand Down
17 changes: 17 additions & 0 deletions pkg/net/http/withBody.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func newValidator() (*validator.Validate, ut.Translator) {
_ = v.RegisterValidation("nonested", validateMetadataNestedValues)
_ = v.RegisterValidation("valuemax", validateMetadataValueMaxLength)
_ = v.RegisterValidation("singletransactiontype", validateSingleTransactionType)
_ = v.RegisterValidation("prohibitedexternalaccountprefix", validateProhibitedExternalAccountPrefix)

_ = v.RegisterTranslation("required", trans, func(ut ut.Translator) error {
return ut.Add("required", "{0} is a required field", true)
Expand Down Expand Up @@ -271,6 +272,15 @@ func newValidator() (*validator.Validate, ut.Translator) {
return t
})

_ = v.RegisterTranslation("prohibitedexternalaccountprefix", trans, func(ut ut.Translator) error {
prefix := cn.DefaultExternalAccountAliasPrefix
return ut.Add("prohibitedexternalaccountprefix", "{0} cannot contain the text '"+prefix+"'", true)
}, func(ut ut.Translator, fe validator.FieldError) string {
t, _ := ut.T("prohibitedexternalaccountprefix", formatErrorFieldName(fe.Namespace()))

return t
})

return v, trans
}

Expand Down Expand Up @@ -349,6 +359,13 @@ func validateSingleTransactionType(fl validator.FieldLevel) bool {
return true
}

// validateProhibitedExternalAccountPrefix
func validateProhibitedExternalAccountPrefix(fl validator.FieldLevel) bool {
f := fl.Field().Interface().(string)

return !strings.Contains(f, cn.DefaultExternalAccountAliasPrefix)
}

// formatErrorFieldName formats metadata field error names for error messages
func formatErrorFieldName(text string) string {
re, _ := regexp.Compile(`\.(.+)$`)
Expand Down

0 comments on commit 42940b2

Please sign in to comment.