Skip to content

ALIS-1913:Draft delete #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions api-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Parameters:
Type: 'AWS::SSM::Parameter::Value<String>'
DeletedCommentTableName:
Type: 'AWS::SSM::Parameter::Value<String>'
DeletedDraftArticleInfoTableName:
Type: 'AWS::SSM::Parameter::Value<String>'
DeletedDraftArticleContentTableName:
Type: 'AWS::SSM::Parameter::Value<String>'
ElasticSearchEndpoint:
Type: 'AWS::SSM::Parameter::Value<String>'
TopicTableName:
Expand Down Expand Up @@ -110,6 +114,8 @@ Globals:
COMMENT_TABLE_NAME: !Ref CommentTableName
COMMENT_LIKED_USER_TABLE_NAME: !Ref CommentLikedUserTableName
DELETED_COMMENT_TABLE_NAME: !Ref DeletedCommentTableName
DELETED_DRAFT_ARTICLE_INFO_TABLE_NAME: !Ref DeletedDraftArticleInfoTableName
DELETED_DRAFT_ARTICLE_CONTENT_TABLE_NAME: !Ref DeletedDraftArticleContentTableName
TOPIC_TABLE_NAME: !Ref TopicTableName
TAG_TABLE_NAME: !Ref TagTableName
TIP_TABLE_NAME: !Ref TipTableName
Expand Down Expand Up @@ -808,6 +814,28 @@ Resources:
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
/me/articles/{article_id}:
delete:
description: '指定された公開されたことのない下書き記事を削除する'
parameters:
- name: 'article_id'
in: 'path'
description: '対象下書き記事を指定するために使用'
required: true
type: 'string'
responses:
'200':
description: '下書き記事削除の完了'
security:
- cognitoUserPool: []
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MeArticlesDelete.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
/me/articles/{article_id}/drafts/publish:
put:
description: "指定された article_id の下書き記事を公開"
Expand Down Expand Up @@ -1967,6 +1995,19 @@ Resources:
Path: /me/articles/{article_id}/like
Method: post
RestApiId: !Ref RestApi
MeArticlesDelete:
Type: AWS::Serverless::Function
Properties:
Handler: handler.lambda_handler
Role: !GetAtt LambdaRole.Arn
CodeUri: ./deploy/me_articles_delete.zip
Events:
Api:
Type: Api
Properties:
Path: /me/articles/{article_id}
Method: delete
RestApiId: !Ref RestApi
ArticlesCommentsIndex:
Type: AWS::Serverless::Function
Properties:
Expand Down
138 changes: 138 additions & 0 deletions database-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@ Resources:
KeyType: HASH
- AttributeName: created_at
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: article_id-index
KeySchema:
- AttributeName: article_id
KeyType: HASH
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
ProvisionedThroughput:
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
Expand Down Expand Up @@ -301,6 +311,34 @@ Resources:
ProvisionedThroughput:
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
DeletedDraftArticleInfo:
Type: AWS::DynamoDB::Table
DependsOn:
- ArticleInfo
Properties:
AttributeDefinitions:
- AttributeName: article_id
AttributeType: S
KeySchema:
- AttributeName: article_id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
DeletedDraftArticleContent:
Type: AWS::DynamoDB::Table
DependsOn:
- ArticleInfo
Properties:
AttributeDefinitions:
- AttributeName: article_id
AttributeType: S
KeySchema:
- AttributeName: article_id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
LikeTokenAggregation:
Type: AWS::DynamoDB::Table
DependsOn:
Expand Down Expand Up @@ -1392,6 +1430,106 @@ Resources:
ScaleOutCooldown: 60
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBWriteCapacityUtilization
DeletedDraftArticleInfoTableReadCapacityScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
DependsOn: ScalingRole
Properties:
MaxCapacity: !Ref MaxDynamoWriteCapacitty
MinCapacity: !Ref MinDynamoWriteCapacitty
ResourceId: !Join
- /
- - table
- !Ref DeletedDraftArticleInfo
RoleARN: !GetAtt ScalingRole.Arn
ScalableDimension: dynamodb:table:ReadCapacityUnits
ServiceNamespace: dynamodb
DeletedDraftArticleInfoTableWriteCapacityScalableTarget:
Type: 'AWS::ApplicationAutoScaling::ScalableTarget'
DependsOn: ScalingRole
Properties:
MaxCapacity: !Ref MaxDynamoWriteCapacitty
MinCapacity: !Ref MinDynamoWriteCapacitty
ResourceId: !Join
- /
- - table
- !Ref DeletedDraftArticleInfo
RoleARN: !GetAtt ScalingRole.Arn
ScalableDimension: dynamodb:table:WriteCapacityUnits
ServiceNamespace: dynamodb
DeletedDraftArticleInfoTableReadScalingPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: ReadAutoScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref DeletedDraftArticleInfoTableReadCapacityScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 50.0
ScaleInCooldown: 60
ScaleOutCooldown: 60
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBReadCapacityUtilization
DeletedDraftArticleInfoTableWriteScalingPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: WriteAutoScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref DeletedDraftArticleInfoTableWriteCapacityScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 50.0
ScaleInCooldown: 60
ScaleOutCooldown: 60
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBWriteCapacityUtilization
DeletedDraftArticleContentTableReadCapacityScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
DependsOn: ScalingRole
Properties:
MaxCapacity: !Ref MaxDynamoWriteCapacitty
MinCapacity: !Ref MinDynamoWriteCapacitty
ResourceId: !Join
- /
- - table
- !Ref DeletedDraftArticleContent
RoleARN: !GetAtt ScalingRole.Arn
ScalableDimension: dynamodb:table:ReadCapacityUnits
ServiceNamespace: dynamodb
DeletedDraftArticleContentTableWriteCapacityScalableTarget:
Type: 'AWS::ApplicationAutoScaling::ScalableTarget'
DependsOn: ScalingRole
Properties:
MaxCapacity: !Ref MaxDynamoWriteCapacitty
MinCapacity: !Ref MinDynamoWriteCapacitty
ResourceId: !Join
- /
- - table
- !Ref DeletedDraftArticleContent
RoleARN: !GetAtt ScalingRole.Arn
ScalableDimension: dynamodb:table:WriteCapacityUnits
ServiceNamespace: dynamodb
DeletedDraftArticleContentTableReadScalingPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: ReadAutoScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref DeletedDraftArticleContentTableReadCapacityScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 50.0
ScaleInCooldown: 60
ScaleOutCooldown: 60
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBReadCapacityUtilization
DeletedDraftArticleContentTableWriteScalingPolicy:
Type: 'AWS::ApplicationAutoScaling::ScalingPolicy'
Properties:
PolicyName: WriteAutoScalingPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref DeletedDraftArticleContentTableWriteCapacityScalableTarget
TargetTrackingScalingPolicyConfiguration:
TargetValue: 50.0
ScaleInCooldown: 60
ScaleOutCooldown: 60
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBWriteCapacityUtilization
UsersTableReadCapacityScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
DependsOn: ScalingRole
Expand Down
38 changes: 38 additions & 0 deletions database.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ Resources:
KeyType: HASH
- AttributeName: created_at
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: article_id-index
KeySchema:
- AttributeName: article_id
KeyType: HASH
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
Expand Down Expand Up @@ -274,6 +284,34 @@ Resources:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
DeletionPolicy: Retain
DeletedDraftArticleInfo:
Type: AWS::DynamoDB::Table
DependsOn:
- ArticleInfo
Properties:
AttributeDefinitions:
- AttributeName: article_id
AttributeType: S
KeySchema:
- AttributeName: article_id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
DeletedDraftArticleContent:
Type: AWS::DynamoDB::Table
DependsOn:
- ArticleInfo
Properties:
AttributeDefinitions:
- AttributeName: article_id
AttributeType: S
KeySchema:
- AttributeName: article_id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 2
WriteCapacityUnits: 2
LikeTokenAggregation:
Type: AWS::DynamoDB::Table
DependsOn:
Expand Down
2 changes: 2 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ aws cloudformation deploy \
ArticleFraudUserTableName=${SSM_PARAMS_PREFIX}ArticleFraudUserTableName \
ArticlePvUserTableName=${SSM_PARAMS_PREFIX}ArticlePvUserTableName \
ArticleScoreTableName=${SSM_PARAMS_PREFIX}ArticleScoreTableName \
DeletedDraftArticleInfoTableName=${SSM_PARAMS_PREFIX}DeletedDraftArticleInfoTableName \
DeletedDraftArticleContentTableName=${SSM_PARAMS_PREFIX}DeletedDraftArticleContentTableName \
UsersTableName=${SSM_PARAMS_PREFIX}UsersTableName \
BetaUsersTableName=${SSM_PARAMS_PREFIX}BetaUsersTableName \
ExternalProviderUsersTableName=${SSM_PARAMS_PREFIX}ExternalProviderUsersTableName \
Expand Down
14 changes: 14 additions & 0 deletions src/common/db_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ def validate_article_existence(dynamodb, article_id, user_id=None, status=None):
raise RecordNotFoundError('Record Not Found')
return True

