Skip to content

Commit

Permalink
impl transfer energy rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
aradwann committed Mar 13, 2024
1 parent 84cf1b2 commit c17d447
Show file tree
Hide file tree
Showing 11 changed files with 1,347 additions and 100 deletions.
166 changes: 150 additions & 16 deletions doc/swagger/eenergy.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@
"application/json"
],
"paths": {
"/v1/create_user": {
"/v1/energy/transfer": {
"post": {
"summary": "Create new user",
"description": "Use this API to create a new user",
"operationId": "EenergyService_CreateUser",
"summary": "transfer energy",
"description": "Use this API to transfer energy from account to another",
"operationId": "EenergyService_TransferEnergy",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/pbCreateUserResponse"
"$ref": "#/definitions/pbTransferEnergyResponse"
}
},
"default": {
Expand All @@ -46,7 +46,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/pbCreateUserRequest"
"$ref": "#/definitions/pbTransferEnergyRequest"
}
}
],
Expand All @@ -55,16 +55,16 @@
]
}
},
"/v1/login_user": {
"/v1/user": {
"post": {
"summary": "Login user",
"description": "Use this API to login user and get access token \u0026 refresh token",
"operationId": "EenergyService_LoginUser",
"summary": "Create new user",
"description": "Use this API to create a new user",
"operationId": "EenergyService_CreateUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/pbLoginUserResponse"
"$ref": "#/definitions/pbCreateUserResponse"
}
},
"default": {
Expand All @@ -80,16 +80,14 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/pbLoginUserRequest"
"$ref": "#/definitions/pbCreateUserRequest"
}
}
],
"tags": [
"EenergyService"
]
}
},
"/v1/update_user": {
},
"patch": {
"summary": "Update user",
"description": "Use this API to update user",
Expand Down Expand Up @@ -123,7 +121,41 @@
]
}
},
"/v1/verify_email": {
"/v1/user/login": {
"post": {
"summary": "Login user",
"description": "Use this API to login user and get access token \u0026 refresh token",
"operationId": "EenergyService_LoginUser",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/pbLoginUserResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/pbLoginUserRequest"
}
}
],
"tags": [
"EenergyService"
]
}
},
"/v1/verify-email": {
"get": {
"summary": "verify email",
"description": "Use this API to verify the user email",
Expand Down Expand Up @@ -164,6 +196,29 @@
}
},
"definitions": {
"pbAccount": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "int64"
},
"owner": {
"type": "string"
},
"balance": {
"type": "string",
"format": "int64"
},
"unit": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
},
"pbCreateUserRequest": {
"type": "object",
"properties": {
Expand All @@ -189,6 +244,27 @@
}
}
},
"pbEntry": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "int64"
},
"accountId": {
"type": "string",
"format": "int64"
},
"amount": {
"type": "string",
"format": "int64"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
},
"pbLoginUserRequest": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -225,6 +301,64 @@
}
}
},
"pbTransfer": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "int64"
},
"fromAccountId": {
"type": "string",
"format": "int64"
},
"toAccountId": {
"type": "string",
"format": "int64"
},
"amount": {
"type": "string",
"format": "int64"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
},
"pbTransferEnergyRequest": {
"type": "object",
"properties": {
"fromAccountId": {
"type": "string",
"format": "int64"
},
"toAccountId": {
"type": "string",
"format": "int64"
},
"amount": {
"type": "string",
"format": "int64"
}
}
},
"pbTransferEnergyResponse": {
"type": "object",
"properties": {
"transfer": {
"$ref": "#/definitions/pbTransfer"
},
"fromAccount": {
"$ref": "#/definitions/pbAccount"
},
"fromEntry": {
"$ref": "#/definitions/pbEntry",
"description": "Entry to_entry = 5;",
"title": "Account to_account = 3;"
}
}
},
"pbUpdateUserRequest": {
"type": "object",
"properties": {
Expand Down
28 changes: 28 additions & 0 deletions gapi/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,31 @@ func convertUser(user db.User) *pb.User {
CreatedAt: timestamppb.New(user.CreatedAt),
}
}
func convertTransfer(transfer db.Transfer) *pb.Transfer {
return &pb.Transfer{
Id: transfer.ID,
FromAccountId: transfer.FromAccountID,
ToAccountId: transfer.ToAccountID,
Amount: transfer.Amount,
CreatedAt: timestamppb.New(transfer.CreatedAt),
}
}

func convertAccount(account db.Account) *pb.Account {
return &pb.Account{
Id: account.ID,
Owner: account.Owner,
Balance: account.Balance,
Unit: account.Unit,
CreatedAt: timestamppb.New(account.CreatedAt),
}
}

func convertEntry(entry db.Entry) *pb.Entry {
return &pb.Entry{
Id: entry.ID,
AccountId: entry.AccountID,
Amount: entry.Amount,
CreatedAt: timestamppb.New(entry.CreatedAt),
}
}
73 changes: 73 additions & 0 deletions gapi/rpc_transfer_energy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package gapi

import (
"context"
"errors"

db "github.com/aradwann/eenergy/db/store"
"github.com/aradwann/eenergy/pb"
"github.com/aradwann/eenergy/util"
"github.com/aradwann/eenergy/val"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func (server *Server) TransferEnergy(ctx context.Context, req *pb.TransferEnergyRequest) (*pb.TransferEnergyResponse, error) {
authPayload, err := server.authorizeUser(ctx, []string{util.AdminRole, util.GeneratorRole})
if err != nil {
return nil, unauthenticatedError(err)
}
violations := validateTransferEnergyRequest(req)
if violations != nil {
return nil, invalidArgumentError(violations)
}

fromAccount, err := server.store.GetAccount(ctx, req.FromAccountId)
if err != nil {
if errors.Is(err, db.ErrRecordNotFound) {
return nil, status.Errorf(codes.NotFound, "account not found")
}
return nil, status.Errorf(codes.Internal, "failed to get user account: %s", err)
}
if authPayload.Username != fromAccount.Owner {
return nil, status.Error(codes.PermissionDenied, "cannot transfer from this account")
}

arg := db.TransferTxParams{
FromAccountID: req.GetFromAccountId(),
ToAccountID: req.GetToAccountId(),
Amount: req.GetAmount(),
}

transferRes, err := server.store.TransferTx(ctx, arg)
if err != nil {
if errors.Is(err, db.ErrRecordNotFound) {
return nil, status.Errorf(codes.NotFound, "user not found")
}
return nil, status.Errorf(codes.Internal, "failed to transfer energy units : %s", err)
}

rsp := &pb.TransferEnergyResponse{
Transfer: convertTransfer(transferRes.Transfer),
FromAccount: convertAccount(transferRes.FromAccount),
FromEntry: convertEntry(transferRes.FromEntry),
}
return rsp, nil
}

func validateTransferEnergyRequest(req *pb.TransferEnergyRequest) (violations []*errdetails.BadRequest_FieldViolation) {
if err := val.ValidateAccountId(req.GetFromAccountId()); err != nil {
violations = append(violations, fieldViolation("from_account_id", err))
}

if err := val.ValidateAccountId(req.GetToAccountId()); err != nil {
violations = append(violations, fieldViolation("to_account_id", err))
}

if err := val.ValidateAmount(req.GetAmount()); err != nil {
violations = append(violations, fieldViolation("amount", err))
}

return
}
Loading

0 comments on commit c17d447

Please sign in to comment.