From 843b86e4ab1ccc890813234a81350c918e262713 Mon Sep 17 00:00:00 2001 From: Henrique Marlon Date: Sat, 16 Nov 2024 10:34:12 -0300 Subject: [PATCH] feat: change the structure of handlers and other changes --- internal/domain/entity/contracts.go | 16 ++-- internal/domain/entity/crowdfunding.go | 47 ++++++++--- internal/domain/entity/crowdfunding_test.go | 8 +- internal/domain/entity/order.go | 44 +++++++---- internal/domain/entity/order_test.go | 10 +-- internal/domain/entity/user.go | 55 ++++++++++--- .../advance_handler/order_advance_handlers.go | 79 ++++++++++--------- .../advance_handler/user_advance_handler.go | 4 + .../crowdfunding_inspect_handlers.go | 4 + ..._handlers.go => order_inspect_handlers.go} | 4 + .../crowdfunding_repository_sqlite.go | 4 + .../repository/order_repository_sqlite.go | 5 ++ .../repository/user_respository_sqlite.go | 37 +++++---- .../close_crowdfunding.go | 18 ++--- .../find_crowdfundings_by_investor.go | 1 + .../crowdfunding_usecase/general_dto.go | 8 +- .../usecase/order_usecase/create_order.go | 10 +-- .../order_usecase/find_orders_by_investors.go | 1 + internal/usecase/order_usecase/general_dto.go | 4 +- .../usecase/user_usecase/find_user_by_role.go | 19 ++--- internal/usecase/user_usecase/update_user.go | 1 + 21 files changed, 241 insertions(+), 138 deletions(-) rename internal/infra/cartesi/handler/inspect_handler/{bid_inspect_handlers.go => order_inspect_handlers.go} (94%) create mode 100644 internal/usecase/crowdfunding_usecase/find_crowdfundings_by_investor.go create mode 100644 internal/usecase/order_usecase/find_orders_by_investors.go create mode 100644 internal/usecase/user_usecase/update_user.go diff --git a/internal/domain/entity/contracts.go b/internal/domain/entity/contracts.go index 27b33f5..7281457 100644 --- a/internal/domain/entity/contracts.go +++ b/internal/domain/entity/contracts.go @@ -2,6 +2,7 @@ package entity import ( "errors" + "fmt" "github.com/ethereum/go-ethereum/common" ) @@ -20,11 +21,11 @@ type ContractRepository interface { } type Contract struct { - Id uint `json:"id" gorm:"primaryKey"` - Symbol string `json:"symbol,omitempty" gorm:"uniqueIndex;not null"` + Id uint `json:"id" gorm:"primaryKey"` + Symbol string `json:"symbol,omitempty" gorm:"uniqueIndex;not null"` Address common.Address `json:"address,omitempty" gorm:"type:text;not null"` - CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"` - UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` + CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"` + UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` } func NewContract(symbol string, address common.Address, createdAt int64) (*Contract, error) { @@ -40,8 +41,11 @@ func NewContract(symbol string, address common.Address, createdAt int64) (*Contr } func (c *Contract) Validate() error { - if c.Symbol == "" || c.Address == (common.Address{}) { - return ErrInvalidContract + if c.Symbol == "" { + return fmt.Errorf("%w: symbol cannot be empty", ErrInvalidContract) + } + if c.Address == (common.Address{}) { + return fmt.Errorf("%w: address cannot be empty", ErrInvalidContract) } return nil } diff --git a/internal/domain/entity/crowdfunding.go b/internal/domain/entity/crowdfunding.go index 7695f55..87fc13d 100644 --- a/internal/domain/entity/crowdfunding.go +++ b/internal/domain/entity/crowdfunding.go @@ -2,6 +2,7 @@ package entity import ( "errors" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" @@ -13,9 +14,19 @@ var ( ErrInvalidCrowdfunding = errors.New("invalid crowdfunding") ) +type CrowdfundingState string + +const ( + CrowdfundingStateOngoing CrowdfundingState = "ongoing" + CrowdfundingStateClosed CrowdfundingState = "closed" + CrowdfundingStateCanceled CrowdfundingState = "canceled" + CrowdfundingStateSettled CrowdfundingState = "settled" +) + type CrowdfundingRepository interface { CreateCrowdfunding(crowdfunding *Crowdfunding) (*Crowdfunding, error) FindCrowdfundingsByCreator(creator common.Address) ([]*Crowdfunding, error) + FindCrowdfundingsByInvestor(investor common.Address) ([]*Crowdfunding, error) FindCrowdfundingById(id uint) (*Crowdfunding, error) FindAllCrowdfundings() ([]*Crowdfunding, error) CloseCrowdfunding(id uint) ([]*Order, error) @@ -24,19 +35,11 @@ type CrowdfundingRepository interface { DeleteCrowdfunding(id uint) error } -type CrowdfundingState string - -const ( - CrowdfundingStateOngoing CrowdfundingState = "ongoing" - CrowdfundingStateClosed CrowdfundingState = "closed" - CrowdfundingStateSettled CrowdfundingState = "settled" -) - type Crowdfunding struct { Id uint `json:"id" gorm:"primaryKey"` Creator common.Address `json:"creator,omitempty" gorm:"type:text;not null"` - DebtIssued uint256.Int `json:"debt_issued,omitempty" gorm:"type:bigint;not null"` - MaxInterestRate uint256.Int `json:"max_interest_rate,omitempty" gorm:"type:bigint;not null"` + DebtIssued *uint256.Int `json:"debt_issued,omitempty" gorm:"type:bigint;not null"` + MaxInterestRate *uint256.Int `json:"max_interest_rate,omitempty" gorm:"type:bigint;not null"` State CrowdfundingState `json:"state,omitempty" gorm:"type:text;not null"` Orders []*Order `json:"orders,omitempty" gorm:"foreignKey:CrowdfundingId;constraint:OnDelete:CASCADE"` ExpiresAt int64 `json:"expires_at,omitempty" gorm:"not null"` @@ -44,7 +47,7 @@ type Crowdfunding struct { UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` } -func NewCrowdfunding(creator common.Address, debt_issued uint256.Int, maxInterestRate uint256.Int, expiresAt int64, createdAt int64) (*Crowdfunding, error) { +func NewCrowdfunding(creator common.Address, debt_issued *uint256.Int, maxInterestRate *uint256.Int, expiresAt int64, createdAt int64) (*Crowdfunding, error) { crowdfunding := &Crowdfunding{ Creator: creator, DebtIssued: debt_issued, @@ -60,8 +63,26 @@ func NewCrowdfunding(creator common.Address, debt_issued uint256.Int, maxInteres } func (a *Crowdfunding) Validate() error { - if a.Creator == (common.Address{}) || a.DebtIssued.Sign() == 0 || a.MaxInterestRate.Sign() == 0 || a.ExpiresAt == 0 || a.CreatedAt == 0 || a.CreatedAt >= a.ExpiresAt { - return ErrInvalidCrowdfunding + if a.Creator == (common.Address{}) { + return fmt.Errorf("%w: invalid creator address", ErrInvalidCrowdfunding) + } + if a.DebtIssued.Sign() == 0 { + return fmt.Errorf("%w: debt issued cannot be zero", ErrInvalidCrowdfunding) + } + if a.DebtIssued.Cmp(uint256.NewInt(15000000000)) > 0 { + return fmt.Errorf("%w: debt issued exceeds the maximum allowed value", ErrInvalidCrowdfunding) + } + if a.MaxInterestRate.Sign() == 0 { + return fmt.Errorf("%w: max interest rate cannot be zero", ErrInvalidCrowdfunding) + } + if a.ExpiresAt == 0 { + return fmt.Errorf("%w: expiration date is missing", ErrInvalidCrowdfunding) + } + if a.CreatedAt == 0 { + return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding) + } + if a.CreatedAt >= a.ExpiresAt { + return fmt.Errorf("%w: creation date cannot be greater than or equal to expiration date", ErrInvalidCrowdfunding) } return nil } diff --git a/internal/domain/entity/crowdfunding_test.go b/internal/domain/entity/crowdfunding_test.go index b701734..37c03b5 100644 --- a/internal/domain/entity/crowdfunding_test.go +++ b/internal/domain/entity/crowdfunding_test.go @@ -16,7 +16,7 @@ func TestNewCrowdfunding(t *testing.T) { createdAt := time.Now().Unix() expiresAt := createdAt + 3600 - crowdfunding, err := NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt) + crowdfunding, err := NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt) assert.NoError(t, err) assert.NotNil(t, crowdfunding) assert.Equal(t, *debt_issued, crowdfunding.DebtIssued) @@ -33,7 +33,7 @@ func TestNewCrowdfunding_Fail_InvalidCrowdfunding(t *testing.T) { createdAt := time.Now().Unix() expiresAt := createdAt + 3600 - crowdfunding, err := NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt) + crowdfunding, err := NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt) assert.Error(t, err) assert.Nil(t, crowdfunding) assert.Equal(t, ErrInvalidCrowdfunding, err) @@ -41,7 +41,7 @@ func TestNewCrowdfunding_Fail_InvalidCrowdfunding(t *testing.T) { debt_issued = uint256.NewInt(100) interestRate = uint256.NewInt(0) - crowdfunding, err = NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt) + crowdfunding, err = NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt) assert.Error(t, err) assert.Nil(t, crowdfunding) assert.Equal(t, ErrInvalidCrowdfunding, err) @@ -50,7 +50,7 @@ func TestNewCrowdfunding_Fail_InvalidCrowdfunding(t *testing.T) { interestRate = uint256.NewInt(50) expiresAt = createdAt - crowdfunding, err = NewCrowdfunding(creator, *debt_issued, *interestRate, expiresAt, createdAt) + crowdfunding, err = NewCrowdfunding(creator, debt_issued, interestRate, expiresAt, createdAt) assert.Error(t, err) assert.Nil(t, crowdfunding) assert.Equal(t, ErrInvalidCrowdfunding, err) diff --git a/internal/domain/entity/order.go b/internal/domain/entity/order.go index ccc1ca1..ce5f9bc 100644 --- a/internal/domain/entity/order.go +++ b/internal/domain/entity/order.go @@ -2,6 +2,7 @@ package entity import ( "errors" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/holiman/uint256" @@ -12,16 +13,6 @@ var ( ErrOrderNotFound = errors.New("order not found") ) -type OrderRepository interface { - CreateOrder(order *Order) (*Order, error) - FindOrdersByState(crowdfundingId uint, state string) ([]*Order, error) - FindOrderById(id uint) (*Order, error) - FindOrdersByCrowdfundingId(id uint) ([]*Order, error) - FindAllOrders() ([]*Order, error) - UpdateOrder(order *Order) (*Order, error) - DeleteOrder(id uint) error -} - type OrderState string const ( @@ -32,18 +23,29 @@ const ( OrderStatePaid OrderState = "paid" ) +type OrderRepository interface { + CreateOrder(order *Order) (*Order, error) + FindOrderById(id uint) (*Order, error) + FindOrdersByCrowdfundingId(id uint) ([]*Order, error) + FindOrdersByState(crowdfundingId uint, state string) ([]*Order, error) + FindOrdersByInvestor(investor common.Address) ([]*Order, error) + FindAllOrders() ([]*Order, error) + UpdateOrder(order *Order) (*Order, error) + DeleteOrder(id uint) error +} + type Order struct { Id uint `json:"id" gorm:"primaryKey"` CrowdfundingId uint `json:"crowdfunding_id" gorm:"not null;index"` Investor common.Address `json:"investor,omitempty" gorm:"not null"` - Amount uint256.Int `json:"amount,omitempty" gorm:"type:bigint;not null"` - InterestRate uint256.Int `json:"interest_rate,omitempty" gorm:"type:bigint;not null"` + Amount *uint256.Int `json:"amount,omitempty" gorm:"type:bigint;not null"` + InterestRate *uint256.Int `json:"interest_rate,omitempty" gorm:"type:bigint;not null"` State OrderState `json:"state,omitempty" gorm:"type:text;not null"` CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"` UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` } -func NewOrder(crowdfundingId uint, investor common.Address, amount uint256.Int, interestRate uint256.Int, createdAt int64) (*Order, error) { +func NewOrder(crowdfundingId uint, investor common.Address, amount *uint256.Int, interestRate *uint256.Int, createdAt int64) (*Order, error) { order := &Order{ CrowdfundingId: crowdfundingId, Investor: investor, @@ -59,8 +61,20 @@ func NewOrder(crowdfundingId uint, investor common.Address, amount uint256.Int, } func (b *Order) Validate() error { - if b.CrowdfundingId == 0 || b.Investor == (common.Address{}) || b.Amount.Sign() == 0 || b.InterestRate.Sign() == 0 { - return ErrInvalidOrder + if b.CrowdfundingId == 0 { + return fmt.Errorf("%w: crowdfunding ID cannot be zero", ErrInvalidOrder) + } + if b.Investor == (common.Address{}) { + return fmt.Errorf("%w: investor address cannot be empty", ErrInvalidOrder) + } + if b.Amount.Sign() == 0 { + return fmt.Errorf("%w: amount cannot be zero", ErrInvalidOrder) + } + if b.InterestRate.Sign() == 0 { + return fmt.Errorf("%w: interest rate cannot be zero", ErrInvalidOrder) + } + if b.CreatedAt == 0 { + return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding) } return nil } diff --git a/internal/domain/entity/order_test.go b/internal/domain/entity/order_test.go index a50abca..db64155 100644 --- a/internal/domain/entity/order_test.go +++ b/internal/domain/entity/order_test.go @@ -16,7 +16,7 @@ func TestNewOrder_Success(t *testing.T) { interestRate := uint256.NewInt(50) createdAt := time.Now().Unix() - order, err := NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt) + order, err := NewOrder(crowdfundingId, investor, amount, interestRate, createdAt) assert.NoError(t, err) assert.NotNil(t, order) assert.Equal(t, crowdfundingId, order.CrowdfundingId) @@ -34,7 +34,7 @@ func TestNewOrder_Fail_InvalidOrder(t *testing.T) { interestRate := uint256.NewInt(50) createdAt := time.Now().Unix() - order, err := NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt) + order, err := NewOrder(crowdfundingId, investor, amount, interestRate, createdAt) assert.Error(t, err) assert.Nil(t, order) assert.Equal(t, ErrInvalidOrder, err) @@ -42,7 +42,7 @@ func TestNewOrder_Fail_InvalidOrder(t *testing.T) { crowdfundingId = uint(1) investor = common.Address{} - order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt) + order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt) assert.Error(t, err) assert.Nil(t, order) assert.Equal(t, ErrInvalidOrder, err) @@ -50,7 +50,7 @@ func TestNewOrder_Fail_InvalidOrder(t *testing.T) { investor = common.HexToAddress("0x123") amount = uint256.NewInt(0) - order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt) + order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt) assert.Error(t, err) assert.Nil(t, order) assert.Equal(t, ErrInvalidOrder, err) @@ -58,7 +58,7 @@ func TestNewOrder_Fail_InvalidOrder(t *testing.T) { amount = uint256.NewInt(100) interestRate = uint256.NewInt(0) - order, err = NewOrder(crowdfundingId, investor, *amount, *interestRate, createdAt) + order, err = NewOrder(crowdfundingId, investor, amount, interestRate, createdAt) assert.Error(t, err) assert.Nil(t, order) assert.Equal(t, ErrInvalidOrder, err) diff --git a/internal/domain/entity/user.go b/internal/domain/entity/user.go index e7328eb..db9ac71 100644 --- a/internal/domain/entity/user.go +++ b/internal/domain/entity/user.go @@ -2,8 +2,10 @@ package entity import ( "errors" + "fmt" "github.com/ethereum/go-ethereum/common" + "github.com/holiman/uint256" ) var ( @@ -22,25 +24,30 @@ const ( type UserRepository interface { CreateUser(User *User) (*User, error) - FindUserByRole(role string) (*User, error) + FindUsersByRole(role string) ([]*User, error) FindUserByAddress(address common.Address) (*User, error) FindAllUsers() ([]*User, error) + UpdateUser(User *User) (*User, error) DeleteUser(address common.Address) error } type User struct { - Id uint `json:"id" gorm:"primaryKey"` - Role string `json:"role,omitempty" gorm:"not null"` - Address common.Address `json:"address,omitempty" gorm:"type:text;uniqueIndex;not null"` - CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"` - UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` + Id uint `json:"id" gorm:"primaryKey"` + Role string `json:"role,omitempty" gorm:"not null"` + Address common.Address `json:"address,omitempty" gorm:"type:text;uniqueIndex;not null"` + InvestmentLimit *uint256.Int `json:"investment_limit,omitempty" gorm:"type:bigint;not null"` + DebtIssuanceLimit *uint256.Int `json:"debt_issuance_limit,omitempty" gorm:"type:bigint;not null"` + CreatedAt int64 `json:"created_at,omitempty" gorm:"not null"` + UpdatedAt int64 `json:"updated_at,omitempty" gorm:"default:0"` } func NewUser(role string, address common.Address, created_at int64) (*User, error) { user := &User{ - Role: role, - Address: address, - CreatedAt: created_at, + Role: role, + InvestmentLimit: setInvestimentLimit(role), + DebtIssuanceLimit: setDebtIssuanceLimit(role), + Address: address, + CreatedAt: created_at, } if err := user.Validate(); err != nil { return nil, err @@ -49,8 +56,34 @@ func NewUser(role string, address common.Address, created_at int64) (*User, erro } func (u *User) Validate() error { - if u.Role == "" || u.Address == (common.Address{}) { - return ErrInvalidUser + if u.Role == "" { + return fmt.Errorf("%w: role cannot be empty", ErrInvalidUser) + } + if u.Address == (common.Address{}) { + return fmt.Errorf("%w: address cannot be empty", ErrInvalidUser) + } + if u.CreatedAt == 0 { + return fmt.Errorf("%w: creation date is missing", ErrInvalidCrowdfunding) } return nil } + +func setInvestimentLimit(role string) *uint256.Int { + switch role { + case string(UserRoleQualifiedInvestor): + return new(uint256.Int).SetAllOne() //According to CVM Resolution 88 + case string(UserRoleNonQualifiedInvestor): + return uint256.NewInt(20000) //According to CVM Resolution 88 + default: + return uint256.NewInt(0) + } +} + +func setDebtIssuanceLimit(role string) *uint256.Int { + switch role { + case string(UserRoleCreator): + return uint256.NewInt(15000000) //According to CVM Resolution 88 + default: + return uint256.NewInt(0) + } +} diff --git a/internal/infra/cartesi/handler/advance_handler/order_advance_handlers.go b/internal/infra/cartesi/handler/advance_handler/order_advance_handlers.go index 2a88de5..84fdee7 100644 --- a/internal/infra/cartesi/handler/advance_handler/order_advance_handlers.go +++ b/internal/infra/cartesi/handler/advance_handler/order_advance_handlers.go @@ -1,14 +1,14 @@ package advance_handler import ( - "encoding/json" - "fmt" + // "encoding/json" + // "fmt" "github.com/rollmelette/rollmelette" "github.com/tribeshq/tribes/internal/domain/entity" - "github.com/tribeshq/tribes/internal/usecase/contract_usecase" - "github.com/tribeshq/tribes/internal/usecase/order_usecase" - "github.com/tribeshq/tribes/internal/usecase/user_usecase" + // "github.com/tribeshq/tribes/internal/usecase/contract_usecase" + // "github.com/tribeshq/tribes/internal/usecase/order_usecase" + // "github.com/tribeshq/tribes/internal/usecase/user_usecase" ) type OrderAdvanceHandlers struct { @@ -28,39 +28,40 @@ func NewOrderAdvanceHandlers(orderRepository entity.OrderRepository, userReposit } func (h *OrderAdvanceHandlers) CreateOrderHandler(env rollmelette.Env, metadata rollmelette.Metadata, deposit rollmelette.Deposit, payload []byte) error { - switch deposit := deposit.(type) { - case *rollmelette.ERC20Deposit: - var input order_usecase.CreateOrderInputDTO - if err := json.Unmarshal(payload, &input); err != nil { - return err - } - createOrder := order_usecase.NewCreateOrderUseCase(h.OrderRepository, h.ContractRepository, h.CrowdfundingRepository) - res, err := createOrder.Execute(&input, deposit, metadata) - if err != nil { - return err - } + // switch deposit := deposit.(type) { + // case *rollmelette.ERC20Deposit: + // var input order_usecase.CreateOrderInputDTO + // if err := json.Unmarshal(payload, &input); err != nil { + // return err + // } + // createOrder := order_usecase.NewCreateOrderUseCase(h.OrderRepository, h.ContractRepository, h.CrowdfundingRepository) + // res, err := createOrder.Execute(&input, deposit, metadata) + // if err != nil { + // return err + // } - findContractBySymbol := contract_usecase.NewFindContractBySymbolUseCase(h.ContractRepository) - stablecoin, err := findContractBySymbol.Execute(&contract_usecase.FindContractBySymbolInputDTO{Symbol: "STABLECOIN"}) - if err != nil { - return err - } - findUserByRole := user_usecase.NewFindUserByRoleUseCase(h.UserRepository) - crowdfundingeer, err := findUserByRole.Execute(&user_usecase.FindUserByRoleInputDTO{Role: "crowdfundingeer"}) - if err != nil { - return err - } + // findContractBySymbol := contract_usecase.NewFindContractBySymbolUseCase(h.ContractRepository) + // stablecoin, err := findContractBySymbol.Execute(&contract_usecase.FindContractBySymbolInputDTO{Symbol: "STABLECOIN"}) + // if err != nil { + // return err + // } + // findUserByRole := user_usecase.NewFindUserByRoleUseCase(h.UserRepository) + // crowdfundingeer, err := findUserByRole.Execute(&user_usecase.FindUserByRoleInputDTO{Role: "crowdfundingeer"}) + // if err != nil { + // return err + // } - if err := env.ERC20Transfer(stablecoin.Address, res.Investor, crowdfundingeer.Address, res.Amount.ToBig()); err != nil { - return err - } - order, err := json.Marshal(res) - if err != nil { - return err - } - env.Notice(append([]byte("order created - "), order...)) - return nil - default: - return fmt.Errorf("unsupported deposit type") - } -} + // if err := env.ERC20Transfer(stablecoin.Address, res.Investor, crowdfundingeer.Address, res.Amount.ToBig()); err != nil { + // return err + // } + // order, err := json.Marshal(res) + // if err != nil { + // return err + // } + // env.Notice(append([]byte("order created - "), order...)) + // return nil + // default: + // return fmt.Errorf("unsupported deposit type") + // } + return nil +} \ No newline at end of file diff --git a/internal/infra/cartesi/handler/advance_handler/user_advance_handler.go b/internal/infra/cartesi/handler/advance_handler/user_advance_handler.go index f86ac85..1c1ca57 100644 --- a/internal/infra/cartesi/handler/advance_handler/user_advance_handler.go +++ b/internal/infra/cartesi/handler/advance_handler/user_advance_handler.go @@ -40,6 +40,10 @@ func (h *UserAdvanceHandlers) CreateUserHandler(env rollmelette.Env, metadata ro return nil } +func (h *UserAdvanceHandlers) UpdateUserHandler(env rollmelette.Env, metadata rollmelette.Metadata, deposit rollmelette.Deposit, payload []byte) error { + return nil +} + func (h *UserAdvanceHandlers) DeleteUserHandler(env rollmelette.Env, metadata rollmelette.Metadata, deposit rollmelette.Deposit, payload []byte) error { var input user_usecase.DeleteUserInputDTO if err := json.Unmarshal(payload, &input); err != nil { diff --git a/internal/infra/cartesi/handler/inspect_handler/crowdfunding_inspect_handlers.go b/internal/infra/cartesi/handler/inspect_handler/crowdfunding_inspect_handlers.go index 1db4337..413d6ea 100644 --- a/internal/infra/cartesi/handler/inspect_handler/crowdfunding_inspect_handlers.go +++ b/internal/infra/cartesi/handler/inspect_handler/crowdfunding_inspect_handlers.go @@ -55,3 +55,7 @@ func (h *CrowdfundingInspectHandlers) FindAllCrowdfundingsHandler(env rollmelett env.Report(allCrowdfundings) return nil } + +func (h *CrowdfundingInspectHandlers) FindCrowdfundingsByInvestorHandler(env rollmelette.EnvInspector, ctx context.Context) error { + return nil +} \ No newline at end of file diff --git a/internal/infra/cartesi/handler/inspect_handler/bid_inspect_handlers.go b/internal/infra/cartesi/handler/inspect_handler/order_inspect_handlers.go similarity index 94% rename from internal/infra/cartesi/handler/inspect_handler/bid_inspect_handlers.go rename to internal/infra/cartesi/handler/inspect_handler/order_inspect_handlers.go index 57c75a1..bf3a1f0 100644 --- a/internal/infra/cartesi/handler/inspect_handler/bid_inspect_handlers.go +++ b/internal/infra/cartesi/handler/inspect_handler/order_inspect_handlers.go @@ -75,3 +75,7 @@ func (h *OrderInspectHandlers) FindAllOrdersHandler(env rollmelette.EnvInspector env.Report(allOrders) return nil } + +func (h *OrderInspectHandlers) FindOrdersByInvestorHandler(env rollmelette.EnvInspector, ctx context.Context) error { + return nil +} diff --git a/internal/infra/repository/crowdfunding_repository_sqlite.go b/internal/infra/repository/crowdfunding_repository_sqlite.go index bd8cba8..ce7c649 100644 --- a/internal/infra/repository/crowdfunding_repository_sqlite.go +++ b/internal/infra/repository/crowdfunding_repository_sqlite.go @@ -39,6 +39,10 @@ func (r *CrowdfundingRepositorySqlite) FindCrowdfundingsByCreator(creator common return crowdfundings, nil } +func (r *CrowdfundingRepositorySqlite) FindCrowdfundingsByInvestor(investor common.Address) ([]*entity.Crowdfunding, error) { + return nil, nil +} + func (r *CrowdfundingRepositorySqlite) FindCrowdfundingById(id uint) (*entity.Crowdfunding, error) { var crowdfunding entity.Crowdfunding err := r.Db.Preload("Orders").First(&crowdfunding, id).Error diff --git a/internal/infra/repository/order_repository_sqlite.go b/internal/infra/repository/order_repository_sqlite.go index 73999a9..b14b8e5 100644 --- a/internal/infra/repository/order_repository_sqlite.go +++ b/internal/infra/repository/order_repository_sqlite.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" + "github.com/ethereum/go-ethereum/common" "github.com/tribeshq/tribes/internal/domain/entity" "gorm.io/gorm" ) @@ -35,6 +36,10 @@ func (r *OrderRepositorySqlite) FindOrdersByState(crowdfundingId uint, state str return orders, nil } +func (r *OrderRepositorySqlite) FindOrdersByInvestor(investor common.Address) ([]*entity.Order, error) { + return nil, nil +} + func (r *OrderRepositorySqlite) FindOrderById(id uint) (*entity.Order, error) { var order entity.Order err := r.Db.First(&order, "order_id = ?", id).Error diff --git a/internal/infra/repository/user_respository_sqlite.go b/internal/infra/repository/user_respository_sqlite.go index 1b22dfd..59442d6 100644 --- a/internal/infra/repository/user_respository_sqlite.go +++ b/internal/infra/repository/user_respository_sqlite.go @@ -67,22 +67,23 @@ func (r *UserRepositorySqlite) FindUserByAddress(address common.Address) (*entit }, nil } -func (r *UserRepositorySqlite) FindUserByRole(role string) (*entity.User, error) { - var result map[string]interface{} - err := r.Db.Raw("SELECT id, role, address, created_at, updated_at FROM users WHERE role = ? LIMIT 1", role).Scan(&result).Error - if err != nil { - if err == gorm.ErrRecordNotFound { - return nil, entity.ErrCrowdfundingNotFound - } - return nil, err - } - return &entity.User{ - Id: uint(result["id"].(int64)), - Role: result["role"].(string), - Address: common.HexToAddress(result["address"].(string)), - CreatedAt: result["created_at"].(int64), - UpdatedAt: result["updated_at"].(int64), - }, nil +func (r *UserRepositorySqlite) FindUsersByRole(role string) ([]*entity.User, error) { + // var result map[string]interface{} + // err := r.Db.Raw("SELECT id, role, address, created_at, updated_at FROM users WHERE role = ? LIMIT 1", role).Scan(&result).Error + // if err != nil { + // if err == gorm.ErrRecordNotFound { + // return nil, entity.ErrCrowdfundingNotFound + // } + // return nil, err + // } + // return &entity.User{ + // Id: uint(result["id"].(int64)), + // Role: result["role"].(string), + // Address: common.HexToAddress(result["address"].(string)), + // CreatedAt: result["created_at"].(int64), + // UpdatedAt: result["updated_at"].(int64), + // }, nil + return nil, nil } func (r *UserRepositorySqlite) FindAllUsers() ([]*entity.User, error) { @@ -105,6 +106,10 @@ func (r *UserRepositorySqlite) FindAllUsers() ([]*entity.User, error) { return users, nil } +func (r *UserRepositorySqlite) UpdateUser(input *entity.User) (*entity.User, error) { + return nil, nil +} + func (r *UserRepositorySqlite) DeleteUser(address common.Address) error { res := r.Db.Delete(&entity.User{}, "address = ?", address.String()) if res.Error != nil { diff --git a/internal/usecase/crowdfunding_usecase/close_crowdfunding.go b/internal/usecase/crowdfunding_usecase/close_crowdfunding.go index d6b589a..24dc7b2 100644 --- a/internal/usecase/crowdfunding_usecase/close_crowdfunding.go +++ b/internal/usecase/crowdfunding_usecase/close_crowdfunding.go @@ -17,8 +17,8 @@ type FinishCrowdfundingInputDTO struct { type FinishCrowdfundingOutputDTO struct { Id uint `json:"id"` Creator common.Address `json:"creator,omitempty"` - DebtIssued uint256.Int `json:"debt_issued,omitempty"` - MaxInterestRate uint256.Int `json:"max_interest_rate,omitempty"` + DebtIssued *uint256.Int `json:"debt_issued,omitempty"` + MaxInterestRate *uint256.Int `json:"max_interest_rate,omitempty"` State string `json:"state,omitempty"` Orders []*entity.Order `json:"orders,omitempty"` ExpiresAt int64 `json:"expires_at,omitempty"` @@ -80,10 +80,10 @@ func (u *FinishCrowdfundingUseCase) Execute(input *FinishCrowdfundingInputDTO, m } sort.Slice(orders, func(i, j int) bool { - return orders[i].InterestRate.Cmp(&orders[j].InterestRate) < 0 + return orders[i].InterestRate.Cmp(orders[j].InterestRate) < 0 }) - debtIssuedRemaining := new(uint256.Int).Set(&activeCrowdfunding.DebtIssued) + debtIssuedRemaining := new(uint256.Int).Set(activeCrowdfunding.DebtIssued) for _, order := range orders { if debtIssuedRemaining.IsZero() { @@ -96,20 +96,20 @@ func (u *FinishCrowdfundingUseCase) Execute(input *FinishCrowdfundingInputDTO, m continue } - if debtIssuedRemaining.Gt(&order.Amount) { + if debtIssuedRemaining.Gt(order.Amount) { order.State = "accepted" order.UpdatedAt = metadata.BlockTimestamp _, err := u.OrderRepository.UpdateOrder(order) if err != nil { return nil, err } - debtIssuedRemaining.Sub(debtIssuedRemaining, &order.Amount) + debtIssuedRemaining.Sub(debtIssuedRemaining, order.Amount) } else { partiallyAcceptedAmount := new(uint256.Int).Set(debtIssuedRemaining) _, err := u.OrderRepository.CreateOrder(&entity.Order{ CrowdfundingId: order.CrowdfundingId, Investor: order.Investor, - Amount: *partiallyAcceptedAmount, + Amount: partiallyAcceptedAmount, InterestRate: order.InterestRate, State: "partially_accepted", CreatedAt: metadata.BlockTimestamp, @@ -119,11 +119,11 @@ func (u *FinishCrowdfundingUseCase) Execute(input *FinishCrowdfundingInputDTO, m return nil, err } - rejectedAmount := new(uint256.Int).Sub(&order.Amount, partiallyAcceptedAmount) + rejectedAmount := new(uint256.Int).Sub(order.Amount, partiallyAcceptedAmount) _, err = u.OrderRepository.CreateOrder(&entity.Order{ CrowdfundingId: order.CrowdfundingId, Investor: order.Investor, - Amount: *rejectedAmount, + Amount: rejectedAmount, InterestRate: order.InterestRate, State: "rejected", CreatedAt: metadata.BlockTimestamp, diff --git a/internal/usecase/crowdfunding_usecase/find_crowdfundings_by_investor.go b/internal/usecase/crowdfunding_usecase/find_crowdfundings_by_investor.go new file mode 100644 index 0000000..840784a --- /dev/null +++ b/internal/usecase/crowdfunding_usecase/find_crowdfundings_by_investor.go @@ -0,0 +1 @@ +package crowdfunding_usecase \ No newline at end of file diff --git a/internal/usecase/crowdfunding_usecase/general_dto.go b/internal/usecase/crowdfunding_usecase/general_dto.go index 6763e81..74bfbc5 100644 --- a/internal/usecase/crowdfunding_usecase/general_dto.go +++ b/internal/usecase/crowdfunding_usecase/general_dto.go @@ -8,8 +8,8 @@ import ( type FindCrowdfundingOutputDTO struct { Id uint `json:"id"` Creator common.Address `json:"creator"` - DebtIssued uint256.Int `json:"debt_issued"` - MaxInterestRate uint256.Int `json:"max_interest_rate"` + DebtIssued *uint256.Int `json:"debt_issued"` + MaxInterestRate *uint256.Int `json:"max_interest_rate"` State string `json:"state"` Orders []*FindCrowdfundingOutputSubDTO `json:"orders"` ExpiresAt int64 `json:"expires_at"` @@ -21,8 +21,8 @@ type FindCrowdfundingOutputSubDTO struct { Id uint `json:"id"` CrowdfundingId uint `json:"crowdfunding_id"` Investor common.Address `json:"investor"` - Amount uint256.Int `json:"amount"` - InterestRate uint256.Int `json:"interest_rate"` + Amount *uint256.Int `json:"amount"` + InterestRate *uint256.Int `json:"interest_rate"` State string `json:"state"` CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` diff --git a/internal/usecase/order_usecase/create_order.go b/internal/usecase/order_usecase/create_order.go index 053630d..ca5bbf9 100644 --- a/internal/usecase/order_usecase/create_order.go +++ b/internal/usecase/order_usecase/create_order.go @@ -11,15 +11,15 @@ import ( type CreateOrderInputDTO struct { Creator common.Address `json:"creator"` - Price uint256.Int `json:"interest_rate"` + Price *uint256.Int `json:"interest_rate"` } type CreateOrderOutputDTO struct { Id uint `json:"id"` CrowdfundingId uint `json:"crowdfunding_id"` Investor common.Address `json:"investor"` - Amount uint256.Int `json:"amount"` - InterestRate uint256.Int `json:"interest_rate"` + Amount *uint256.Int `json:"amount"` + InterestRate *uint256.Int `json:"interest_rate"` State string `json:"state"` CreatedAt int64 `json:"created_at"` } @@ -64,11 +64,11 @@ func (c *CreateOrderUseCase) Execute(input *CreateOrderInputDTO, deposit rollmel return nil, fmt.Errorf("invalid contract address provided for order creation: %v", deposit.(*rollmelette.ERC20Deposit).Token) } - if input.Price.Gt(&activeCrowdfunding.MaxInterestRate) { + if input.Price.Gt(activeCrowdfunding.MaxInterestRate) { return nil, fmt.Errorf("order price exceeds active crowdfunding max interest rate") } - order, err := entity.NewOrder(activeCrowdfunding.Id, deposit.(*rollmelette.ERC20Deposit).Sender, *uint256.MustFromBig(deposit.(*rollmelette.ERC20Deposit).Amount), input.Price, metadata.BlockTimestamp) + order, err := entity.NewOrder(activeCrowdfunding.Id, deposit.(*rollmelette.ERC20Deposit).Sender, uint256.MustFromBig(deposit.(*rollmelette.ERC20Deposit).Amount), input.Price, metadata.BlockTimestamp) if err != nil { return nil, err } diff --git a/internal/usecase/order_usecase/find_orders_by_investors.go b/internal/usecase/order_usecase/find_orders_by_investors.go new file mode 100644 index 0000000..58044d9 --- /dev/null +++ b/internal/usecase/order_usecase/find_orders_by_investors.go @@ -0,0 +1 @@ +package order_usecase \ No newline at end of file diff --git a/internal/usecase/order_usecase/general_dto.go b/internal/usecase/order_usecase/general_dto.go index 44f063f..fd4d77a 100644 --- a/internal/usecase/order_usecase/general_dto.go +++ b/internal/usecase/order_usecase/general_dto.go @@ -9,8 +9,8 @@ type FindOrderOutputDTO struct { Id uint `json:"id"` CrowdfundingId uint `json:"crowdfunding_id"` Investor common.Address `json:"investor"` - Amount uint256.Int `json:"amount"` - InterestRate uint256.Int `json:"interest_rate"` + Amount *uint256.Int `json:"amount"` + InterestRate *uint256.Int `json:"interest_rate"` State string `json:"state"` CreatedAt int64 `json:"created_at"` UpdatedAt int64 `json:"updated_at"` diff --git a/internal/usecase/user_usecase/find_user_by_role.go b/internal/usecase/user_usecase/find_user_by_role.go index e3e71c3..9780438 100644 --- a/internal/usecase/user_usecase/find_user_by_role.go +++ b/internal/usecase/user_usecase/find_user_by_role.go @@ -18,16 +18,17 @@ func NewFindUserByRoleUseCase(userRepository entity.UserRepository) *FindUserByR } } -func (u *FindUserByRoleUseCase) Execute(input *FindUserByRoleInputDTO) (*FindUserOutputDTO, error) { - res, err := u.userRepository.FindUserByRole(input.Role) +func (u *FindUserByRoleUseCase) Execute(input *FindUserByRoleInputDTO) ([]*FindUserOutputDTO, error) { + _, err := u.userRepository.FindUsersByRole(input.Role) if err != nil { return nil, err } - return &FindUserOutputDTO{ - Id: res.Id, - Role: res.Role, - Address: res.Address, - CreatedAt: res.CreatedAt, - UpdatedAt: res.UpdatedAt, - }, nil + // return &FindUserOutputDTO{ + // Id: res.Id, + // Role: res.Role, + // Address: res.Address, + // CreatedAt: res.CreatedAt, + // UpdatedAt: res.UpdatedAt, + // }, nil + return nil, nil } diff --git a/internal/usecase/user_usecase/update_user.go b/internal/usecase/user_usecase/update_user.go new file mode 100644 index 0000000..ade5c41 --- /dev/null +++ b/internal/usecase/user_usecase/update_user.go @@ -0,0 +1 @@ +package user_usecase \ No newline at end of file