@staticmethod
def validate_article_history_existence(dynamodb, article_id):
article_history_table = dynamodb.Table(os.environ['ARTICLE_HISTORY_TABLE_NAME'])
query_params = {
'IndexName': 'article_id-index',
'KeyConditionExpression': Key('article_id').eq(article_id)
}

article_histories = article_history_table.query(**query_params)['Items']

if len(article_histories) != 0:
raise RecordNotFoundError('This article is not removable')
return True

@staticmethod
def validate_user_existence(dynamodb, user_id):
users_table = dynamodb.Table(os.environ['USERS_TABLE_NAME'])
Expand Down
10 changes: 10 additions & 0 deletions src/handlers/me/articles/delete/handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
import boto3
from me_articles_delete import MeArticlesDelete

dynamodb = boto3.resource('dynamodb')


def lambda_handler(event, context):
me_articles_delete = MeArticlesDelete(event=event, context=context, dynamodb=dynamodb)
return me_articles_delete.main()
72 changes: 72 additions & 0 deletions src/handlers/me/articles/delete/me_articles_delete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
import os
import time
import settings
import logging
import json
from db_util import DBUtil
from lambda_base import LambdaBase
from jsonschema import validate
from user_util import UserUtil
from botocore.exceptions import ClientError


class MeArticlesDelete(LambdaBase):
def get_schema(self):
return {
'type': 'object',
'properties': {
'article_id': settings.parameters['article_id']
},
'required': ['article_id']
}

