From ae8e84deb6656a6fb951ad0bdefb5d45bb0e2470 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 5 Feb 2022 01:24:23 +0100 Subject: [PATCH 01/38] =?UTF-8?q?=F0=9F=9A=80=20crowdaction=20hex=20refact?= =?UTF-8?q?oring=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/models/crowdaction.go | 13 +++++++ pkg/handler/aws/crowdaction/README.md | 0 pkg/handler/aws/crowdaction/main.go | 51 +++++++++++++++++++++++++++ pkg/handler/aws/emailContact/main.go | 6 +++- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 internal/models/crowdaction.go create mode 100644 pkg/handler/aws/crowdaction/README.md create mode 100644 pkg/handler/aws/crowdaction/main.go diff --git a/internal/models/crowdaction.go b/internal/models/crowdaction.go new file mode 100644 index 0000000..7cf360a --- /dev/null +++ b/internal/models/crowdaction.go @@ -0,0 +1,13 @@ +package models + +type CrowdActionRequest struct { + Title string + Description string + AppVersion string +} + +type CrowdAction struct { + CrowdactionID string + Title string + Description string +} diff --git a/pkg/handler/aws/crowdaction/README.md b/pkg/handler/aws/crowdaction/README.md new file mode 100644 index 0000000..e69de29 diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go new file mode 100644 index 0000000..556aa79 --- /dev/null +++ b/pkg/handler/aws/crowdaction/main.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "os" + + "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" + "github.com/go-playground/validator/v10" +) + +var ( + tableName = os.Getenv("TABLE_NAME") +) + +func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { + fmt.Println("Entering the crowdaction endpoint") + + // invoking crowdaction model + var request models.CrowdActionRequest + + // creating a new validator object + validate := validator.New() + + // validating against error + if err := validate.StructCtx(ctx, request); err != nil { + return errToResponse(err, http.StatusBadRequest), nil + } + + // AWS session + //sess := session.Must(session.NewSession()) + + if err := json.Unmarshal([]byte(req.Body), &request); err != nil { + return errToResponse(err, http.StatusBadRequest), nil + } + + return events.APIGatewayV2HTTPResponse{StatusCode: 200, Body: "Success!"}, nil +} + +func main() { + lambda.Start(handler) +} + +func errToResponse(err error, code int) events.APIGatewayV2HTTPResponse { + msg, _ := json.Marshal(map[string]string{"message": err.Error()}) + return events.APIGatewayV2HTTPResponse{Body: string(msg), StatusCode: code} +} diff --git a/pkg/handler/aws/emailContact/main.go b/pkg/handler/aws/emailContact/main.go index 97059ce..2a18144 100644 --- a/pkg/handler/aws/emailContact/main.go +++ b/pkg/handler/aws/emailContact/main.go @@ -3,6 +3,9 @@ package main import ( "context" "encoding/json" + "fmt" + "net/http" + "github.com/CollActionteam/collaction_backend/internal/contact" "github.com/CollActionteam/collaction_backend/internal/models" awsRepository "github.com/CollActionteam/collaction_backend/pkg/repository/aws" @@ -10,7 +13,6 @@ import ( "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go/aws/session" "github.com/go-playground/validator/v10" - "net/http" ) func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { @@ -19,6 +21,8 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP return errToResponse(err, http.StatusBadRequest), nil } + fmt.Println("Hello World") + validate := validator.New() if err := validate.StructCtx(ctx, request); err != nil { //TODO 10.01.22 mrsoftware: fix the error message From ac8387fd4e7d0b90f8791e93be78071295c63779 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 5 Feb 2022 13:23:37 +0100 Subject: [PATCH 02/38] =?UTF-8?q?=F0=9F=9A=A7=20=20dynamodb=20manager=20re?= =?UTF-8?q?pository,=20pt1:=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/repository/aws/dynamoManager.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 pkg/repository/aws/dynamoManager.go diff --git a/pkg/repository/aws/dynamoManager.go b/pkg/repository/aws/dynamoManager.go new file mode 100644 index 0000000..af14746 --- /dev/null +++ b/pkg/repository/aws/dynamoManager.go @@ -0,0 +1,27 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/session" + "github.com/pkg/errors" +) + +type DynamoManager struct { + // need to look this up + Client *dynamodb.DDB +} + +func NewDynamoManager(session *session.Session) *DynamoManager { + return &DynamoManager{Client: dynamodb.New(session)} +} + +func (d *DynamoManager) GetItem(pk string) (string, error) { + // need to look this up + param, err := d.Client.GetItem(&dynamodb) + if err != nil { + return "", errors.WithStack(err) + } + + // need to look this up + return *param.Response, nil +} From 7ae52c79876f7a5062517afe6915912e102f9eb0 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Fri, 25 Feb 2022 14:52:40 +0100 Subject: [PATCH 03/38] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20launching=20own=20sa?= =?UTF-8?q?m=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samconfig.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 samconfig.yaml diff --git a/samconfig.yaml b/samconfig.yaml new file mode 100644 index 0000000..14cadb8 --- /dev/null +++ b/samconfig.yaml @@ -0,0 +1,12 @@ +version = 0.1 +[default] +[default.deploy] +[default.deploy.parameters] +s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1xoanv4heoh1g" +s3_prefix = "collaction-dev-edreinoso" +stack_name = "collaction-dev-edreinoso" +region = "eu-central-1" +confirm_changeset = true +capabilities = "CAPABILITY_IAM" +image_repositories = [] +parameter_overrides = "Stage=\"dev\" FirebaseProjectId=\"collaction-52ca9\" DomainParameter=\"\" SubdomainSuffixParameter=\"\" HostedZoneIdParameter=\"\" AcmCertificateArnParameter=\"\"" From 9963992dbb8508d488c53e776e6f9b011a9ea8e1 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 26 Feb 2022 08:58:52 +0100 Subject: [PATCH 04/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20deployed?= =?UTF-8?q?=20first=20function=20on=20to=20aws?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- pkg/handler/aws/crowdaction/main.go | 34 +++------ template.yaml | 105 +++++++++++++--------------- 3 files changed, 60 insertions(+), 81 deletions(-) diff --git a/.gitignore b/.gitignore index 7c5b4ba..2ad12b0 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ _ignored/ .vscode/launch.json .vscode/extensions.json *.code-workspace - +*.gitconfig # VisualStudioCode Patch # Ignore all local history of files .history diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 556aa79..6b14fca 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -4,41 +4,25 @@ import ( "context" "encoding/json" "fmt" - "net/http" - "os" - "github.com/CollActionteam/collaction_backend/internal/models" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" - "github.com/go-playground/validator/v10" ) -var ( - tableName = os.Getenv("TABLE_NAME") -) - -func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { - fmt.Println("Entering the crowdaction endpoint") - - // invoking crowdaction model - var request models.CrowdActionRequest +func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) string { + fmt.Println("Hello Go, first message from AWS!") - // creating a new validator object - validate := validator.New() - - // validating against error - if err := validate.StructCtx(ctx, request); err != nil { - return errToResponse(err, http.StatusBadRequest), nil - } + crowdactionID := req.PathParameters["crowdactionID"] - // AWS session - //sess := session.Must(session.NewSession()) + fmt.Println("Getting the crowdactionID from the request") - if err := json.Unmarshal([]byte(req.Body), &request); err != nil { - return errToResponse(err, http.StatusBadRequest), nil + if crowdactionID == "" { + firstReturnValue := "Returning all crowdactions" + return firstReturnValue } + firstReturnValue := "Returning specific crowdaction" - return events.APIGatewayV2HTTPResponse{StatusCode: 200, Body: "Success!"}, nil + return firstReturnValue } func main() { diff --git a/template.yaml b/template.yaml index b2eff57..9588cec 100644 --- a/template.yaml +++ b/template.yaml @@ -1,9 +1,8 @@ -AWSTemplateFormatVersion: '2010-09-09' +AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > CollAction backend # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst - Globals: Function: Timeout: 10 @@ -35,13 +34,12 @@ Parameters: Type: String NoEcho: true Description: "ARN of certificate for CloudFront in region us-east-1 (Only for custom domain)" - + Conditions: shouldUseCustomDomainNames: !Not [!Equals [!Ref DomainParameter, ""]] Resources: - - DnsRecords: + DnsRecords: Type: AWS::Route53::RecordSetGroup Condition: shouldUseCustomDomainNames Properties: @@ -82,14 +80,14 @@ Resources: StaticContentDistribution: Type: AWS::CloudFront::Distribution Condition: shouldUseCustomDomainNames - Properties: + Properties: DistributionConfig: DefaultCacheBehavior: AllowedMethods: [HEAD, DELETE, POST, GET, OPTIONS, PUT, PATCH] TargetOriginId: StaticBucketOrigin ViewerProtocolPolicy: redirect-to-https ForwardedValues: - QueryString: 'false' + QueryString: "false" Cookies: Forward: none Enabled: true @@ -99,7 +97,7 @@ Resources: - Id: StaticBucketOrigin DomainName: !Sub ${StaticHostingBucket}.s3.${ AWS::Region }.amazonaws.com S3OriginConfig: - OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOriginIdentity}' + OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CloudFrontOriginIdentity}" ViewerCertificate: AcmCertificateArn: !Ref AcmCertificateArnParameter MinimumProtocolVersion: TLSv1.1_2016 @@ -108,21 +106,21 @@ Resources: HttpApiDomainName: Type: AWS::ApiGatewayV2::DomainName Condition: shouldUseCustomDomainNames - Properties: + Properties: DomainName: !Sub "api${SubdomainSuffixParameter}.${DomainParameter}" - DomainNameConfigurations: + DomainNameConfigurations: - EndpointType: REGIONAL CertificateArn: !Ref Certificate HttpApiMapping: Type: AWS::ApiGatewayV2::ApiMapping Condition: shouldUseCustomDomainNames - Properties: + Properties: ApiMappingKey: "" DomainName: !Sub "api${SubdomainSuffixParameter}.${DomainParameter}" ApiId: !Ref HttpApi Stage: !Ref HttpApi.Stage - DependsOn: + DependsOn: - HttpApiDomainName - HttpApi @@ -143,7 +141,7 @@ Resources: CorsConfiguration: AllowMethods: [GET] AllowOrigins: [http://localhost:8080] - + EmailContactFunction: Type: AWS::Serverless::Function Properties: @@ -160,19 +158,19 @@ Resources: Auth: Authorizer: "NONE" Policies: - - Version: '2012-10-17' + - Version: "2012-10-17" Statement: - Effect: Allow Action: - - 'ses:SendEmail' - - 'ses:SendRawEmail' - - 'ssm:GetParameter' - Resource: '*' + - "ses:SendEmail" + - "ses:SendRawEmail" + - "ssm:GetParameter" + Resource: "*" ProfilePictureUploadBucket: - Type: 'AWS::S3::Bucket' + Type: "AWS::S3::Bucket" StaticHostingBucket: - Type: 'AWS::S3::Bucket' + Type: "AWS::S3::Bucket" Properties: AccessControl: Private WebsiteConfiguration: @@ -196,10 +194,10 @@ Resources: BUCKET: !Ref ProfilePictureUploadBucket Policies: - Statement: - - Effect: Allow - Action: - - s3:PutObject* - Resource: '*' + - Effect: Allow + Action: + - s3:PutObject* + Resource: "*" Events: ProfilePictureUpload: Type: HttpApi @@ -209,7 +207,7 @@ Resources: ApiId: !Ref HttpApi ProcessProfilePictureFunction: - Type: 'AWS::Serverless::Function' + Type: "AWS::Serverless::Function" Properties: CodeUri: process-profile-picture/ Handler: process-profile-picture @@ -219,17 +217,18 @@ Resources: # Beware of recursive execution! Double check referenced buckets! OUTPUT_BUCKET_NAME: !Ref StaticHostingBucket KEY_PREIFX: profile-pictures/ - CLOUDFRONT_DISTRIBUTION: !If [shouldUseCustomDomainNames, !Ref StaticContentDistribution, ""] + CLOUDFRONT_DISTRIBUTION: + !If [shouldUseCustomDomainNames, !Ref StaticContentDistribution, ""] Policies: - Statement: - - Effect: Allow - Action: - - s3:GetObject* - - s3:PutObject* - - s3:DeleteObject* - - rekognition:DetectModerationLabels - - cloudfront:CreateInvalidation - Resource: '*' + - Effect: Allow + Action: + - s3:GetObject* + - s3:PutObject* + - s3:DeleteObject* + - rekognition:DetectModerationLabels + - cloudfront:CreateInvalidation + Resource: "*" Events: S3Event: Type: S3 @@ -256,10 +255,10 @@ Resources: GlobalSecondaryIndexes: - IndexName: "invertedIndex" KeySchema: - - AttributeName: "sk" - KeyType: "HASH" - - AttributeName: "pk" - KeyType: "RANGE" + - AttributeName: "sk" + KeyType: "HASH" + - AttributeName: "pk" + KeyType: "RANGE" Projection: ProjectionType: "ALL" # Data duplication is less costly than additional per primary key lookups (?) ProvisionedThroughput: @@ -269,7 +268,7 @@ Resources: CrowdactionFunction: Type: AWS::Serverless::Function Properties: - CodeUri: crowdaction/ + CodeUri: pkg/handler/aws/crowdaction Handler: crowdaction Runtime: go1.x Events: @@ -294,8 +293,7 @@ Resources: TABLE_NAME: !Ref SingleTable Policies: - DynamoDBCrudPolicy: - TableName: - !Ref SingleTable + TableName: !Ref SingleTable ParticipationQueue: Type: AWS::SQS::Queue @@ -318,8 +316,7 @@ Resources: MaximumBatchingWindowInSeconds: 300 #5min Policies: - DynamoDBCrudPolicy: - TableName: - !Ref SingleTable + TableName: !Ref SingleTable ParticipationFunction: Type: AWS::Serverless::Function @@ -341,15 +338,14 @@ Resources: ApiId: !Ref HttpApi Policies: - DynamoDBCrudPolicy: - TableName: - !Ref SingleTable + TableName: !Ref SingleTable - Statement: - - Sid: ParticipationQueuePutRecordPolicy - Effect: Allow - Action: - - sqs:SendMessage - Resource: !GetAtt ParticipationQueue.Arn - + - Sid: ParticipationQueuePutRecordPolicy + Effect: Allow + Action: + - sqs:SendMessage + Resource: !GetAtt ParticipationQueue.Arn + ProfileCRUDFunction: Type: AWS::Serverless::Function Properties: @@ -368,8 +364,7 @@ Resources: PROFILE_TABLE: !Ref ProfileTable Policies: - DynamoDBCrudPolicy: - TableName: - !Ref ProfileTable + TableName: !Ref ProfileTable # TODO use table SingleTabel instead ProfileTable: @@ -392,5 +387,5 @@ Outputs: Description: "CloudFront distribution endpoint URL for static files" Value: !Sub "https://static${SubdomainSuffixParameter}.${DomainParameter}/" TableName: - Value: !Ref SingleTable - Description: Table name of the newly created DynamoDB table \ No newline at end of file + Value: !Ref SingleTable + Description: Table name of the newly created DynamoDB table From 605e5643a40637276b63edca1da8874e5099f501 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 26 Feb 2022 09:00:56 +0100 Subject: [PATCH 05/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20removing?= =?UTF-8?q?=20extra=20copy=20of=20dynamo=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/repository/aws/dynamoManager.go | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 pkg/repository/aws/dynamoManager.go diff --git a/pkg/repository/aws/dynamoManager.go b/pkg/repository/aws/dynamoManager.go deleted file mode 100644 index af14746..0000000 --- a/pkg/repository/aws/dynamoManager.go +++ /dev/null @@ -1,27 +0,0 @@ -package aws - -import ( - "github.com/aws/aws-sdk-go/service/dynamodb" - "github.com/aws/aws-sdk-go/session" - "github.com/pkg/errors" -) - -type DynamoManager struct { - // need to look this up - Client *dynamodb.DDB -} - -func NewDynamoManager(session *session.Session) *DynamoManager { - return &DynamoManager{Client: dynamodb.New(session)} -} - -func (d *DynamoManager) GetItem(pk string) (string, error) { - // need to look this up - param, err := d.Client.GetItem(&dynamodb) - if err != nil { - return "", errors.WithStack(err) - } - - // need to look this up - return *param.Response, nil -} From 0423b321cec882d32d33fe45b27bd8d097eae7f7 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 26 Feb 2022 09:14:01 +0100 Subject: [PATCH 06/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20init=20mod?= =?UTF-8?q?el=20and=20validation=20on=20request?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/models/commitment.go | 0 internal/models/crowdaction.go | 33 +++++++++++++++++++++++------ pkg/handler/aws/crowdaction/main.go | 4 ++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 internal/models/commitment.go diff --git a/internal/models/commitment.go b/internal/models/commitment.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/models/crowdaction.go b/internal/models/crowdaction.go index 7cf360a..269b641 100644 --- a/internal/models/crowdaction.go +++ b/internal/models/crowdaction.go @@ -1,13 +1,32 @@ package models type CrowdActionRequest struct { - Title string - Description string - AppVersion string + Data CrowdActionData `json:"data" validate:"required"` } -type CrowdAction struct { - CrowdactionID string - Title string - Description string +type CrowdactionParticipant struct { + Name string `json:"name,omitempty"` + UserID string `json:"userID,omitempty"` +} + +type CrowdactionImages struct { + Card string `json:"card,omitempty"` + Banner string `json:"banner,omitempty"` +} + +type CrowdActionData struct { + CrowdactionID string `json:"crowdactionID"` + Title string `json:"title"` + Description string `json:"description"` + Category string `json:"category"` + Subcategory string `json:"subcategory"` + Location string `json:"location"` + DateStart string `json:"date_start"` + DateEnd string `json:"date_end"` + DateLimitJoin string `json:"date_limit_join"` + PasswordJoin string `json:"password_join"` + CommitmentOptions []CommitmentOption `json:"commitment_options"` + ParticipationCount int `json:"participant_count"` + TopParticipants []CrowdactionParticipant `json:"top_participants"` + Images CrowdactionImages `json:"images"` } diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 6b14fca..4ec3ffe 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -7,11 +7,15 @@ import ( "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" + // "github.com/CollActionteam/collaction_backend/internal/contact" + // "github.com/CollActionteam/collaction_backend/internal/models" ) func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) string { fmt.Println("Hello Go, first message from AWS!") + // var request models.CrowdActionRequest + crowdactionID := req.PathParameters["crowdactionID"] fmt.Println("Getting the crowdactionID from the request") From d7daae2de3690ae229ae576a17bde4d554594e5b Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Fri, 4 Mar 2022 18:10:27 +0100 Subject: [PATCH 07/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20changed=20?= =?UTF-8?q?the=20model=20function=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/models/crowdaction.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/models/crowdaction.go b/internal/models/crowdaction.go index 269b641..11e03d1 100644 --- a/internal/models/crowdaction.go +++ b/internal/models/crowdaction.go @@ -1,7 +1,7 @@ package models -type CrowdActionRequest struct { - Data CrowdActionData `json:"data" validate:"required"` +type CrowdactionRequest struct { + Data CrowdactionData `json:"data" validate:"required"` } type CrowdactionParticipant struct { @@ -14,7 +14,7 @@ type CrowdactionImages struct { Banner string `json:"banner,omitempty"` } -type CrowdActionData struct { +type CrowdactionData struct { CrowdactionID string `json:"crowdactionID"` Title string `json:"title"` Description string `json:"description"` @@ -25,8 +25,8 @@ type CrowdActionData struct { DateEnd string `json:"date_end"` DateLimitJoin string `json:"date_limit_join"` PasswordJoin string `json:"password_join"` - CommitmentOptions []CommitmentOption `json:"commitment_options"` ParticipationCount int `json:"participant_count"` TopParticipants []CrowdactionParticipant `json:"top_participants"` Images CrowdactionImages `json:"images"` + // CommitmentOptions []CommitmentOption `json:"commitment_options"` } From e684acfaeb3e0661cd1035fae552f9f65d8e5c4b Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 9 Mar 2022 19:01:36 +0100 Subject: [PATCH 08/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20working=20?= =?UTF-8?q?on=20internal=20and=20handler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 44 +++++++++++++++++ pkg/handler/aws/crowdaction/main.go | 71 ++++++++++++++++++++++++---- 2 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 internal/crowdactions/crowdaction.go diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go new file mode 100644 index 0000000..6ed0172 --- /dev/null +++ b/internal/crowdactions/crowdaction.go @@ -0,0 +1,44 @@ +package crowdaction + +import ( + "context" + "fmt" + + "github.com/CollActionteam/collaction_backend/internal/constants" + "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/utils" +) + +const Separator = "### app version:" + +type DynamoRepository interface { + GetDBItem(tableName string, pk string, crowdactionId string) (*models.CrowdactionData, error) +} + +type Service interface { + GetCrowdaction(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) +} + +type crowdaction struct { + dynamodb DynamoRepository +} + +func NewCrowdactionService(dynamodb DynamoRepository) Service { + return &crowdaction{dynamodb: dynamodb} +} + +/** + GET Crowdaction by Id +**/ +func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) { + item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionId) + if err != nil { + return nil, err + } + if item == nil { + return nil, fmt.Errorf("Crowdaction not found") + } + // var crowdaction models.CrowdactionData + // err = dynamodbattribute.UnmarshalMap(foo, &crowdaction) + return item, err +} diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 4ec3ffe..bc547e0 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -4,29 +4,84 @@ import ( "context" "encoding/json" "fmt" + "net/http" + crowdaction "github.com/CollActionteam/collaction_backend/internal/crowdactions" + "github.com/CollActionteam/collaction_backend/internal/models" + hnd "github.com/CollActionteam/collaction_backend/pkg/handler" + awsRepository "github.com/CollActionteam/collaction_backend/pkg/repository/aws" + "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" + // "github.com/CollActionteam/collaction_backend/internal/contact" // "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/go-playground/validator/v10" ) +// type CrowdactionHandler struct { +// // getting all the main functions from the internal +// crowadction crowdactions.Dynamo +// } + +// // return crowdactions by +// func getCrowdactions (status string) (events.APIGatewayProxyResponse, error) {} + +// // return single crowdaction by ID +// func getCrowdaction (crowdactionId string, dynamoRepository Dynamo) (events.APIGatewayProxyResponse, error) { +// crowdaction, err := models. + +// // should call the internal and receive a response +// } + +// func retrieveInfoFromRequest(req events.APIGatewayV2HTTPRequest) (*models.Crowdaction, error) { +// crowdactionID := req.PathParameters["crowdactionID"] +// usrInf, err := auth.ExtractUserInfo(req) +// if err != nil { +// return nil, err +// } +// crowdaction, _ := models.GetCrowdaction(crowdactionID, constants.TableName) +// if crowdaction == nil { +// return "", "", nil, errors.New("crowdaction not found") +// } +// return crowdaction, nil +// } + func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) string { + var request models.CrowdactionRequest + + if err := json.Unmarshal([]byte(req.Body), &request); err != nil { + return errToResponse(err, http.StatusBadRequest), nil + } + fmt.Println("Hello Go, first message from AWS!") - // var request models.CrowdActionRequest + validate := validator.New() + if err := validate.StructCtx(ctx, request); err != nil { + body, _ := json.Marshal(hnd.Response{Status: hnd.StatusFail, Data: map[string]interface{}{"error": utils.ValidationResponse(err, validate)}}) + return events.APIGatewayV2HTTPResponse{Body: string(body), StatusCode: http.StatusBadRequest}, nil + } crowdactionID := req.PathParameters["crowdactionID"] + dynamoRepository := awsRepository.NewDynamo() - fmt.Println("Getting the crowdactionID from the request") + if err := crowdaction.NewCrowdactionService(dynamoRepository).GetCrowdaction(crowdactionID) + // fmt.Println("Getting the crowdactionID from the request") - if crowdactionID == "" { - firstReturnValue := "Returning all crowdactions" - return firstReturnValue - } - firstReturnValue := "Returning specific crowdaction" + // if crowdactionID == "" { + // status := req.QueryStringParameters["status"] + // switch status { + // case "": + // status = "joinable" + // case "featured": + // status = "joinable" + // } + // return getCrowdactions(status) + // } - return firstReturnValue + // return getCrowdaction(crowdactionID) + + return event.APIGatewayProxyResponse{StatusCode: 200, Body: string(body)}, nill } func main() { From 32666f855ef4762a8e9224599f397fbd7d8bec1b Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Thu, 10 Mar 2022 18:08:48 +0100 Subject: [PATCH 09/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20simple=20v?= =?UTF-8?q?ersion=20of=20GET=20request=20by=20ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 12 +++-- pkg/handler/aws/crowdaction/main.go | 70 +++++++++------------------- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 6ed0172..e351c44 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -7,12 +7,14 @@ import ( "github.com/CollActionteam/collaction_backend/internal/constants" "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" + "github.com/aws/aws-sdk-go/service/dynamodb" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" ) const Separator = "### app version:" type DynamoRepository interface { - GetDBItem(tableName string, pk string, crowdactionId string) (*models.CrowdactionData, error) + GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) } type Service interface { @@ -38,7 +40,9 @@ func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionId string) if item == nil { return nil, fmt.Errorf("Crowdaction not found") } - // var crowdaction models.CrowdactionData - // err = dynamodbattribute.UnmarshalMap(foo, &crowdaction) - return item, err + fmt.Printf("GetCrowdaction calling internal") + var crowdaction models.CrowdactionData + err = dynamodbattribute.UnmarshalMap(item, &crowdaction) + return &crowdaction, err + // return item, err } diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index bc547e0..d7d2f8d 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -6,48 +6,17 @@ import ( "fmt" "net/http" - crowdaction "github.com/CollActionteam/collaction_backend/internal/crowdactions" + cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" "github.com/CollActionteam/collaction_backend/internal/models" hnd "github.com/CollActionteam/collaction_backend/pkg/handler" awsRepository "github.com/CollActionteam/collaction_backend/pkg/repository/aws" "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" - - // "github.com/CollActionteam/collaction_backend/internal/contact" - // "github.com/CollActionteam/collaction_backend/internal/models" "github.com/go-playground/validator/v10" ) -// type CrowdactionHandler struct { -// // getting all the main functions from the internal -// crowadction crowdactions.Dynamo -// } - -// // return crowdactions by -// func getCrowdactions (status string) (events.APIGatewayProxyResponse, error) {} - -// // return single crowdaction by ID -// func getCrowdaction (crowdactionId string, dynamoRepository Dynamo) (events.APIGatewayProxyResponse, error) { -// crowdaction, err := models. - -// // should call the internal and receive a response -// } - -// func retrieveInfoFromRequest(req events.APIGatewayV2HTTPRequest) (*models.Crowdaction, error) { -// crowdactionID := req.PathParameters["crowdactionID"] -// usrInf, err := auth.ExtractUserInfo(req) -// if err != nil { -// return nil, err -// } -// crowdaction, _ := models.GetCrowdaction(crowdactionID, constants.TableName) -// if crowdaction == nil { -// return "", "", nil, errors.New("crowdaction not found") -// } -// return crowdaction, nil -// } - -func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) string { +func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { var request models.CrowdactionRequest if err := json.Unmarshal([]byte(req.Body), &request); err != nil { @@ -63,25 +32,30 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) string { } crowdactionID := req.PathParameters["crowdactionID"] + dynamoRepository := awsRepository.NewDynamo() - if err := crowdaction.NewCrowdactionService(dynamoRepository).GetCrowdaction(crowdactionID) - // fmt.Println("Getting the crowdactionID from the request") - - // if crowdactionID == "" { - // status := req.QueryStringParameters["status"] - // switch status { - // case "": - // status = "joinable" - // case "featured": - // status = "joinable" - // } - // return getCrowdactions(status) + fmt.Println("Getting the crowdactionID from the request") + + getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID) + + if err != nil { + return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + } + if getCrowdaction == nil { + return utils.CreateMessageHttpResponse(http.StatusNotFound, "not participating"), nil + } + + // if getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID); err != nil { + // return errToResponse(err, http.StatusInternalServerError), nil // } - // return getCrowdaction(crowdactionID) - - return event.APIGatewayProxyResponse{StatusCode: 200, Body: string(body)}, nill + jsonPayload, _ := json.Marshal(getCrowdaction) + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil + } func main() { From c25eec92eb684838d71e3f979bf1ced9ee3ceffa Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Fri, 11 Mar 2022 10:42:07 +0100 Subject: [PATCH 10/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20testing=20?= =?UTF-8?q?GET=20request=20by=20ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 7 ++++--- internal/models/commitment.go | 0 pkg/handler/aws/crowdaction/main.go | 26 ++++++++++++++++---------- pkg/repository/aws/dynamo.go | 5 +++++ 4 files changed, 25 insertions(+), 13 deletions(-) delete mode 100644 internal/models/commitment.go diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index e351c44..eeab50e 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -26,21 +26,22 @@ type crowdaction struct { } func NewCrowdactionService(dynamodb DynamoRepository) Service { + // fmt.Println("NewCrowdactionService") return &crowdaction{dynamodb: dynamodb} } /** GET Crowdaction by Id **/ -func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) { - item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionId) +func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { + // fmt.Println("GetCrowdaction calling internal:", crowdactionID) + item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionID) if err != nil { return nil, err } if item == nil { return nil, fmt.Errorf("Crowdaction not found") } - fmt.Printf("GetCrowdaction calling internal") var crowdaction models.CrowdactionData err = dynamodbattribute.UnmarshalMap(item, &crowdaction) return &crowdaction, err diff --git a/internal/models/commitment.go b/internal/models/commitment.go deleted file mode 100644 index e69de29..0000000 diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index d7d2f8d..4f05ce3 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -16,14 +16,19 @@ import ( "github.com/go-playground/validator/v10" ) +// func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { + // func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { + crowdactionID := req.PathParameters["crowdactionID"] + + fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest - if err := json.Unmarshal([]byte(req.Body), &request); err != nil { - return errToResponse(err, http.StatusBadRequest), nil - } + // if err := json.Unmarshal([]byte(req.Body), &request); err != nil { + // return errToResponse(err, http.StatusBadRequest), nil + // } - fmt.Println("Hello Go, first message from AWS!") + fmt.Println("bad request") validate := validator.New() if err := validate.StructCtx(ctx, request); err != nil { @@ -31,31 +36,32 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP return events.APIGatewayV2HTTPResponse{Body: string(body), StatusCode: http.StatusBadRequest}, nil } - crowdactionID := req.PathParameters["crowdactionID"] + fmt.Println("Request has been validated!") dynamoRepository := awsRepository.NewDynamo() - fmt.Println("Getting the crowdactionID from the request") + // crowdactionService := cwd.NewCrowdactionService(dynamoRepository) + + // getCrowdaction, err := crowdactionService.GetCrowdaction(ctx, crowdactionID) getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID) if err != nil { + // fmt.Println("There was an error") return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil } if getCrowdaction == nil { + // fmt.Println("No crowdaction available") return utils.CreateMessageHttpResponse(http.StatusNotFound, "not participating"), nil } - // if getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID); err != nil { - // return errToResponse(err, http.StatusInternalServerError), nil - // } + fmt.Println("getCrowdaction", getCrowdaction) jsonPayload, _ := json.Marshal(getCrowdaction) return events.APIGatewayV2HTTPResponse{ Body: string(jsonPayload), StatusCode: http.StatusOK, }, nil - } func main() { diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index d915d43..4969c7d 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -45,6 +45,7 @@ type UpdateItemData struct { } func NewDynamo() *Dynamo { + fmt.Println("New Dynamo Session") sess := session.Must(session.NewSession()) return &Dynamo{dbClient: dynamodb.New(sess)} } @@ -71,6 +72,8 @@ func (s *Dynamo) GetPrimaryKey(pk string, sk string) PrimaryKey { } func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]*dynamodb.AttributeValue, error) { + // fmt.Println("Calling GetDBItem", tableName, pk, sk) + result, err := s.dbClient.GetItem(&dynamodb.GetItemInput{ TableName: &tableName, Key: s.GetPrimaryKey(pk, sk), @@ -87,6 +90,8 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* if result == nil { return nil, nil } + + // fmt.Println("result from query: ", result) return result.Item, nil } From bae64a5a7a67313659cb72852a2850e1022afb4f Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Fri, 11 Mar 2022 10:58:26 +0100 Subject: [PATCH 11/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20creating?= =?UTF-8?q?=20external=20function=20to=20GET=20crowdaction=20by=20ID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 1 - pkg/handler/aws/crowdaction/main.go | 65 ++++++++++++++++------------ 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index eeab50e..67228a4 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -45,5 +45,4 @@ func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionID string) var crowdaction models.CrowdactionData err = dynamodbattribute.UnmarshalMap(item, &crowdaction) return &crowdaction, err - // return item, err } diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 4f05ce3..366624c 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -16,6 +16,31 @@ import ( "github.com/go-playground/validator/v10" ) +func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { + dynamoRepository := awsRepository.NewDynamo() + getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID) + + if err != nil { + return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + } + if getCrowdaction == nil { + return utils.CreateMessageHttpResponse(http.StatusNotFound, "not participating"), nil + } + + fmt.Println("getCrowdaction", getCrowdaction) + + jsonPayload, _ := json.Marshal(getCrowdaction) + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil + + // return events.APIGatewayProxyResponse{ + // Body: string(body), + // StatusCode: http.StatusOK, + // }, nil +} + // func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { // func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { @@ -24,44 +49,30 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest + // This statement gives an error // if err := json.Unmarshal([]byte(req.Body), &request); err != nil { // return errToResponse(err, http.StatusBadRequest), nil // } - fmt.Println("bad request") - + // Do we really need validation for this type of requests? validate := validator.New() if err := validate.StructCtx(ctx, request); err != nil { body, _ := json.Marshal(hnd.Response{Status: hnd.StatusFail, Data: map[string]interface{}{"error": utils.ValidationResponse(err, validate)}}) return events.APIGatewayV2HTTPResponse{Body: string(body), StatusCode: http.StatusBadRequest}, nil } - fmt.Println("Request has been validated!") - - dynamoRepository := awsRepository.NewDynamo() - - // crowdactionService := cwd.NewCrowdactionService(dynamoRepository) - - // getCrowdaction, err := crowdactionService.GetCrowdaction(ctx, crowdactionID) - - getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID) - - if err != nil { - // fmt.Println("There was an error") - return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } - if getCrowdaction == nil { - // fmt.Println("No crowdaction available") - return utils.CreateMessageHttpResponse(http.StatusNotFound, "not participating"), nil + if crowdactionID == "" { + status := req.QueryStringParameters["status"] + switch status { + case "": + status = "joinable" + case "featured": + status = "joinable" + } + // get all crowdactions } - - fmt.Println("getCrowdaction", getCrowdaction) - - jsonPayload, _ := json.Marshal(getCrowdaction) - return events.APIGatewayV2HTTPResponse{ - Body: string(jsonPayload), - StatusCode: http.StatusOK, - }, nil + // get crowdaction by ID + return getCrowdactionByID(ctx, crowdactionID) } func main() { From 3d5c1a5d416076d4dff9bcfe8a4eb02e55fef118 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 19 Mar 2022 12:22:03 +0100 Subject: [PATCH 12/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20including?= =?UTF-8?q?=20query=20function=20in=20ddb=20repository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/repository/aws/dynamo.go | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index 4969c7d..87c424c 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -4,11 +4,14 @@ import ( "fmt" "github.com/CollActionteam/collaction_backend/internal/constants" + "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) const ( @@ -95,6 +98,59 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* return result.Item, nil } +func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, *utils.PrimaryKey, error) { + // var crowdactions models.CrowdactionData + crowdactions := []models.CrowdactionData{} + keyCond := expression.Key(utils.PartitionKey).Equal(expression.Value(utils.PKCrowdaction)) + expr, err := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() + + if err != nil { + return crowdactions, nil, err + } + + var exclusiveStartKey utils.PrimaryKey + + if startFrom != nil { + exclusiveStartKey = *startFrom + } + + result, err := s.dbClient.Query(&dynamodb.QueryInput{ + Limit: aws.Int64(utils.CrowdactionsPageLength), + ExclusiveStartKey: exclusiveStartKey, + TableName: aws.String(tableName), + ExpressionAttributeNames: expr.Names(), + ExpressionAttributeValues: expr.Values(), + KeyConditionExpression: expr.KeyCondition(), + FilterExpression: expr.Filter(), + }) + + // err = dynamodbattribute.UnmarshalMap(result, &crowdactions) + + for _, item := range result.Items { + var crowdaction models.CrowdactionData + err := dynamodbattribute.UnmarshalMap(item, &crowdaction) + + if err == nil { // have to figure out this error + crowdactions = append(crowdactions, crowdaction) + } + } + + if len(result.Items) != len(crowdactions) { + err = fmt.Errorf("Error unmarshelling %d items", len(result.Items)-len(crowdactions)) + } + + startFrom = nil + + if result.LastEvaluatedKey != nil && len(result.LastEvaluatedKey) > 0 { + lastPK := result.LastEvaluatedKey[utils.PartitionKey].S + lastSK := result.LastEvaluatedKey[utils.SortKey].S + exclusiveStartKey = utils.GetPrimaryKey(*lastPK, *lastSK) + startFrom = &exclusiveStartKey + } + + return crowdactions, startFrom, err +} + func (s *Dynamo) PutDBItem(tableName string, pk string, sk string, record interface{}) error { av, err := dynamodbattribute.MarshalMap(record) if err != nil { From 33a7ab1c5d30c5792aaa5d57abccabaa3d42d55a Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 19 Mar 2022 13:01:21 +0100 Subject: [PATCH 13/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20initial=20?= =?UTF-8?q?code=20base=20for=20GET=20crowdactions=20by=20status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 36 +++++++++++++++- pkg/handler/aws/crowdaction/main.go | 64 ++++++++++++++++++++++------ pkg/repository/aws/dynamo.go | 6 +-- 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 67228a4..11fdc56 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -9,22 +9,30 @@ import ( "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) const Separator = "### app version:" type DynamoRepository interface { GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) + Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } type Service interface { GetCrowdaction(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) + GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } - type crowdaction struct { dynamodb DynamoRepository } +const ( + KeyDateStart = "date_start" + KeyDateEnd = "date_end" + KeyDateJoinBefore = "date_limit_join" +) + func NewCrowdactionService(dynamodb DynamoRepository) Service { // fmt.Println("NewCrowdactionService") return &crowdaction{dynamodb: dynamodb} @@ -46,3 +54,29 @@ func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionID string) err = dynamodbattribute.UnmarshalMap(item, &crowdaction) return &crowdaction, err } + +/** + GET Crowdaction by Status +**/ +func (e *crowdaction) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { + crowdactions := []models.CrowdactionData{} // empty crowdaction array + + switch status { + case "joinable": + // call joinable crowdaction list + // crowdactions, _, err = models.ListJoinableCrowdactions(tableName, nil) // TODO future + filterCond := expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) + items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + return items, err + case "active": + filterCond := expression.Name(KeyDateStart).LessThanEqual(expression.Value(utils.GetDateStringNow())) + items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + return items, err + case "ended": + filterCond := expression.Name(KeyDateEnd).LessThanEqual(expression.Value(utils.GetDateStringNow())) + items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + return items, err + default: + return crowdactions, nil + } +} diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 366624c..c3e3d1f 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -34,21 +34,54 @@ func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGa Body: string(jsonPayload), StatusCode: http.StatusOK, }, nil +} - // return events.APIGatewayProxyResponse{ - // Body: string(body), - // StatusCode: http.StatusOK, - // }, nil +func getAllCrowdactions(ctx context.Context, status string) (events.APIGatewayV2HTTPResponse, error) { + dynamoRepository := awsRepository.NewDynamo() + var startFrom *utils.PrimaryKey + getAllCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, startFrom) + if err != nil { + return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + } + + jsonPayload, _ := json.Marshal(getAllCrowdactions) + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil + + // var crowdactions []models.Crowdaction + // var err error + + // /* TODO Send password for handling in app for MVP + // for i; i < len(crowdactions); i++) { + // if crowdactions[i].PasswordJoin != "" { + // crowdactions[i].PasswordJoin = passwordRequired + // } + // } + // */ + // if err != nil { + // return utils.GetMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + // } else { + // body, err := json.Marshal(crowdactions) + // if err != nil { + // return utils.GetMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + // } + // return events.APIGatewayProxyResponse{ + // Body: string(body), + // StatusCode: http.StatusOK, + // }, nil + // } } -// func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { - // func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) { crowdactionID := req.PathParameters["crowdactionID"] fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest + //dynamoRepository := awsRepository.NewDynamo() // should pass this dynamo variable + // This statement gives an error // if err := json.Unmarshal([]byte(req.Body), &request); err != nil { // return errToResponse(err, http.StatusBadRequest), nil @@ -63,14 +96,21 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP if crowdactionID == "" { status := req.QueryStringParameters["status"] - switch status { - case "": - status = "joinable" - case "featured": - status = "joinable" - } // get all crowdactions + return getAllCrowdactions(ctx, status) } + + // This switch statement is useless + // if crowdactionID == "" { + // status := req.QueryStringParameters["status"] + // switch status { + // case "": + // status = "joinable" + // case "featured": + // status = "joinable" + // } + // // get all crowdactions + // } // get crowdaction by ID return getCrowdactionByID(ctx, crowdactionID) } diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index 87c424c..f4b4d42 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -98,14 +98,14 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* return result.Item, nil } -func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, *utils.PrimaryKey, error) { +func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { // var crowdactions models.CrowdactionData crowdactions := []models.CrowdactionData{} keyCond := expression.Key(utils.PartitionKey).Equal(expression.Value(utils.PKCrowdaction)) expr, err := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() if err != nil { - return crowdactions, nil, err + return crowdactions, err } var exclusiveStartKey utils.PrimaryKey @@ -148,7 +148,7 @@ func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom = &exclusiveStartKey } - return crowdactions, startFrom, err + return crowdactions, err } func (s *Dynamo) PutDBItem(tableName string, pk string, sk string, record interface{}) error { From b555b09c94b810b1a35d5ebe71ebeced4cc89033 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 19 Mar 2022 16:04:34 +0100 Subject: [PATCH 14/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20cleaning?= =?UTF-8?q?=20up,=20commitment=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 5 +-- internal/models/commitment.go | 8 ++++ internal/models/crowdaction.go | 2 +- pkg/handler/aws/crowdaction/main.go | 62 +++++++--------------------- pkg/repository/aws/dynamo.go | 5 +-- 5 files changed, 27 insertions(+), 55 deletions(-) create mode 100644 internal/models/commitment.go diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 11fdc56..74338b7 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -20,7 +20,7 @@ type DynamoRepository interface { } type Service interface { - GetCrowdaction(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) + GetCrowdactionById(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } type crowdaction struct { @@ -34,14 +34,13 @@ const ( ) func NewCrowdactionService(dynamodb DynamoRepository) Service { - // fmt.Println("NewCrowdactionService") return &crowdaction{dynamodb: dynamodb} } /** GET Crowdaction by Id **/ -func (e *crowdaction) GetCrowdaction(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { +func (e *crowdaction) GetCrowdactionById(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { // fmt.Println("GetCrowdaction calling internal:", crowdactionID) item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionID) if err != nil { diff --git a/internal/models/commitment.go b/internal/models/commitment.go new file mode 100644 index 0000000..e8dac0c --- /dev/null +++ b/internal/models/commitment.go @@ -0,0 +1,8 @@ +package models + +type CommitmentOption struct { + Id string `json:"id"` + Label string `json:"label"` + Description string `json:"description"` + Requires []CommitmentOption `json:"requires,omitempty"` +} diff --git a/internal/models/crowdaction.go b/internal/models/crowdaction.go index 11e03d1..67ec0c9 100644 --- a/internal/models/crowdaction.go +++ b/internal/models/crowdaction.go @@ -28,5 +28,5 @@ type CrowdactionData struct { ParticipationCount int `json:"participant_count"` TopParticipants []CrowdactionParticipant `json:"top_participants"` Images CrowdactionImages `json:"images"` - // CommitmentOptions []CommitmentOption `json:"commitment_options"` + CommitmentOptions []CommitmentOption `json:"commitment_options"` } diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index c3e3d1f..55744cc 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -18,7 +18,7 @@ import ( func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { dynamoRepository := awsRepository.NewDynamo() - getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdaction(ctx, crowdactionID) + getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionById(ctx, crowdactionID) if err != nil { return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil @@ -27,8 +27,6 @@ func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGa return utils.CreateMessageHttpResponse(http.StatusNotFound, "not participating"), nil } - fmt.Println("getCrowdaction", getCrowdaction) - jsonPayload, _ := json.Marshal(getCrowdaction) return events.APIGatewayV2HTTPResponse{ Body: string(jsonPayload), @@ -36,42 +34,25 @@ func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGa }, nil } -func getAllCrowdactions(ctx context.Context, status string) (events.APIGatewayV2HTTPResponse, error) { +func getCrowdactionsByStatus(ctx context.Context, status string) (events.APIGatewayV2HTTPResponse, error) { dynamoRepository := awsRepository.NewDynamo() var startFrom *utils.PrimaryKey - getAllCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, startFrom) + getCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, startFrom) + if err != nil { return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } - - jsonPayload, _ := json.Marshal(getAllCrowdactions) - return events.APIGatewayV2HTTPResponse{ - Body: string(jsonPayload), - StatusCode: http.StatusOK, - }, nil + } else { + jsonPayload, err := json.Marshal(getCrowdactions) - // var crowdactions []models.Crowdaction - // var err error + if err != nil { + return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil + } - // /* TODO Send password for handling in app for MVP - // for i; i < len(crowdactions); i++) { - // if crowdactions[i].PasswordJoin != "" { - // crowdactions[i].PasswordJoin = passwordRequired - // } - // } - // */ - // if err != nil { - // return utils.GetMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - // } else { - // body, err := json.Marshal(crowdactions) - // if err != nil { - // return utils.GetMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - // } - // return events.APIGatewayProxyResponse{ - // Body: string(body), - // StatusCode: http.StatusOK, - // }, nil - // } + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil + } } func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { @@ -96,22 +77,9 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP if crowdactionID == "" { status := req.QueryStringParameters["status"] - // get all crowdactions - return getAllCrowdactions(ctx, status) + return getCrowdactionsByStatus(ctx, status) } - // This switch statement is useless - // if crowdactionID == "" { - // status := req.QueryStringParameters["status"] - // switch status { - // case "": - // status = "joinable" - // case "featured": - // status = "joinable" - // } - // // get all crowdactions - // } - // get crowdaction by ID return getCrowdactionByID(ctx, crowdactionID) } diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index f4b4d42..3c60f7f 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -48,7 +48,6 @@ type UpdateItemData struct { } func NewDynamo() *Dynamo { - fmt.Println("New Dynamo Session") sess := session.Must(session.NewSession()) return &Dynamo{dbClient: dynamodb.New(sess)} } @@ -124,13 +123,11 @@ func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, FilterExpression: expr.Filter(), }) - // err = dynamodbattribute.UnmarshalMap(result, &crowdactions) - for _, item := range result.Items { var crowdaction models.CrowdactionData err := dynamodbattribute.UnmarshalMap(item, &crowdaction) - if err == nil { // have to figure out this error + if err == nil { crowdactions = append(crowdactions, crowdaction) } } From 841b968556714b995e49e4169ef23e127f3fba05 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sun, 20 Mar 2022 17:33:48 +0100 Subject: [PATCH 15/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20including?= =?UTF-8?q?=20the=20mock=20repository=20for=20dynamo=20and=20crowdaction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/mocks/repository/dynamoManager.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 pkg/mocks/repository/dynamoManager.go diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go new file mode 100644 index 0000000..cc119f4 --- /dev/null +++ b/pkg/mocks/repository/dynamoManager.go @@ -0,0 +1,17 @@ +package repository + +import ( + "context" + + "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/stretchr/testify/mock" +) + +type Dynamo struct { + mock.Mock +} + +func (d *Dynamo) GetCrowdactionById(ctx context.Context, data models.CrowdactionData) error { + args := d.Called(ctx, data) + return args.Error(0) +} From 483e006be11fd0a7580979fa91b88830f98081eb Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sun, 20 Mar 2022 17:56:16 +0100 Subject: [PATCH 16/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20modifying?= =?UTF-8?q?=20the=20mock=20repository=20to=20include=20GetCrowdactionBySta?= =?UTF-8?q?tus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/mocks/repository/dynamoManager.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index cc119f4..d79f053 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -3,7 +3,8 @@ package repository import ( "context" - "github.com/CollActionteam/collaction_backend/internal/models" + models "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/mock" ) @@ -11,7 +12,12 @@ type Dynamo struct { mock.Mock } -func (d *Dynamo) GetCrowdactionById(ctx context.Context, data models.CrowdactionData) error { - args := d.Called(ctx, data) +func (d *Dynamo) GetCrowdactionById(ctx context.Context, crowdactionID string) error { + args := d.Called(ctx, crowdactionID) return args.Error(0) } + +func (d *Dynamo) GetCrowdactionByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { + args := d.Called(ctx, status, startFrom) + return args.Get(0).([]models.CrowdactionData), args.Error(1) +} From 9ce295a4ead3adeaf5750ab7ad10abd491d228a2 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sun, 20 Mar 2022 17:59:47 +0100 Subject: [PATCH 17/38] =?UTF-8?q?=F0=9F=9A=A7=20[crowdaction]=20removed=20?= =?UTF-8?q?unnecessary=20comments,=20per=20the=20feedback=20on=20pull=20re?= =?UTF-8?q?quest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/crowdactions/crowdaction.go | 9 ++------- pkg/handler/aws/crowdaction/README.md | 0 pkg/handler/aws/crowdaction/main.go | 9 +-------- pkg/repository/aws/dynamo.go | 2 +- 4 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 pkg/handler/aws/crowdaction/README.md diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 74338b7..03b765e 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -12,13 +12,10 @@ import ( "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) -const Separator = "### app version:" - type DynamoRepository interface { GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } - type Service interface { GetCrowdactionById(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) @@ -41,13 +38,13 @@ func NewCrowdactionService(dynamodb DynamoRepository) Service { GET Crowdaction by Id **/ func (e *crowdaction) GetCrowdactionById(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { - // fmt.Println("GetCrowdaction calling internal:", crowdactionID) + fmt.Println("GetCrowdaction calling internal:", crowdactionID) item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionID) if err != nil { return nil, err } if item == nil { - return nil, fmt.Errorf("Crowdaction not found") + return nil, fmt.Errorf("crowdaction not found") } var crowdaction models.CrowdactionData err = dynamodbattribute.UnmarshalMap(item, &crowdaction) @@ -62,8 +59,6 @@ func (e *crowdaction) GetCrowdactionsByStatus(ctx context.Context, status string switch status { case "joinable": - // call joinable crowdaction list - // crowdactions, _, err = models.ListJoinableCrowdactions(tableName, nil) // TODO future filterCond := expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) return items, err diff --git a/pkg/handler/aws/crowdaction/README.md b/pkg/handler/aws/crowdaction/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index 55744cc..d00b74d 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -17,6 +17,7 @@ import ( ) func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { + fmt.Println("getCrowdactionByID handler: crowdactionID ", crowdactionID) dynamoRepository := awsRepository.NewDynamo() getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionById(ctx, crowdactionID) @@ -61,14 +62,6 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest - //dynamoRepository := awsRepository.NewDynamo() // should pass this dynamo variable - - // This statement gives an error - // if err := json.Unmarshal([]byte(req.Body), &request); err != nil { - // return errToResponse(err, http.StatusBadRequest), nil - // } - - // Do we really need validation for this type of requests? validate := validator.New() if err := validate.StructCtx(ctx, request); err != nil { body, _ := json.Marshal(hnd.Response{Status: hnd.StatusFail, Data: map[string]interface{}{"error": utils.ValidationResponse(err, validate)}}) diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index 3c60f7f..c83f451 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -74,7 +74,7 @@ func (s *Dynamo) GetPrimaryKey(pk string, sk string) PrimaryKey { } func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]*dynamodb.AttributeValue, error) { - // fmt.Println("Calling GetDBItem", tableName, pk, sk) + fmt.Println("Calling GetDBItem", tableName, pk, sk) result, err := s.dbClient.GetItem(&dynamodb.GetItemInput{ TableName: &tableName, From 8c5c28095c7aea596780fbd039d268aa3dfd893f Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 23 Mar 2022 17:24:19 +0100 Subject: [PATCH 18/38] [pull request] removing samconfig file from history --- samconfig.yaml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 samconfig.yaml diff --git a/samconfig.yaml b/samconfig.yaml deleted file mode 100644 index 14cadb8..0000000 --- a/samconfig.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version = 0.1 -[default] -[default.deploy] -[default.deploy.parameters] -s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1xoanv4heoh1g" -s3_prefix = "collaction-dev-edreinoso" -stack_name = "collaction-dev-edreinoso" -region = "eu-central-1" -confirm_changeset = true -capabilities = "CAPABILITY_IAM" -image_repositories = [] -parameter_overrides = "Stage=\"dev\" FirebaseProjectId=\"collaction-52ca9\" DomainParameter=\"\" SubdomainSuffixParameter=\"\" HostedZoneIdParameter=\"\" AcmCertificateArnParameter=\"\"" From 99f52ef0a458f569847e5bcbda255d969cc28e11 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 23 Mar 2022 17:25:12 +0100 Subject: [PATCH 19/38] [pull request] ignoring samconfig file as per the pull request --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2ad12b0..9a84bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,6 @@ _ignored/ # MacOS .DS_Store -.idea \ No newline at end of file +.idea + +samconfig.yaml \ No newline at end of file From 4dc778923598e789caf3db1450a6b99342ede834 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 23 Mar 2022 17:36:47 +0100 Subject: [PATCH 20/38] [pull request] modified naming for the internal interface --- internal/crowdactions/crowdaction.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 03b765e..86d55dc 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -12,7 +12,7 @@ import ( "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) -type DynamoRepository interface { +type CrowdactionRepository interface { GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } @@ -21,7 +21,7 @@ type Service interface { GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } type crowdaction struct { - dynamodb DynamoRepository + dynamodb CrowdactionRepository } const ( @@ -30,7 +30,7 @@ const ( KeyDateJoinBefore = "date_limit_join" ) -func NewCrowdactionService(dynamodb DynamoRepository) Service { +func NewCrowdactionService(dynamodb CrowdactionRepository) Service { return &crowdaction{dynamodb: dynamodb} } From 18aa9636f17bc59c03d9aa86beb31b558b85841e Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 23 Mar 2022 17:50:17 +0100 Subject: [PATCH 21/38] [pull request] getting rid of useless else statement --- pkg/handler/aws/crowdaction/main.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index d00b74d..b23ed45 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -3,7 +3,6 @@ package main import ( "context" "encoding/json" - "fmt" "net/http" cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" @@ -17,7 +16,6 @@ import ( ) func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { - fmt.Println("getCrowdactionByID handler: crowdactionID ", crowdactionID) dynamoRepository := awsRepository.NewDynamo() getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionById(ctx, crowdactionID) @@ -42,24 +40,18 @@ func getCrowdactionsByStatus(ctx context.Context, status string) (events.APIGate if err != nil { return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } else { - jsonPayload, err := json.Marshal(getCrowdactions) + } + jsonPayload, _ := json.Marshal(getCrowdactions) - if err != nil { - return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil - return events.APIGatewayV2HTTPResponse{ - Body: string(jsonPayload), - StatusCode: http.StatusOK, - }, nil - } } func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { crowdactionID := req.PathParameters["crowdactionID"] - - fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest validate := validator.New() From 8fb01c0109178b58777bca0205ffa28760d07aa7 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Thu, 24 Mar 2022 12:19:26 +0100 Subject: [PATCH 22/38] [pull request] removing dynamodb dependencies in logic --- internal/crowdactions/crowdaction.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 86d55dc..6670347 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -7,14 +7,11 @@ import ( "github.com/CollActionteam/collaction_backend/internal/constants" "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" - "github.com/aws/aws-sdk-go/service/dynamodb" - "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" - "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) type CrowdactionRepository interface { - GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) - Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) + GetDBItem(tableName string, pk string, crowdactionId string) (*models.CrowdactionData, error) + Query(tableName string, filterCond string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) } type Service interface { GetCrowdactionById(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) @@ -46,9 +43,7 @@ func (e *crowdaction) GetCrowdactionById(ctx context.Context, crowdactionID stri if item == nil { return nil, fmt.Errorf("crowdaction not found") } - var crowdaction models.CrowdactionData - err = dynamodbattribute.UnmarshalMap(item, &crowdaction) - return &crowdaction, err + return item, err } /** @@ -59,16 +54,13 @@ func (e *crowdaction) GetCrowdactionsByStatus(ctx context.Context, status string switch status { case "joinable": - filterCond := expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + items, err := e.dynamodb.Query(constants.TableName, KeyDateJoinBefore, startFrom) return items, err case "active": - filterCond := expression.Name(KeyDateStart).LessThanEqual(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + items, err := e.dynamodb.Query(constants.TableName, KeyDateStart, startFrom) return items, err case "ended": - filterCond := expression.Name(KeyDateEnd).LessThanEqual(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) + items, err := e.dynamodb.Query(constants.TableName, KeyDateEnd, startFrom) return items, err default: return crowdactions, nil From a47a23bae6fcc20179db19e115ac1423c59167d7 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Thu, 24 Mar 2022 22:45:21 +0100 Subject: [PATCH 23/38] [pull request] including mock repository and crowdaction test --- internal/crowdactions/crowdaction_test.go | 31 +++++++++++++++++++++++ pkg/mocks/repository/dynamoManager.go | 12 ++++----- 2 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 internal/crowdactions/crowdaction_test.go diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go new file mode 100644 index 0000000..5cf0076 --- /dev/null +++ b/internal/crowdactions/crowdaction_test.go @@ -0,0 +1,31 @@ +package crowdaction_test + +import ( + "context" + "fmt" + "testing" + + cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" + "github.com/CollActionteam/collaction_backend/pkg/mocks/repository" + "github.com/stretchr/testify/assert" +) + +func TestCrowdaction_GetCrowdactionById(t *testing.T, ctx context.Context) { + as := assert.New(t) + dynamoRepository := &repository.Dynamo{} + crowdactionID := "Helloworld2" + + t.Run("dev stage", func(t *testing.T) { + dynamoRepository.On("Send", context.Background(), crowdactionID).Return(nil).Once() + + service := cwd.NewCrowdactionService(dynamoRepository) + + crowdaction, err := service.GetCrowdactionById(ctx, crowdactionID) + + fmt.Printf("Hello world", crowdaction) + + as.NoError(err) + + dynamoRepository.AssertExpectations(t) + }) +} diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index d79f053..90eb984 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -1,8 +1,6 @@ package repository import ( - "context" - models "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/mock" @@ -12,12 +10,12 @@ type Dynamo struct { mock.Mock } -func (d *Dynamo) GetCrowdactionById(ctx context.Context, crowdactionID string) error { - args := d.Called(ctx, crowdactionID) - return args.Error(0) +func (d *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.CrowdactionData, error) { + args := d.Called(tableName, pk, sk) + return args.Get(0).(*models.CrowdactionData), args.Error(1) } -func (d *Dynamo) GetCrowdactionByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - args := d.Called(ctx, status, startFrom) +func (d *Dynamo) Query(tableName string, filter string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { + args := d.Called(tableName, filter, startFrom) return args.Get(0).([]models.CrowdactionData), args.Error(1) } From 39c74174d32442563a70f23bd66a11539f565f99 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Thu, 24 Mar 2022 22:45:50 +0100 Subject: [PATCH 24/38] [pull request] cleaning up some unnecessary lines --- pkg/handler/aws/crowdaction/main.go | 1 - pkg/repository/aws/dynamo.go | 17 ++++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index b23ed45..afa316e 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -47,7 +47,6 @@ func getCrowdactionsByStatus(ctx context.Context, status string) (events.APIGate Body: string(jsonPayload), StatusCode: http.StatusOK, }, nil - } func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index c83f451..71f8831 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -73,9 +73,8 @@ func (s *Dynamo) GetPrimaryKey(pk string, sk string) PrimaryKey { } } -func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]*dynamodb.AttributeValue, error) { - fmt.Println("Calling GetDBItem", tableName, pk, sk) - +func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.CrowdactionData, error) { + var crowdaction models.CrowdactionData result, err := s.dbClient.GetItem(&dynamodb.GetItemInput{ TableName: &tableName, Key: s.GetPrimaryKey(pk, sk), @@ -84,7 +83,7 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == dynamodb.ErrCodeResourceNotFoundException { - err = nil // Just return nil (not found is not an error) + err = nil } } return nil, err @@ -93,12 +92,12 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* return nil, nil } - // fmt.Println("result from query: ", result) - return result.Item, nil + err = dynamodbattribute.UnmarshalMap(result.Item, &crowdaction) + return &crowdaction, err } -func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - // var crowdactions models.CrowdactionData +func (s *Dynamo) Query(tableName string, filter string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { + filterCond := expression.Name(filter).GreaterThan(expression.Value(utils.GetDateStringNow())) crowdactions := []models.CrowdactionData{} keyCond := expression.Key(utils.PartitionKey).Equal(expression.Value(utils.PKCrowdaction)) expr, err := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() @@ -133,7 +132,7 @@ func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, } if len(result.Items) != len(crowdactions) { - err = fmt.Errorf("Error unmarshelling %d items", len(result.Items)-len(crowdactions)) + err = fmt.Errorf("error unmarshelling %d items", len(result.Items)-len(crowdactions)) } startFrom = nil From 525b2b496f0f31f261e4fae4552dd2ef6a10e31e Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 16:20:06 +0200 Subject: [PATCH 25/38] [pull request] separating repository concerns --- internal/crowdactions/crowdaction.go | 56 +++++---------- pkg/repository/aws/crowdactionManager.go | 89 ++++++++++++++++++++++++ pkg/repository/aws/dynamo.go | 44 ++---------- 3 files changed, 113 insertions(+), 76 deletions(-) create mode 100644 pkg/repository/aws/crowdactionManager.go diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 6670347..804f650 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -4,21 +4,17 @@ import ( "context" "fmt" - "github.com/CollActionteam/collaction_backend/internal/constants" - "github.com/CollActionteam/collaction_backend/internal/models" + m "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" ) -type CrowdactionRepository interface { - GetDBItem(tableName string, pk string, crowdactionId string) (*models.CrowdactionData, error) - Query(tableName string, filterCond string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) -} type Service interface { - GetCrowdactionById(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) - GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) + GetCrowdactionById(ctx context.Context, crowdactionId string) (*m.CrowdactionData, error) + GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) } -type crowdaction struct { - dynamodb CrowdactionRepository +type CrowdactionManager interface { + GetById(pk string, crowdactionId string) (*m.CrowdactionData, error) + GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) } const ( @@ -27,42 +23,26 @@ const ( KeyDateJoinBefore = "date_limit_join" ) -func NewCrowdactionService(dynamodb CrowdactionRepository) Service { - return &crowdaction{dynamodb: dynamodb} +type crowdactionService struct { + crowdactionRepository CrowdactionManager +} + +func NewCrowdactionService(crowdactionRepository CrowdactionManager) Service { + return &crowdactionService{crowdactionRepository: crowdactionRepository} } /** GET Crowdaction by Id **/ -func (e *crowdaction) GetCrowdactionById(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { - fmt.Println("GetCrowdaction calling internal:", crowdactionID) - item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionID) - if err != nil { - return nil, err - } - if item == nil { - return nil, fmt.Errorf("crowdaction not found") - } - return item, err +func (e *crowdactionService) GetCrowdactionById(ctx context.Context, crowdactionID string) (*m.CrowdactionData, error) { + fmt.Println("GetCrowdactionById", crowdactionID) + return e.crowdactionRepository.GetById(utils.PKCrowdaction, crowdactionID) } /** GET Crowdaction by Status **/ -func (e *crowdaction) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - crowdactions := []models.CrowdactionData{} // empty crowdaction array - - switch status { - case "joinable": - items, err := e.dynamodb.Query(constants.TableName, KeyDateJoinBefore, startFrom) - return items, err - case "active": - items, err := e.dynamodb.Query(constants.TableName, KeyDateStart, startFrom) - return items, err - case "ended": - items, err := e.dynamodb.Query(constants.TableName, KeyDateEnd, startFrom) - return items, err - default: - return crowdactions, nil - } +func (e *crowdactionService) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { + fmt.Println("GetCrowdactionsByStatus", status, startFrom) + return e.crowdactionRepository.GetByStatus(status, startFrom) } diff --git a/pkg/repository/aws/crowdactionManager.go b/pkg/repository/aws/crowdactionManager.go new file mode 100644 index 0000000..fb29b7b --- /dev/null +++ b/pkg/repository/aws/crowdactionManager.go @@ -0,0 +1,89 @@ +package aws + +import ( + "fmt" + + "github.com/CollActionteam/collaction_backend/internal/constants" + m "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/utils" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" +) + +type Crowdaction interface { + GetById(pk string, sk string) (*m.CrowdactionData, error) + GetByStatus(status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) +} + +const ( + KeyDateStart = "date_start" + KeyDateEnd = "date_end" + KeyDateJoinBefore = "date_limit_join" +) + +type crowdaction struct { + dbClient *Dynamo +} + +func NewCrowdaction(dynamo *Dynamo) Crowdaction { + return &crowdaction{dbClient: dynamo} +} + +/** + GET Crowdaction by Id +**/ +func (s *crowdaction) GetById(pk string, sk string) (*m.CrowdactionData, error) { + item, err := s.dbClient.GetDBItem(constants.TableName, pk, sk) + + if item == nil || err != nil { + return nil, err + } + + var c m.CrowdactionData + err = dynamodbattribute.UnmarshalMap(item, &c) + + return &c, err +} + +/** + GET Crowdaction by Status +**/ +func (s *crowdaction) GetByStatus(status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { + crowdactions := []m.CrowdactionData{} + var filterCond expression.ConditionBuilder + + switch status { + case "joinable": + filterCond = expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: joinable", filterCond) + case "active": + filterCond = expression.Name(KeyDateStart).LessThanEqual(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: active", filterCond) + case "ended": + filterCond = expression.Name(KeyDateEnd).LessThanEqual(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: ended", filterCond) + default: + fmt.Println("None of the edge cases matched") + } + + items, err := s.dbClient.Query(constants.TableName, filterCond, startFrom) + + if items == nil || err != nil { + return nil, err + } + + for _, foo := range items { + var crowdaction m.CrowdactionData + err := dynamodbattribute.UnmarshalMap(foo, &crowdaction) + + if err == nil { + crowdactions = append(crowdactions, crowdaction) + } + } + + if len(items) != len(crowdactions) { + err = fmt.Errorf("error unmarshelling %d items", len(items)-len(crowdactions)) + } + + return crowdactions, err +} diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index 71f8831..0698ba8 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/CollActionteam/collaction_backend/internal/constants" - "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -73,8 +72,7 @@ func (s *Dynamo) GetPrimaryKey(pk string, sk string) PrimaryKey { } } -func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.CrowdactionData, error) { - var crowdaction models.CrowdactionData +func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]*dynamodb.AttributeValue, error) { result, err := s.dbClient.GetItem(&dynamodb.GetItemInput{ TableName: &tableName, Key: s.GetPrimaryKey(pk, sk), @@ -83,7 +81,7 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.Crow if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == dynamodb.ErrCodeResourceNotFoundException { - err = nil + err = nil // Just return nil (not found is not an error) } } return nil, err @@ -91,20 +89,12 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.Crow if result == nil { return nil, nil } - - err = dynamodbattribute.UnmarshalMap(result.Item, &crowdaction) - return &crowdaction, err + return result.Item, nil } -func (s *Dynamo) Query(tableName string, filter string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - filterCond := expression.Name(filter).GreaterThan(expression.Value(utils.GetDateStringNow())) - crowdactions := []models.CrowdactionData{} +func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]map[string]*dynamodb.AttributeValue, error) { keyCond := expression.Key(utils.PartitionKey).Equal(expression.Value(utils.PKCrowdaction)) - expr, err := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() - - if err != nil { - return crowdactions, err - } + expr, _ := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() var exclusiveStartKey utils.PrimaryKey @@ -122,29 +112,7 @@ func (s *Dynamo) Query(tableName string, filter string, startFrom *utils.Primary FilterExpression: expr.Filter(), }) - for _, item := range result.Items { - var crowdaction models.CrowdactionData - err := dynamodbattribute.UnmarshalMap(item, &crowdaction) - - if err == nil { - crowdactions = append(crowdactions, crowdaction) - } - } - - if len(result.Items) != len(crowdactions) { - err = fmt.Errorf("error unmarshelling %d items", len(result.Items)-len(crowdactions)) - } - - startFrom = nil - - if result.LastEvaluatedKey != nil && len(result.LastEvaluatedKey) > 0 { - lastPK := result.LastEvaluatedKey[utils.PartitionKey].S - lastSK := result.LastEvaluatedKey[utils.SortKey].S - exclusiveStartKey = utils.GetPrimaryKey(*lastPK, *lastSK) - startFrom = &exclusiveStartKey - } - - return crowdactions, err + return result.Items, err } func (s *Dynamo) PutDBItem(tableName string, pk string, sk string, record interface{}) error { From 595b73703ce4398c949c0332102b12a0396edd9a Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 16:21:00 +0200 Subject: [PATCH 26/38] [pull request] modifying test cases with new repository structure --- internal/crowdactions/crowdaction_test.go | 2 +- pkg/mocks/repository/dynamoManager.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index 5cf0076..379b66e 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -22,7 +22,7 @@ func TestCrowdaction_GetCrowdactionById(t *testing.T, ctx context.Context) { crowdaction, err := service.GetCrowdactionById(ctx, crowdactionID) - fmt.Printf("Hello world", crowdaction) + fmt.Println("Hello world", crowdaction) as.NoError(err) diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index 90eb984..a868639 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -10,12 +10,12 @@ type Dynamo struct { mock.Mock } -func (d *Dynamo) GetDBItem(tableName string, pk string, sk string) (*models.CrowdactionData, error) { - args := d.Called(tableName, pk, sk) +func (d *Dynamo) GetById(pk string, sk string) (*models.CrowdactionData, error) { + args := d.Called(pk, sk) return args.Get(0).(*models.CrowdactionData), args.Error(1) } -func (d *Dynamo) Query(tableName string, filter string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - args := d.Called(tableName, filter, startFrom) +func (d *Dynamo) GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { + args := d.Called(filterCond, startFrom) return args.Get(0).([]models.CrowdactionData), args.Error(1) } From 98f45af7afdf84d1fc8036bda16805ea8aa42073 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 16:21:44 +0200 Subject: [PATCH 27/38] [pull request] changing dynamo repository call from crowdaction main handler --- pkg/handler/aws/crowdaction/main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index afa316e..dc32435 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -16,7 +16,7 @@ import ( ) func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { - dynamoRepository := awsRepository.NewDynamo() + dynamoRepository := awsRepository.NewCrowdaction(awsRepository.NewDynamo()) getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionById(ctx, crowdactionID) if err != nil { @@ -34,9 +34,8 @@ func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGa } func getCrowdactionsByStatus(ctx context.Context, status string) (events.APIGatewayV2HTTPResponse, error) { - dynamoRepository := awsRepository.NewDynamo() - var startFrom *utils.PrimaryKey - getCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, startFrom) + dynamoRepository := awsRepository.NewCrowdaction(awsRepository.NewDynamo()) + getCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, nil) if err != nil { return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil From 45cb5932ad8dae05aef9d41bde354ba05ab20172 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 16:27:49 +0200 Subject: [PATCH 28/38] [pull request] changing parameters to pass unit test case --- internal/crowdactions/crowdaction_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index 379b66e..342cd38 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -10,9 +10,10 @@ import ( "github.com/stretchr/testify/assert" ) -func TestCrowdaction_GetCrowdactionById(t *testing.T, ctx context.Context) { +func TestCrowdaction_GetCrowdactionById(t *testing.T) { as := assert.New(t) dynamoRepository := &repository.Dynamo{} + var ctx context.Context crowdactionID := "Helloworld2" t.Run("dev stage", func(t *testing.T) { From 93138e25040e70c5c82fb01237e54b3cb5fcc8df Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 16:33:45 +0200 Subject: [PATCH 29/38] [pull request] changing crowdactionID from test case --- internal/crowdactions/crowdaction_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index 342cd38..df7b5ad 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -14,7 +14,7 @@ func TestCrowdaction_GetCrowdactionById(t *testing.T) { as := assert.New(t) dynamoRepository := &repository.Dynamo{} var ctx context.Context - crowdactionID := "Helloworld2" + crowdactionID := "sustainability#food#185f66fd" t.Run("dev stage", func(t *testing.T) { dynamoRepository.On("Send", context.Background(), crowdactionID).Return(nil).Once() From f03c63a66d0b29b42c66d021948248a3aaa94b55 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Mon, 28 Mar 2022 17:34:00 +0200 Subject: [PATCH 30/38] [pull request] changing method call for crowdaction test --- internal/crowdactions/crowdaction_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index df7b5ad..8ff639a 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -17,7 +17,7 @@ func TestCrowdaction_GetCrowdactionById(t *testing.T) { crowdactionID := "sustainability#food#185f66fd" t.Run("dev stage", func(t *testing.T) { - dynamoRepository.On("Send", context.Background(), crowdactionID).Return(nil).Once() + dynamoRepository.On("GetById", context.Background(), crowdactionID).Return(nil).Once() service := cwd.NewCrowdactionService(dynamoRepository) From 8449139843b29b7d4adee3c8a8ab688777e4fe0e Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Tue, 29 Mar 2022 10:43:21 +0200 Subject: [PATCH 31/38] [pull request] fixing parameter issue in crowdaction_test --- internal/crowdactions/crowdaction_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index 8ff639a..a22842e 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -7,6 +7,7 @@ import ( cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" "github.com/CollActionteam/collaction_backend/pkg/mocks/repository" + "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/assert" ) @@ -17,7 +18,7 @@ func TestCrowdaction_GetCrowdactionById(t *testing.T) { crowdactionID := "sustainability#food#185f66fd" t.Run("dev stage", func(t *testing.T) { - dynamoRepository.On("GetById", context.Background(), crowdactionID).Return(nil).Once() + dynamoRepository.On("GetById", utils.PKCrowdaction, crowdactionID).Return(nil).Once() service := cwd.NewCrowdactionService(dynamoRepository) From 14f671af677054e6c0e7af1ac832eacc87765688 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Tue, 29 Mar 2022 10:52:56 +0200 Subject: [PATCH 32/38] [pull request] testing issue with the args.get(x) call in mock/dynamo repository --- pkg/mocks/repository/dynamoManager.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index a868639..3158b8b 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -1,6 +1,8 @@ package repository import ( + "fmt" + models "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/mock" @@ -12,6 +14,10 @@ type Dynamo struct { func (d *Dynamo) GetById(pk string, sk string) (*models.CrowdactionData, error) { args := d.Called(pk, sk) + fmt.Println("Before the args") + fmt.Println("Args", args) + fmt.Println("Args", args.Get(0)) + fmt.Println("After the args") return args.Get(0).(*models.CrowdactionData), args.Error(1) } From 09ed55a7a05bd69fa5a57634a4c605fe2db05efe Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Tue, 29 Mar 2022 11:02:08 +0200 Subject: [PATCH 33/38] [pull request] including Mock in each of the function calls from the dynamo repository --- pkg/mocks/repository/dynamoManager.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index 3158b8b..1a2d2f4 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -13,7 +13,7 @@ type Dynamo struct { } func (d *Dynamo) GetById(pk string, sk string) (*models.CrowdactionData, error) { - args := d.Called(pk, sk) + args := d.Mock.Called(pk, sk) fmt.Println("Before the args") fmt.Println("Args", args) fmt.Println("Args", args.Get(0)) @@ -22,6 +22,6 @@ func (d *Dynamo) GetById(pk string, sk string) (*models.CrowdactionData, error) } func (d *Dynamo) GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - args := d.Called(filterCond, startFrom) + args := d.Mock.Called(filterCond, startFrom) return args.Get(0).([]models.CrowdactionData), args.Error(1) } From 589a25ced77940129a0fb0a0125d673254e3f5fc Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Tue, 29 Mar 2022 11:44:12 +0200 Subject: [PATCH 34/38] [pull request] modifying test cases for crowdaction --- internal/crowdactions/crowdaction_test.go | 5 ++++- pkg/mocks/repository/dynamoManager.go | 16 +++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go index a22842e..5ae810a 100644 --- a/internal/crowdactions/crowdaction_test.go +++ b/internal/crowdactions/crowdaction_test.go @@ -6,7 +6,9 @@ import ( "testing" cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" + m "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/pkg/mocks/repository" + "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/assert" ) @@ -15,10 +17,11 @@ func TestCrowdaction_GetCrowdactionById(t *testing.T) { as := assert.New(t) dynamoRepository := &repository.Dynamo{} var ctx context.Context + var crowdactions *m.CrowdactionData crowdactionID := "sustainability#food#185f66fd" t.Run("dev stage", func(t *testing.T) { - dynamoRepository.On("GetById", utils.PKCrowdaction, crowdactionID).Return(nil).Once() + dynamoRepository.On("GetById", utils.PKCrowdaction, crowdactionID).Return(crowdactions, nil).Once() service := cwd.NewCrowdactionService(dynamoRepository) diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index 1a2d2f4..3d37bab 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -1,9 +1,7 @@ package repository import ( - "fmt" - - models "github.com/CollActionteam/collaction_backend/internal/models" + m "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/mock" ) @@ -12,16 +10,12 @@ type Dynamo struct { mock.Mock } -func (d *Dynamo) GetById(pk string, sk string) (*models.CrowdactionData, error) { +func (d *Dynamo) GetById(pk string, sk string) (*m.CrowdactionData, error) { args := d.Mock.Called(pk, sk) - fmt.Println("Before the args") - fmt.Println("Args", args) - fmt.Println("Args", args.Get(0)) - fmt.Println("After the args") - return args.Get(0).(*models.CrowdactionData), args.Error(1) + return args.Get(0).(*m.CrowdactionData), args.Error(1) } -func (d *Dynamo) GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { +func (d *Dynamo) GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { args := d.Mock.Called(filterCond, startFrom) - return args.Get(0).([]models.CrowdactionData), args.Error(1) + return args.Get(0).([]m.CrowdactionData), args.Error(1) } From 72c469fcf8d54fce694d2ebafa396ef0cfede1d9 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Wed, 23 Mar 2022 17:24:19 +0100 Subject: [PATCH 35/38] [pull request] changes done based on feedback [pull request] ignoring samconfig file as per the pull request [pull request] modified naming for the internal interface [pull request] getting rid of useless else statement [pull request] removing dynamodb dependencies in logic [pull request] including mock repository and crowdaction test [pull request] cleaning up some unnecessary lines [pull request] separating repository concerns [pull request] modifying test cases with new repository structure [pull request] changing dynamo repository call from crowdaction main handler [pull request] changing parameters to pass unit test case [pull request] changing crowdactionID from test case [pull request] changing method call for crowdaction test [pull request] fixing parameter issue in crowdaction_test [pull request] testing issue with the args.get(x) call in mock/dynamo repository [pull request] including Mock in each of the function calls from the dynamo repository [pull request] modifying test cases for crowdaction --- .gitignore | 4 +- internal/crowdactions/crowdaction.go | 64 +++++----------- internal/crowdactions/crowdaction_test.go | 36 +++++++++ pkg/handler/aws/crowdaction/main.go | 28 +++---- pkg/mocks/repository/dynamoManager.go | 16 ++-- pkg/repository/aws/crowdactionManager.go | 89 +++++++++++++++++++++++ pkg/repository/aws/dynamo.go | 39 +--------- samconfig.yaml | 12 --- 8 files changed, 165 insertions(+), 123 deletions(-) create mode 100644 internal/crowdactions/crowdaction_test.go create mode 100644 pkg/repository/aws/crowdactionManager.go delete mode 100644 samconfig.yaml diff --git a/.gitignore b/.gitignore index 2ad12b0..9a84bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,6 @@ _ignored/ # MacOS .DS_Store -.idea \ No newline at end of file +.idea + +samconfig.yaml \ No newline at end of file diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 03b765e..804f650 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -4,24 +4,17 @@ import ( "context" "fmt" - "github.com/CollActionteam/collaction_backend/internal/constants" - "github.com/CollActionteam/collaction_backend/internal/models" + m "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" - "github.com/aws/aws-sdk-go/service/dynamodb" - "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" - "github.com/aws/aws-sdk-go/service/dynamodb/expression" ) -type DynamoRepository interface { - GetDBItem(tableName string, pk string, crowdactionId string) (map[string]*dynamodb.AttributeValue, error) - Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) -} type Service interface { - GetCrowdactionById(ctx context.Context, crowdactionId string) (*models.CrowdactionData, error) - GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) + GetCrowdactionById(ctx context.Context, crowdactionId string) (*m.CrowdactionData, error) + GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) } -type crowdaction struct { - dynamodb DynamoRepository +type CrowdactionManager interface { + GetById(pk string, crowdactionId string) (*m.CrowdactionData, error) + GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) } const ( @@ -30,47 +23,26 @@ const ( KeyDateJoinBefore = "date_limit_join" ) -func NewCrowdactionService(dynamodb DynamoRepository) Service { - return &crowdaction{dynamodb: dynamodb} +type crowdactionService struct { + crowdactionRepository CrowdactionManager +} + +func NewCrowdactionService(crowdactionRepository CrowdactionManager) Service { + return &crowdactionService{crowdactionRepository: crowdactionRepository} } /** GET Crowdaction by Id **/ -func (e *crowdaction) GetCrowdactionById(ctx context.Context, crowdactionID string) (*models.CrowdactionData, error) { - fmt.Println("GetCrowdaction calling internal:", crowdactionID) - item, err := e.dynamodb.GetDBItem(constants.TableName, utils.PKCrowdaction, crowdactionID) - if err != nil { - return nil, err - } - if item == nil { - return nil, fmt.Errorf("crowdaction not found") - } - var crowdaction models.CrowdactionData - err = dynamodbattribute.UnmarshalMap(item, &crowdaction) - return &crowdaction, err +func (e *crowdactionService) GetCrowdactionById(ctx context.Context, crowdactionID string) (*m.CrowdactionData, error) { + fmt.Println("GetCrowdactionById", crowdactionID) + return e.crowdactionRepository.GetById(utils.PKCrowdaction, crowdactionID) } /** GET Crowdaction by Status **/ -func (e *crowdaction) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - crowdactions := []models.CrowdactionData{} // empty crowdaction array - - switch status { - case "joinable": - filterCond := expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) - return items, err - case "active": - filterCond := expression.Name(KeyDateStart).LessThanEqual(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) - return items, err - case "ended": - filterCond := expression.Name(KeyDateEnd).LessThanEqual(expression.Value(utils.GetDateStringNow())) - items, err := e.dynamodb.Query(constants.TableName, filterCond, startFrom) - return items, err - default: - return crowdactions, nil - } +func (e *crowdactionService) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { + fmt.Println("GetCrowdactionsByStatus", status, startFrom) + return e.crowdactionRepository.GetByStatus(status, startFrom) } diff --git a/internal/crowdactions/crowdaction_test.go b/internal/crowdactions/crowdaction_test.go new file mode 100644 index 0000000..5ae810a --- /dev/null +++ b/internal/crowdactions/crowdaction_test.go @@ -0,0 +1,36 @@ +package crowdaction_test + +import ( + "context" + "fmt" + "testing" + + cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" + m "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/pkg/mocks/repository" + + "github.com/CollActionteam/collaction_backend/utils" + "github.com/stretchr/testify/assert" +) + +func TestCrowdaction_GetCrowdactionById(t *testing.T) { + as := assert.New(t) + dynamoRepository := &repository.Dynamo{} + var ctx context.Context + var crowdactions *m.CrowdactionData + crowdactionID := "sustainability#food#185f66fd" + + t.Run("dev stage", func(t *testing.T) { + dynamoRepository.On("GetById", utils.PKCrowdaction, crowdactionID).Return(crowdactions, nil).Once() + + service := cwd.NewCrowdactionService(dynamoRepository) + + crowdaction, err := service.GetCrowdactionById(ctx, crowdactionID) + + fmt.Println("Hello world", crowdaction) + + as.NoError(err) + + dynamoRepository.AssertExpectations(t) + }) +} diff --git a/pkg/handler/aws/crowdaction/main.go b/pkg/handler/aws/crowdaction/main.go index d00b74d..dc32435 100644 --- a/pkg/handler/aws/crowdaction/main.go +++ b/pkg/handler/aws/crowdaction/main.go @@ -3,7 +3,6 @@ package main import ( "context" "encoding/json" - "fmt" "net/http" cwd "github.com/CollActionteam/collaction_backend/internal/crowdactions" @@ -17,8 +16,7 @@ import ( ) func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGatewayV2HTTPResponse, error) { - fmt.Println("getCrowdactionByID handler: crowdactionID ", crowdactionID) - dynamoRepository := awsRepository.NewDynamo() + dynamoRepository := awsRepository.NewCrowdaction(awsRepository.NewDynamo()) getCrowdaction, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionById(ctx, crowdactionID) if err != nil { @@ -36,30 +34,22 @@ func getCrowdactionByID(ctx context.Context, crowdactionID string) (events.APIGa } func getCrowdactionsByStatus(ctx context.Context, status string) (events.APIGatewayV2HTTPResponse, error) { - dynamoRepository := awsRepository.NewDynamo() - var startFrom *utils.PrimaryKey - getCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, startFrom) + dynamoRepository := awsRepository.NewCrowdaction(awsRepository.NewDynamo()) + getCrowdactions, err := cwd.NewCrowdactionService(dynamoRepository).GetCrowdactionsByStatus(ctx, status, nil) if err != nil { return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } else { - jsonPayload, err := json.Marshal(getCrowdactions) - - if err != nil { - return utils.CreateMessageHttpResponse(http.StatusInternalServerError, err.Error()), nil - } - - return events.APIGatewayV2HTTPResponse{ - Body: string(jsonPayload), - StatusCode: http.StatusOK, - }, nil } + jsonPayload, _ := json.Marshal(getCrowdactions) + + return events.APIGatewayV2HTTPResponse{ + Body: string(jsonPayload), + StatusCode: http.StatusOK, + }, nil } func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { crowdactionID := req.PathParameters["crowdactionID"] - - fmt.Println("Hello Go, first message from CollAction AWS: ", crowdactionID) var request models.CrowdactionRequest validate := validator.New() diff --git a/pkg/mocks/repository/dynamoManager.go b/pkg/mocks/repository/dynamoManager.go index d79f053..3d37bab 100644 --- a/pkg/mocks/repository/dynamoManager.go +++ b/pkg/mocks/repository/dynamoManager.go @@ -1,9 +1,7 @@ package repository import ( - "context" - - models "github.com/CollActionteam/collaction_backend/internal/models" + m "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/stretchr/testify/mock" ) @@ -12,12 +10,12 @@ type Dynamo struct { mock.Mock } -func (d *Dynamo) GetCrowdactionById(ctx context.Context, crowdactionID string) error { - args := d.Called(ctx, crowdactionID) - return args.Error(0) +func (d *Dynamo) GetById(pk string, sk string) (*m.CrowdactionData, error) { + args := d.Mock.Called(pk, sk) + return args.Get(0).(*m.CrowdactionData), args.Error(1) } -func (d *Dynamo) GetCrowdactionByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - args := d.Called(ctx, status, startFrom) - return args.Get(0).([]models.CrowdactionData), args.Error(1) +func (d *Dynamo) GetByStatus(filterCond string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { + args := d.Mock.Called(filterCond, startFrom) + return args.Get(0).([]m.CrowdactionData), args.Error(1) } diff --git a/pkg/repository/aws/crowdactionManager.go b/pkg/repository/aws/crowdactionManager.go new file mode 100644 index 0000000..fb29b7b --- /dev/null +++ b/pkg/repository/aws/crowdactionManager.go @@ -0,0 +1,89 @@ +package aws + +import ( + "fmt" + + "github.com/CollActionteam/collaction_backend/internal/constants" + m "github.com/CollActionteam/collaction_backend/internal/models" + "github.com/CollActionteam/collaction_backend/utils" + "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute" + "github.com/aws/aws-sdk-go/service/dynamodb/expression" +) + +type Crowdaction interface { + GetById(pk string, sk string) (*m.CrowdactionData, error) + GetByStatus(status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) +} + +const ( + KeyDateStart = "date_start" + KeyDateEnd = "date_end" + KeyDateJoinBefore = "date_limit_join" +) + +type crowdaction struct { + dbClient *Dynamo +} + +func NewCrowdaction(dynamo *Dynamo) Crowdaction { + return &crowdaction{dbClient: dynamo} +} + +/** + GET Crowdaction by Id +**/ +func (s *crowdaction) GetById(pk string, sk string) (*m.CrowdactionData, error) { + item, err := s.dbClient.GetDBItem(constants.TableName, pk, sk) + + if item == nil || err != nil { + return nil, err + } + + var c m.CrowdactionData + err = dynamodbattribute.UnmarshalMap(item, &c) + + return &c, err +} + +/** + GET Crowdaction by Status +**/ +func (s *crowdaction) GetByStatus(status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { + crowdactions := []m.CrowdactionData{} + var filterCond expression.ConditionBuilder + + switch status { + case "joinable": + filterCond = expression.Name(KeyDateJoinBefore).GreaterThan(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: joinable", filterCond) + case "active": + filterCond = expression.Name(KeyDateStart).LessThanEqual(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: active", filterCond) + case "ended": + filterCond = expression.Name(KeyDateEnd).LessThanEqual(expression.Value(utils.GetDateStringNow())) + fmt.Println("GetByStatus: ended", filterCond) + default: + fmt.Println("None of the edge cases matched") + } + + items, err := s.dbClient.Query(constants.TableName, filterCond, startFrom) + + if items == nil || err != nil { + return nil, err + } + + for _, foo := range items { + var crowdaction m.CrowdactionData + err := dynamodbattribute.UnmarshalMap(foo, &crowdaction) + + if err == nil { + crowdactions = append(crowdactions, crowdaction) + } + } + + if len(items) != len(crowdactions) { + err = fmt.Errorf("error unmarshelling %d items", len(items)-len(crowdactions)) + } + + return crowdactions, err +} diff --git a/pkg/repository/aws/dynamo.go b/pkg/repository/aws/dynamo.go index c83f451..0698ba8 100644 --- a/pkg/repository/aws/dynamo.go +++ b/pkg/repository/aws/dynamo.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/CollActionteam/collaction_backend/internal/constants" - "github.com/CollActionteam/collaction_backend/internal/models" "github.com/CollActionteam/collaction_backend/utils" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -74,8 +73,6 @@ func (s *Dynamo) GetPrimaryKey(pk string, sk string) PrimaryKey { } func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]*dynamodb.AttributeValue, error) { - fmt.Println("Calling GetDBItem", tableName, pk, sk) - result, err := s.dbClient.GetItem(&dynamodb.GetItemInput{ TableName: &tableName, Key: s.GetPrimaryKey(pk, sk), @@ -92,20 +89,12 @@ func (s *Dynamo) GetDBItem(tableName string, pk string, sk string) (map[string]* if result == nil { return nil, nil } - - // fmt.Println("result from query: ", result) return result.Item, nil } -func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]models.CrowdactionData, error) { - // var crowdactions models.CrowdactionData - crowdactions := []models.CrowdactionData{} +func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, startFrom *utils.PrimaryKey) ([]map[string]*dynamodb.AttributeValue, error) { keyCond := expression.Key(utils.PartitionKey).Equal(expression.Value(utils.PKCrowdaction)) - expr, err := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() - - if err != nil { - return crowdactions, err - } + expr, _ := expression.NewBuilder().WithKeyCondition(keyCond).WithFilter(filterCond).Build() var exclusiveStartKey utils.PrimaryKey @@ -123,29 +112,7 @@ func (s *Dynamo) Query(tableName string, filterCond expression.ConditionBuilder, FilterExpression: expr.Filter(), }) - for _, item := range result.Items { - var crowdaction models.CrowdactionData - err := dynamodbattribute.UnmarshalMap(item, &crowdaction) - - if err == nil { - crowdactions = append(crowdactions, crowdaction) - } - } - - if len(result.Items) != len(crowdactions) { - err = fmt.Errorf("Error unmarshelling %d items", len(result.Items)-len(crowdactions)) - } - - startFrom = nil - - if result.LastEvaluatedKey != nil && len(result.LastEvaluatedKey) > 0 { - lastPK := result.LastEvaluatedKey[utils.PartitionKey].S - lastSK := result.LastEvaluatedKey[utils.SortKey].S - exclusiveStartKey = utils.GetPrimaryKey(*lastPK, *lastSK) - startFrom = &exclusiveStartKey - } - - return crowdactions, err + return result.Items, err } func (s *Dynamo) PutDBItem(tableName string, pk string, sk string, record interface{}) error { diff --git a/samconfig.yaml b/samconfig.yaml deleted file mode 100644 index 14cadb8..0000000 --- a/samconfig.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version = 0.1 -[default] -[default.deploy] -[default.deploy.parameters] -s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-1xoanv4heoh1g" -s3_prefix = "collaction-dev-edreinoso" -stack_name = "collaction-dev-edreinoso" -region = "eu-central-1" -confirm_changeset = true -capabilities = "CAPABILITY_IAM" -image_repositories = [] -parameter_overrides = "Stage=\"dev\" FirebaseProjectId=\"collaction-52ca9\" DomainParameter=\"\" SubdomainSuffixParameter=\"\" HostedZoneIdParameter=\"\" AcmCertificateArnParameter=\"\"" From 4c3e35ead8c8f3662c67824326a83717062b1fd8 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 2 Apr 2022 19:11:17 +0200 Subject: [PATCH 36/38] [pull request] removing unnecessary hello world --- pkg/handler/aws/emailContact/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/handler/aws/emailContact/main.go b/pkg/handler/aws/emailContact/main.go index cb85840..87ec045 100644 --- a/pkg/handler/aws/emailContact/main.go +++ b/pkg/handler/aws/emailContact/main.go @@ -3,7 +3,6 @@ package main import ( "context" "encoding/json" - "fmt" "net/http" "github.com/CollActionteam/collaction_backend/internal/contact" @@ -24,8 +23,6 @@ func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.AP } // TODO implement POW verification using nonce (see https://github.com/CollActionteam/collaction_backend/issues/58) - fmt.Println("Hello World") - validate := validator.New() if err := validate.StructCtx(ctx, request); err != nil { body, _ := json.Marshal(hnd.Response{Status: hnd.StatusFail, Data: map[string]interface{}{"error": utils.ValidationResponse(err, validate)}}) From 4c44370a9d3cb75a438f5d41c18b94a93f9bb1f4 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Sat, 2 Apr 2022 19:13:32 +0200 Subject: [PATCH 37/38] [pull request] removing some unnecessary comments --- internal/crowdactions/crowdaction.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/internal/crowdactions/crowdaction.go b/internal/crowdactions/crowdaction.go index 804f650..54c2445 100644 --- a/internal/crowdactions/crowdaction.go +++ b/internal/crowdactions/crowdaction.go @@ -31,17 +31,11 @@ func NewCrowdactionService(crowdactionRepository CrowdactionManager) Service { return &crowdactionService{crowdactionRepository: crowdactionRepository} } -/** - GET Crowdaction by Id -**/ func (e *crowdactionService) GetCrowdactionById(ctx context.Context, crowdactionID string) (*m.CrowdactionData, error) { fmt.Println("GetCrowdactionById", crowdactionID) return e.crowdactionRepository.GetById(utils.PKCrowdaction, crowdactionID) } -/** - GET Crowdaction by Status -**/ func (e *crowdactionService) GetCrowdactionsByStatus(ctx context.Context, status string, startFrom *utils.PrimaryKey) ([]m.CrowdactionData, error) { fmt.Println("GetCrowdactionsByStatus", status, startFrom) return e.crowdactionRepository.GetByStatus(status, startFrom) From 77bed7e9c9ac25a5f6026f2b39c3bcc8386ba3d0 Mon Sep 17 00:00:00 2001 From: Ed Reinoso Date: Fri, 8 Apr 2022 13:57:58 +0200 Subject: [PATCH 38/38] pointing system for the commitments in crowdactions --- docs/api2.yaml | 242 +++++++++++++++++----------------- internal/models/commitment.go | 1 + 2 files changed, 124 insertions(+), 119 deletions(-) diff --git a/docs/api2.yaml b/docs/api2.yaml index 1a8bbad..ee7b2d0 100644 --- a/docs/api2.yaml +++ b/docs/api2.yaml @@ -1,22 +1,22 @@ openapi: 3.0.1 info: title: collaction-dev - version: '1.0' + version: "1.0" servers: - - url: 'https://api{subdomainSuffix}.{domain}/' + - url: "https://api{subdomainSuffix}.{domain}/" variables: subdomainSuffix: - default: '-dev' + default: "-dev" domain: default: collaction.org paths: - '/crowdactions/{crowdactionID}': + "/crowdactions/{crowdactionID}": get: tags: - Crowdaction summary: Get details of a specific crowdaction parameters: - - $ref: '#/components/parameters/ApiVersionParameter' + - $ref: "#/components/parameters/ApiVersionParameter" - name: crowdactionID in: path required: true @@ -30,7 +30,7 @@ paths: type: string format: password responses: - '200': + "200": description: Crowdaction details content: application/json: @@ -48,8 +48,8 @@ paths: type: string example: >- sustainability#food#88615462-2789-4159-8659-2ecfd33ef305 - - $ref: '#/components/schemas/CrowdactionDetails' - '401': + - $ref: "#/components/schemas/CrowdactionDetails" + "401": description: Unauthorized (Invalid password) content: application/json: @@ -63,9 +63,9 @@ paths: type: string example: password: Invalid or missing password - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '404': + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "404": description: Crowdaction not found content: application/json: @@ -79,50 +79,50 @@ paths: type: string example: password: crowdaction does not exist - /crowdactions: - get: - tags: - - Crowdaction - summary: Get list of crowdactions - parameters: - - $ref: '#/components/parameters/ApiVersionParameter' - - name: status - in: query - required: false - schema: - type: string - enum: - - featured - - joinable - - active - - ended - responses: - '200': - description: List of crowdactions - content: - application/json: - schema: - type: object - properties: - status: - type: string - default: success - data: - type: array - items: - allOf: - - type: object - properties: - crowdactionID: - type: string - example: >- - sustainability#food#88615462-2789-4159-8659-2ecfd33ef305 - - $ref: '#/components/schemas/CrowdactionListItem' - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '/crowdactions/{crowdactionID}/participation': + /crowdactions: + get: + tags: + - Crowdaction + summary: Get list of crowdactions + parameters: + - $ref: "#/components/parameters/ApiVersionParameter" + - name: status + in: query + required: false + schema: + type: string + enum: + - featured + - joinable + - active + - ended + responses: + "200": + description: List of crowdactions + content: + application/json: + schema: + type: object + properties: + status: + type: string + default: success + data: + type: array + items: + allOf: + - type: object + properties: + crowdactionID: + type: string + example: >- + sustainability#food#88615462-2789-4159-8659-2ecfd33ef305 + - $ref: "#/components/schemas/CrowdactionListItem" + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "/crowdactions/{crowdactionID}/participation": parameters: - - $ref: '#/components/parameters/ApiVersionParameter' + - $ref: "#/components/parameters/ApiVersionParameter" - name: crowdactionID in: path required: true @@ -133,7 +133,7 @@ paths: - Crowdaction summary: Get existing participation in a particular crowdaction responses: - '200': + "200": description: Success message content: application/json: @@ -144,10 +144,10 @@ paths: type: string default: success data: - $ref: '#/components/schemas/Participation' - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '404': + $ref: "#/components/schemas/Participation" + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "404": description: Not found (Not participating) content: application/json: @@ -168,7 +168,7 @@ paths: - Crowdaction summary: Stop participating in a particular crowdaction responses: - '200': + "200": description: Success message content: application/json: @@ -180,9 +180,9 @@ paths: default: success data: default: null - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '404': + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "404": description: Not found (Not participating) content: application/json: @@ -225,7 +225,7 @@ paths: - no-meat - no-dairy responses: - '201': + "201": description: Success message content: application/json: @@ -237,7 +237,7 @@ paths: default: success data: default: null - '400': + "400": description: Bad request (Invalid commitments) content: application/json: @@ -251,7 +251,7 @@ paths: type: string example: commitments: Required commitment "no-beef" missing - '401': + "401": description: Unauthorized (Invalid password) content: application/json: @@ -265,9 +265,9 @@ paths: type: string example: password: Invalid or missing password - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '409': + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "409": description: Conflict content: application/json: @@ -283,9 +283,9 @@ paths: crowdactionID: already participating security: - FirebaseAuthorizer: [] - '/profiles/{userID}': + "/profiles/{userID}": parameters: - - $ref: '#/components/parameters/ApiVersionParameter' + - $ref: "#/components/parameters/ApiVersionParameter" - name: userID in: path required: true @@ -300,9 +300,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Profile' + $ref: "#/components/schemas/Profile" responses: - '201': + "201": description: Profile was created successfully content: application/json: @@ -314,7 +314,7 @@ paths: status: type: string default: success - '400': + "400": description: Bad request (Validation failed) content: application/json: @@ -328,9 +328,9 @@ paths: type: object example: displayname: Name must not be empty - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '409': + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "409": description: Conflict content: application/json: @@ -355,11 +355,11 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Profile' + $ref: "#/components/schemas/Profile" security: - FirebaseAuthorizer: [] responses: - '200': + "200": description: Profile was updated successfully content: application/json: @@ -371,7 +371,7 @@ paths: status: type: string default: success - '400': + "400": description: Bad request (Validation failed) content: application/json: @@ -385,9 +385,9 @@ paths: type: object example: displayname: Name must not be empty - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '404': + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "404": description: Profile was not found content: application/json: @@ -406,7 +406,7 @@ paths: - Profile summary: View the profile of a user responses: - '200': + "200": description: Profile was found content: application/json: @@ -417,10 +417,10 @@ paths: type: string default: success data: - $ref: '#/components/schemas/Profile' - '403': - $ref: '#/components/responses/UnsupportedClientVersion' - '404': + $ref: "#/components/schemas/Profile" + "403": + $ref: "#/components/responses/UnsupportedClientVersion" + "404": description: Profile was not found content: application/json: @@ -436,13 +436,13 @@ paths: userID: No such profile /upload-profile-picture: parameters: - - $ref: '#/components/parameters/ApiVersionParameter' + - $ref: "#/components/parameters/ApiVersionParameter" get: tags: - Profile summary: Fetch an upload URL (POST) for the profile picture responses: - '200': + "200": description: >- Returns the URL where to upload (PUT) the square png image (250-1024px) @@ -460,13 +460,13 @@ paths: upload_url: type: string format: uri - '403': - $ref: '#/components/responses/UnsupportedClientVersion' + "403": + $ref: "#/components/responses/UnsupportedClientVersion" security: - FirebaseAuthorizer: [] /contact: parameters: - - $ref: '#/components/parameters/ApiVersionParameter' + - $ref: "#/components/parameters/ApiVersionParameter" post: tags: - Other @@ -479,7 +479,7 @@ paths: type: object properties: data: - $ref: '#/components/schemas/Email' + $ref: "#/components/schemas/Email" nonce: type: string example: c2dlcjIzc3NndnJzdnIyM @@ -487,7 +487,7 @@ paths: Nonce for PoW, see http://www.hashcash.org/ (Not yet implemented -> field will be ignored if present) responses: - '200': + "200": description: The status code indicates if the message was successfully sent content: application/json: @@ -499,7 +499,7 @@ paths: default: success data: default: null - '400': + "400": description: Bad request content: application/json: @@ -513,8 +513,8 @@ paths: type: object example: email: Not a valid email address - '403': - $ref: '#/components/responses/UnsupportedClientVersion' + "403": + $ref: "#/components/responses/UnsupportedClientVersion" components: parameters: ApiVersionParameter: @@ -527,7 +527,7 @@ components: schema: type: string pattern: '^[0-9]+\.[0-9]+$' - example: '1.0' + example: "1.0" responses: UnsupportedClientVersion: description: Forbidden (Client version unsupported) @@ -561,22 +561,22 @@ components: subcategory: type: string location: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" dates: - $ref: '#/components/schemas/CrowdactionDates' + $ref: "#/components/schemas/CrowdactionDates" password_required: type: boolean commitment_options: type: array items: - $ref: '#/components/schemas/CommitmentOption' + $ref: "#/components/schemas/CommitmentOption" participation: - $ref: '#/components/schemas/Date' + $ref: "#/components/schemas/Date" images: type: object properties: banner: - $ref: '#/components/schemas/Image' + $ref: "#/components/schemas/Image" CrowdactionListItem: type: object properties: @@ -587,18 +587,18 @@ components: subcategory: type: string location: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" dates: - $ref: '#/components/schemas/CrowdactionDates' + $ref: "#/components/schemas/CrowdactionDates" password_required: type: boolean participation: - $ref: '#/components/schemas/ParticipationSummary' + $ref: "#/components/schemas/ParticipationSummary" images: type: object properties: card: - $ref: '#/components/schemas/Image' + $ref: "#/components/schemas/Image" CrowdactionDates: type: object description: >- @@ -606,11 +606,11 @@ components: latter properties: start: - $ref: '#/components/schemas/Date' + $ref: "#/components/schemas/Date" end: - $ref: '#/components/schemas/Date' + $ref: "#/components/schemas/Date" join_before: - $ref: '#/components/schemas/Date' + $ref: "#/components/schemas/Date" Location: type: object properties: @@ -629,6 +629,9 @@ components: label: type: string example: Becoming vegetarian + points: + type: int + example: 30 description: type: string example: I will not eat any meat from any animal (including fish). @@ -638,15 +641,16 @@ components: Commitments that are included in (and required by) this commitment. They can also be individually selected items: - $ref: '#/components/schemas/CommitmentOption' + $ref: "#/components/schemas/CommitmentOption" example: id: no-beef label: Not eating beef description: I will avoid eating beef (Goodbye stake). + points: 30 Date: type: string pattern: '\d{4}-\d{2}-\d{2}' - example: '2021-11-28' + example: "2021-11-28" ParticipationSummary: type: object properties: @@ -668,12 +672,12 @@ components: properties: url: type: string - example: 'https://picsum.photos/300/200' + example: "https://picsum.photos/300/200" format: uri blur_hash: type: string example: LEHV6nWB2yk8pyo0adR*.7kCMdnj - description: '(see https://blurha.sh/)' + description: "(see https://blurha.sh/)" Participation: type: object properties: @@ -684,7 +688,7 @@ components: description: Displayname of the user crowdactionID: type: string - example: 'sustainability#food#88615462-2789-4159-8659-2ecfd33ef305' + example: "sustainability#food#88615462-2789-4159-8659-2ecfd33ef305" title: type: string description: Title of the crowdactions @@ -697,7 +701,7 @@ components: - no-dairy description: Array of commitment ids date: - $ref: '#/components/schemas/Date' + $ref: "#/components/schemas/Date" Profile: type: object properties: @@ -705,7 +709,7 @@ components: type: string example: Max Murphy location: - $ref: '#/components/schemas/Location' + $ref: "#/components/schemas/Location" bio: type: string example: >- @@ -723,7 +727,7 @@ components: example: Hello world message: type: string - example: 'Please respond to this email :)' + example: "Please respond to this email :)" app_version: type: string pattern: '^(?:ios|android) [0-9]+\.[0-9]+\.[0-9]+\+[0-9]+$' diff --git a/internal/models/commitment.go b/internal/models/commitment.go index e8dac0c..46eec0d 100644 --- a/internal/models/commitment.go +++ b/internal/models/commitment.go @@ -5,4 +5,5 @@ type CommitmentOption struct { Label string `json:"label"` Description string `json:"description"` Requires []CommitmentOption `json:"requires,omitempty"` + Points int `json:"points"` }