From 69aa14bed175b588a2f796354427128946503b3a Mon Sep 17 00:00:00 2001 From: optclblast Date: Tue, 28 May 2024 23:14:15 +0300 Subject: [PATCH] tmp --- .../interface/rest/controllers/chain.go | 39 ++++++++- .../interface/rest/controllers/multisig.go | 30 ------- backend/internal/interface/rest/domain/dto.go | 5 ++ .../internal/interface/rest/presenters/tx.go | 47 ++++++++++- backend/internal/interface/rest/server.go | 4 + backend/internal/pkg/models/models.go | 2 + .../usecase/interactors/chain/chain.go | 50 +++++++++++ .../repository/transactions/repository.go | 84 +++++++++++++++++++ backend/migrations/blockd.sql | 2 - 9 files changed, 227 insertions(+), 36 deletions(-) delete mode 100644 backend/internal/interface/rest/controllers/multisig.go diff --git a/backend/internal/interface/rest/controllers/chain.go b/backend/internal/interface/rest/controllers/chain.go index 5bbf49a..818898a 100644 --- a/backend/internal/interface/rest/controllers/chain.go +++ b/backend/internal/interface/rest/controllers/chain.go @@ -340,10 +340,43 @@ func (c *transactionsController) NewPayroll(w http.ResponseWriter, r *http.Reque return presenters.ResponseOK() } -func (c *transactionsController) ConfirmPayroll(w http.ResponseWriter, r *http.Request) ([]byte, error) { - return nil, nil +func (c *transactionsController) ListPayrolls(w http.ResponseWriter, r *http.Request) ([]byte, error) { + req, err := presenters.CreateRequest[domain.ListPayrollsRequest](r) + if err != nil { + return nil, fmt.Errorf("error build request. %w", err) + } + + ctx, cancel := context.WithTimeout(r.Context(), time.Second*5) + defer cancel() + + organizationID, err := ctxmeta.OrganizationId(ctx) + if err != nil { + return nil, fmt.Errorf("erropr fetch organization id from context. %w", err) + } + + ids := make(uuid.UUIDs, len(req.IDs)) + for i, idStr := range req.IDs { + id, err := uuid.Parse(idStr) + if err != nil { + return nil, fmt.Errorf("error parse payroll id. %w", err) + } + + ids[i] = id + } + + payrolls, err := c.chainInteractor.ListPayrolls(ctx, chain.ListPayrollsParams{ + OrganizationID: organizationID, + IDs: ids, + Limit: int(req.Limit), + }) + if err != nil { + return nil, fmt.Errorf("error fetch payrolls. %w", err) + } + + return c.txPresenter.ResponsePayrolls(ctx, payrolls) } -func (c *transactionsController) ListPayrolls(w http.ResponseWriter, r *http.Request) ([]byte, error) { +func (c *transactionsController) ConfirmPayroll(w http.ResponseWriter, r *http.Request) ([]byte, error) { + return nil, nil } diff --git a/backend/internal/interface/rest/controllers/multisig.go b/backend/internal/interface/rest/controllers/multisig.go deleted file mode 100644 index 46201a1..0000000 --- a/backend/internal/interface/rest/controllers/multisig.go +++ /dev/null @@ -1,30 +0,0 @@ -package controllers - -import ( - "fmt" - "log/slog" - "net/http" - - "github.com/emochka2007/block-accounting/internal/interface/rest/domain" - "github.com/emochka2007/block-accounting/internal/interface/rest/presenters" - "github.com/emochka2007/block-accounting/internal/usecase/interactors/chain" -) - -type MultisigController interface { -} - -type multisigController struct { - log *slog.Logger - chainInteractor chain.ChainInteractor -} - -func (c *multisigController) New(w http.ResponseWriter, r *http.Request) ([]byte, error) { - req, err := presenters.CreateRequest[domain.NewMultisigRequest](r) - if err != nil { - return nil, fmt.Errorf("error build new multisig request. %w", err) - } - - c.log.Debug("new_multisig", slog.Any("request", req)) - - panic("implement me!") -} diff --git a/backend/internal/interface/rest/domain/dto.go b/backend/internal/interface/rest/domain/dto.go index f1fcbf0..040fd87 100644 --- a/backend/internal/interface/rest/domain/dto.go +++ b/backend/internal/interface/rest/domain/dto.go @@ -120,3 +120,8 @@ type NewPayrollRequest struct { MultisigID string `json:"multisig_id"` Title string `json:"title"` } + +type ListPayrollsRequest struct { + IDs []string `json:"ids"` + Limit uint8 `json:"limit"` +} diff --git a/backend/internal/interface/rest/presenters/tx.go b/backend/internal/interface/rest/presenters/tx.go index d8439b2..f46469c 100644 --- a/backend/internal/interface/rest/presenters/tx.go +++ b/backend/internal/interface/rest/presenters/tx.go @@ -26,6 +26,8 @@ type TransactionsPresenter interface { ResponseListTransactions(ctx context.Context, txs []*models.Transaction, cursor string) ([]byte, error) ResponseMultisigs(ctx context.Context, msgs []models.Multisig) ([]byte, error) + + ResponsePayrolls(ctx context.Context, payrolls []models.Payroll) ([]byte, error) } type transactionsPresenter struct { @@ -223,7 +225,50 @@ func (c *transactionsPresenter) ResponseMultisigs(ctx context.Context, msgs []mo out, err := json.Marshal(r) if err != nil { - return nil, fmt.Errorf("error marshal tx to hal resource. %w", err) + return nil, fmt.Errorf("error marshal multisigs to hal resource. %w", err) + } + + return out, nil +} + +type Payroll struct { + ID string `json:"id"` + Title string `json:"title"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} + +func (c *transactionsPresenter) ResponsePayrolls( + ctx context.Context, + payrolls []models.Payroll, +) ([]byte, error) { + organizationID, err := ctxmeta.OrganizationId(ctx) + if err != nil { + return nil, fmt.Errorf("error fetch organization id from context. %w", err) + } + + outArray := make([]Payroll, len(payrolls)) + + for i, pr := range payrolls { + outArray[i] = Payroll{ + ID: pr.ID.String(), + Title: pr.Title, + CreatedAt: pr.CreatedAt.UnixMilli(), + UpdatedAt: pr.UpdatedAt.UnixMilli(), + } + } + + txsResource := map[string]any{"payrolls": outArray} + + r := hal.NewResource( + txsResource, + "/organizations/"+organizationID.String()+"/payrolls", + hal.WithType("paurolls"), + ) + + out, err := json.Marshal(r) + if err != nil { + return nil, fmt.Errorf("error marshal payrolls to hal resource. %w", err) } return out, nil diff --git a/backend/internal/interface/rest/server.go b/backend/internal/interface/rest/server.go index 809cdca..d3fe156 100644 --- a/backend/internal/interface/rest/server.go +++ b/backend/internal/interface/rest/server.go @@ -111,6 +111,10 @@ func (s *Server) buildRouter() { r.Route("/payrolls", func(r chi.Router) { r.Get("/", s.handle(s.controllers.Transactions.ListPayrolls, "list_payrolls")) r.Post("/", s.handle(s.controllers.Transactions.NewPayroll, "new_payroll")) + r.Put("/", s.handle(s.controllers.Transactions.ConfirmPayroll, "confirm_payroll")) + + r.Post("/salaries", s.handle(nil, "set_salary")) + r.Get("/salaries", s.handle(nil, "get_salaries")) }) r.Route("/multisig", func(r chi.Router) { diff --git a/backend/internal/pkg/models/models.go b/backend/internal/pkg/models/models.go index e28886a..4e1c4d9 100644 --- a/backend/internal/pkg/models/models.go +++ b/backend/internal/pkg/models/models.go @@ -30,4 +30,6 @@ type Payroll struct { Address []byte OrganizationID uuid.UUID MultisigID uuid.UUID + CreatedAt time.Time + UpdatedAt time.Time } diff --git a/backend/internal/usecase/interactors/chain/chain.go b/backend/internal/usecase/interactors/chain/chain.go index e97388d..39946b7 100644 --- a/backend/internal/usecase/interactors/chain/chain.go +++ b/backend/internal/usecase/interactors/chain/chain.go @@ -26,6 +26,7 @@ type ChainInteractor interface { ListMultisigs(ctx context.Context, params ListMultisigsParams) ([]models.Multisig, error) PayrollDeploy(ctx context.Context, params PayrollDeployParams) error + ListPayrolls(ctx context.Context, params ListPayrollsParams) ([]models.Payroll, error) } type chainInteractor struct { @@ -428,6 +429,11 @@ func (i *chainInteractor) PayrollDeploy( return } + i.log.Debug( + "payroll deploy", + slog.Any("response", respObject), + ) + if respObject.Address == "" { i.log.Error( "error multisig address is empty", @@ -479,3 +485,47 @@ func (i *chainInteractor) ListMultisigs( return multisigs, nil } + +type ListPayrollsParams struct { + IDs []uuid.UUID + Limit int + OrganizationID uuid.UUID +} + +func (i *chainInteractor) ListPayrolls( + ctx context.Context, + params ListPayrollsParams, +) ([]models.Payroll, error) { + payrolls, err := i.txRepository.ListPayrolls(ctx, transactions.ListPayrollsParams{ + IDs: params.IDs, + Limit: int64(params.Limit), + OrganizationID: params.OrganizationID, + }) + if err != nil { + return nil, fmt.Errorf("error fetch payrolls from repository. %w", err) + } + + return payrolls, nil +} + +type NewSalaryParams struct { + OrganizationID uuid.UUID + EmployeeID uuid.UUID +} + +func (i *chainInteractor) NewSalary( + ctx context.Context, + params NewSalaryParams, +) error { + user, err := ctxmeta.User(ctx) + if err != nil { + return fmt.Errorf("error fetch user from context. %w", err) + } + + organizationID, err := ctxmeta.OrganizationId(ctx) + if err != nil { + return fmt.Errorf("error fetch organization id from context. %w", err) + } + + return nil +} diff --git a/backend/internal/usecase/repository/transactions/repository.go b/backend/internal/usecase/repository/transactions/repository.go index dc7c228..e1b1050 100644 --- a/backend/internal/usecase/repository/transactions/repository.go +++ b/backend/internal/usecase/repository/transactions/repository.go @@ -57,6 +57,7 @@ type Repository interface { ConfirmMultisig(ctx context.Context, params ConfirmMultisigParams) error AddPayrollContract(ctx context.Context, params AddPayrollContract) error + ListPayrolls(ctx context.Context, params ListPayrollsParams) ([]models.Payroll, error) } type repositorySQL struct { @@ -688,3 +689,86 @@ func (r *repositorySQL) fetchOwners(ctx context.Context, params fetchOwnersParam return owners, nil } + +type ListPayrollsParams struct { + IDs []uuid.UUID + Limit int64 + OrganizationID uuid.UUID +} + +func (r *repositorySQL) ListPayrolls(ctx context.Context, params ListPayrollsParams) ([]models.Payroll, error) { + payrolls := make([]models.Payroll, 0, len(params.IDs)) + + if err := sqltools.Transaction(ctx, r.db, func(ctx context.Context) error { + query := sq.Select( + "id", + "title", + "address", + "organization_id", + "multisig_id", + "created_at", + "updated_at", + ).Where(sq.Eq{ + "organization_id": params.OrganizationID, + }).PlaceholderFormat(sq.Dollar) + + if params.Limit <= 0 { + params.Limit = 100 + } + + if len(params.IDs) > 0 { + query = query.Where(sq.Eq{ + "id": params.IDs, + }) + } + + query = query.Limit(uint64(params.Limit)) + + rows, err := query.RunWith(r.Conn(ctx)).QueryContext(ctx) + if err != nil { + return fmt.Errorf("error fetch payrolls from database. %w", err) + } + + defer rows.Close() // todo check error + + for rows.Next() { + var ( + id uuid.UUID + title string + address []byte + organizationId uuid.UUID + multisigId uuid.UUID + createdAt time.Time + updatedAt time.Time + ) + + if err = rows.Scan( + &id, + &title, + &address, + &organizationId, + &multisigId, + &createdAt, + &updatedAt, + ); err != nil { + return fmt.Errorf("error scan row. %w", err) + } + + payrolls = append(payrolls, models.Payroll{ + ID: id, + Title: title, + Address: address, + OrganizationID: organizationId, + MultisigID: multisigId, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + }) + } + + return nil + }); err != nil { + return nil, err + } + + return payrolls, nil +} diff --git a/backend/migrations/blockd.sql b/backend/migrations/blockd.sql index 12ec28c..308a049 100644 --- a/backend/migrations/blockd.sql +++ b/backend/migrations/blockd.sql @@ -217,5 +217,3 @@ create table payrolls ( created_at timestamp default current_timestamp, updated_at timestamp default current_timestamp ); - -create table payrolls \ No newline at end of file