def validate_params(self):
UserUtil.verified_phone_and_email(self.event)
validate(self.params, self.get_schema())
DBUtil.validate_article_existence(
self.dynamodb,
self.params['article_id'],
user_id=self.event['requestContext']['authorizer']['claims']['cognito:username'],
status='draft')
DBUtil.validate_article_history_existence(self.dynamodb, self.params['article_id'])

def exec_main_proc(self):
article_info_table = self.dynamodb.Table(os.environ['ARTICLE_INFO_TABLE_NAME'])
article_info = article_info_table.get_item(
Key={"article_id": self.params['article_id']}
)['Item']

article_content_table = self.dynamodb.Table(os.environ['ARTICLE_CONTENT_TABLE_NAME'])
article_content = article_content_table.get_item(
Key={"article_id": self.params['article_id']}
)['Item']

deleted_draft_article_info_table = self.dynamodb.Table(os.environ['DELETED_DRAFT_ARTICLE_INFO_TABLE_NAME'])
deleted_draft_article_content_table = \
self.dynamodb.Table(os.environ['DELETED_DRAFT_ARTICLE_CONTENT_TABLE_NAME'])

article_info.update({'deleted_at': int(time.time())})
article_content.update({'deleted_at': int(time.time())})

try:
deleted_draft_article_info_table.put_item(Item=article_info)
deleted_draft_article_content_table.put_item(Item=article_content)
article_info_table.delete_item(
Key={
'article_id': self.params['article_id']
}
)
article_content_table.delete_item(
Key={
'article_id': self.params['article_id']
}
)
except ClientError as e:
logging.fatal(e)
return {
'statusCode': 500,
'body': json.dumps({'message': 'Internal server error'})
}

return {'statusCode': 200}
Loading