diff --git a/lib/configs/api-gateway/schema.ts b/lib/configs/api-gateway/schema.ts index b2c0b3954..d5e39a3f8 100644 --- a/lib/configs/api-gateway/schema.ts +++ b/lib/configs/api-gateway/schema.ts @@ -377,134 +377,134 @@ export const courseReviewPatchReqSchema: apigw.JsonSchema = { required: ['data'], }; -// export const forumThreadGetRespSchema: apigw.JsonSchema = { -// schema: apigw.JsonSchemaVersion.DRAFT7, -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// success: { -// type: apigw.JsonSchemaType.BOOLEAN, -// }, -// data: { -// type: apigw.JsonSchemaType.ARRAY, -// items: { -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// univ_id: { -// type: apigw.JsonSchemaType.INTEGER, -// }, -// board_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// updated_at: { -// type: apigw.JsonSchemaType.STRING, -// }, -// created_at: { -// type: apigw.JsonSchemaType.STRING, -// }, -// tag_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// group_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// thread_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// title: { -// type: apigw.JsonSchemaType.STRING, -// }, -// body: { -// type: apigw.JsonSchemaType.STRING, -// }, -// views: { -// type: apigw.JsonSchemaType.INTEGER, -// }, -// mod: { -// type: apigw.JsonSchemaType.BOOLEAN, -// }, -// }, -// required: [ -// 'univ_id', -// 'board_id', -// 'updated_at', -// 'created_at', -// 'tag_id', -// 'group_id', -// 'thread_id', -// 'title', -// 'body', -// 'views', -// 'mod', -// ], -// }, -// }, -// message: { -// type: apigw.JsonSchemaType.STRING, -// }, -// }, -// required: ['success', 'data', 'message'], -// }; +export const forumThreadGetRespSchema: apigw.JsonSchema = { + schema: apigw.JsonSchemaVersion.DRAFT7, + type: apigw.JsonSchemaType.OBJECT, + properties: { + success: { + type: apigw.JsonSchemaType.BOOLEAN, + }, + data: { + type: apigw.JsonSchemaType.ARRAY, + items: { + type: apigw.JsonSchemaType.OBJECT, + properties: { + univ_id: { + type: apigw.JsonSchemaType.INTEGER, + }, + board_id: { + type: apigw.JsonSchemaType.STRING, + }, + updated_at: { + type: apigw.JsonSchemaType.STRING, + }, + created_at: { + type: apigw.JsonSchemaType.STRING, + }, + tag_id: { + type: apigw.JsonSchemaType.STRING, + }, + group_id: { + type: apigw.JsonSchemaType.STRING, + }, + thread_id: { + type: apigw.JsonSchemaType.STRING, + }, + title: { + type: apigw.JsonSchemaType.STRING, + }, + body: { + type: apigw.JsonSchemaType.STRING, + }, + views: { + type: apigw.JsonSchemaType.INTEGER, + }, + mod: { + type: apigw.JsonSchemaType.BOOLEAN, + }, + }, + required: [ + 'univ_id', + 'board_id', + 'updated_at', + 'created_at', + 'tag_id', + 'group_id', + 'thread_id', + 'title', + 'body', + 'views', + 'mod', + ], + }, + }, + message: { + type: apigw.JsonSchemaType.STRING, + }, + }, + required: ['success', 'data', 'message'], +}; -// export const forumThreadPostReqSchema: apigw.JsonSchema = { -// schema: apigw.JsonSchemaVersion.DRAFT7, -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// data: { -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// univ_id: { -// type: apigw.JsonSchemaType.INTEGER, -// }, -// board_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// tag_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// group_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// title: { -// type: apigw.JsonSchemaType.STRING, -// }, -// body: { -// type: apigw.JsonSchemaType.STRING, -// }, -// }, -// required: ['univ_id', 'board_id', 'tag_id', 'group_id', 'title', 'body'], -// }, -// }, -// required: ['data'], -// }; +export const forumThreadPostReqSchema: apigw.JsonSchema = { + schema: apigw.JsonSchemaVersion.DRAFT7, + type: apigw.JsonSchemaType.OBJECT, + properties: { + data: { + type: apigw.JsonSchemaType.OBJECT, + properties: { + univ_id: { + type: apigw.JsonSchemaType.INTEGER, + }, + board_id: { + type: apigw.JsonSchemaType.STRING, + }, + tag_id: { + type: apigw.JsonSchemaType.STRING, + }, + group_id: { + type: apigw.JsonSchemaType.STRING, + }, + title: { + type: apigw.JsonSchemaType.STRING, + }, + body: { + type: apigw.JsonSchemaType.STRING, + }, + }, + required: ['univ_id', 'board_id', 'tag_id', 'group_id', 'title', 'body'], + }, + }, + required: ['data'], +}; -// export const forumThreadPatchReqSchema: apigw.JsonSchema = { -// schema: apigw.JsonSchemaVersion.DRAFT7, -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// data: { -// type: apigw.JsonSchemaType.OBJECT, -// properties: { -// board_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// tag_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// thread_id: { -// type: apigw.JsonSchemaType.STRING, -// }, -// title: { -// type: apigw.JsonSchemaType.STRING, -// }, -// body: { -// type: apigw.JsonSchemaType.STRING, -// }, -// }, -// required: ['board_id', 'tag_id', 'thread_id', 'title', 'body'], -// }, -// }, -// required: ['data'], -// }; +export const forumThreadPatchReqSchema: apigw.JsonSchema = { + schema: apigw.JsonSchemaVersion.DRAFT7, + type: apigw.JsonSchemaType.OBJECT, + properties: { + data: { + type: apigw.JsonSchemaType.OBJECT, + properties: { + board_id: { + type: apigw.JsonSchemaType.STRING, + }, + tag_id: { + type: apigw.JsonSchemaType.STRING, + }, + thread_id: { + type: apigw.JsonSchemaType.STRING, + }, + title: { + type: apigw.JsonSchemaType.STRING, + }, + body: { + type: apigw.JsonSchemaType.STRING, + }, + }, + required: ['board_id', 'tag_id', 'thread_id', 'title', 'body'], + }, + }, + required: ['data'], +}; export const forumCommentGetRespSchema: apigw.JsonSchema = { schema: apigw.JsonSchemaVersion.DRAFT7, diff --git a/lib/configs/common/registry.ts b/lib/configs/common/registry.ts index a0c0b9e8c..936047c89 100644 --- a/lib/configs/common/registry.ts +++ b/lib/configs/common/registry.ts @@ -10,7 +10,7 @@ export const enum DataEndpoint { CAREER, TIMETABLE, COURSE, - // THREAD, + THREAD, COMMENT, } diff --git a/lib/constructs/business/rest-api-service.ts b/lib/constructs/business/rest-api-service.ts index f8010754e..db4ba68d6 100644 --- a/lib/constructs/business/rest-api-service.ts +++ b/lib/constructs/business/rest-api-service.ts @@ -13,9 +13,9 @@ import { courseReviewGetRespSchema, courseReviewPatchReqSchema, courseReviewPostReqSchema, - // forumThreadGetRespSchema, - // forumThreadPatchReqSchema, - // forumThreadPostReqSchema, + forumThreadGetRespSchema, + forumThreadPatchReqSchema, + forumThreadPostReqSchema, forumCommentGetRespSchema, forumCommentPostReqSchema, forumCommentPatchReqSchema, @@ -26,7 +26,7 @@ import { CourseReviewsFunctions, SyllabusFunctions, TimetableFunctions, - // ForumThreadFunctions, + ForumThreadFunctions, ForumCommentFunctions, } from '../common/lambda-functions'; import { AbstractRestApiEndpoint } from './api-endpoint'; @@ -701,235 +701,235 @@ export class GraphqlApiService extends RestApiService { } } -// export class ForumThreadsApiService extends RestApiService { -// readonly resourceMapping: { -// [path: string]: { [method in apigw2.HttpMethod]?: apigw.Method }; -// }; +export class ForumThreadsApiService extends RestApiService { + readonly resourceMapping: { + [path: string]: { [method in apigw2.HttpMethod]?: apigw.Method }; + }; -// constructor( -// scope: AbstractRestApiEndpoint, -// id: string, -// props: RestApiServiceProps -// ) { -// super(scope, id, props); + constructor( + scope: AbstractRestApiEndpoint, + id: string, + props: RestApiServiceProps, + ) { + super(scope, id, props); -// const root = scope.apiEndpoint.root.addResource("forum"); -// const boardResource = root.addResource("{board_id}"); -// const threadResource = boardResource.addResource("{thread_id}"); + const root = scope.apiEndpoint.root.addResource('forum'); + const boardResource = root.addResource('{board_id}'); + const threadResource = boardResource.addResource('{thread_id}'); -// const optionsForumHome = root.addCorsPreflight({ -// allowOrigins: allowOrigins, -// allowHeaders: allowHeaders, -// allowMethods: [ -// apigw2.HttpMethod.GET, -// apigw2.HttpMethod.POST, -// apigw2.HttpMethod.PATCH, -// apigw2.HttpMethod.DELETE, -// apigw2.HttpMethod.OPTIONS, -// ], -// }); + const optionsForumHome = root.addCorsPreflight({ + allowOrigins: allowOrigins, + allowHeaders: allowHeaders, + allowMethods: [ + apigw2.HttpMethod.GET, + apigw2.HttpMethod.POST, + apigw2.HttpMethod.PATCH, + apigw2.HttpMethod.DELETE, + apigw2.HttpMethod.OPTIONS, + ], + }); -// const optionsForumBoards = boardResource.addCorsPreflight({ -// allowOrigins: allowOrigins, -// allowHeaders: allowHeaders, -// allowMethods: [ -// apigw2.HttpMethod.GET, -// apigw2.HttpMethod.POST, -// apigw2.HttpMethod.PATCH, -// apigw2.HttpMethod.DELETE, -// apigw2.HttpMethod.OPTIONS, -// ], -// }); + const optionsForumBoards = boardResource.addCorsPreflight({ + allowOrigins: allowOrigins, + allowHeaders: allowHeaders, + allowMethods: [ + apigw2.HttpMethod.GET, + apigw2.HttpMethod.POST, + apigw2.HttpMethod.PATCH, + apigw2.HttpMethod.DELETE, + apigw2.HttpMethod.OPTIONS, + ], + }); -// const optionsForumThreads = threadResource.addCorsPreflight({ -// allowOrigins: allowOrigins, -// allowHeaders: allowHeaders, -// allowMethods: [ -// apigw2.HttpMethod.GET, -// apigw2.HttpMethod.POST, -// apigw2.HttpMethod.PATCH, -// apigw2.HttpMethod.DELETE, -// apigw2.HttpMethod.OPTIONS, -// ], -// }); + const optionsForumThreads = threadResource.addCorsPreflight({ + allowOrigins: allowOrigins, + allowHeaders: allowHeaders, + allowMethods: [ + apigw2.HttpMethod.GET, + apigw2.HttpMethod.POST, + apigw2.HttpMethod.PATCH, + apigw2.HttpMethod.DELETE, + apigw2.HttpMethod.OPTIONS, + ], + }); -// const getRespModel = scope.apiEndpoint.addModel("threads-get-resp-model", { -// schema: forumThreadGetRespSchema, -// contentType: "application/json", -// description: "HTTP GET response body schema for fetching threads.", -// modelName: "GetThreadsResp", -// }); -// const postReqModel = scope.apiEndpoint.addModel("thread-post-req-model", { -// schema: forumThreadPostReqSchema, -// contentType: "application/json", -// description: "HTTP POST request body schema for submitting a thread.", -// modelName: "PostThreadReq", -// }); -// const patchReqModel = scope.apiEndpoint.addModel("thread-patch-req-model", { -// schema: forumThreadPatchReqSchema, -// contentType: "application/json", -// description: "HTTP PATCH request body schema for updating a thread", -// modelName: "PatchThreadReq", -// }); + const getRespModel = scope.apiEndpoint.addModel('threads-get-resp-model', { + schema: forumThreadGetRespSchema, + contentType: 'application/json', + description: 'HTTP GET response body schema for fetching threads.', + modelName: 'GetThreadsResp', + }); + const postReqModel = scope.apiEndpoint.addModel('thread-post-req-model', { + schema: forumThreadPostReqSchema, + contentType: 'application/json', + description: 'HTTP POST request body schema for submitting a thread.', + modelName: 'PostThreadReq', + }); + const patchReqModel = scope.apiEndpoint.addModel('thread-patch-req-model', { + schema: forumThreadPatchReqSchema, + contentType: 'application/json', + description: 'HTTP PATCH request body schema for updating a thread', + modelName: 'PatchThreadReq', + }); -// const forumThreadsFunctions = new ForumThreadFunctions( -// this, -// "crud-functions", -// { -// envVars: { -// TABLE_NAME: props.dataSource!, -// }, -// } -// ); + const forumThreadsFunctions = new ForumThreadFunctions( + this, + 'crud-functions', + { + envVars: { + TABLE_NAME: props.dataSource!, + }, + }, + ); -// const getAllInegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.getAllFunction, -// { proxy: true } -// ); -// const getBoardIntegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.getBoardFunction, -// { proxy: true } -// ); -// const getThreadIntegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.getSingleFunction, -// { proxy: true } -// ); -// const postIntegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.postFunction, -// { proxy: true } -// ); -// const patchIntegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.patchFunction, -// { proxy: true } -// ); -// const deleteIntegration = new apigw.LambdaIntegration( -// forumThreadsFunctions.deleteFunction, -// { proxy: true } -// ); + const getAllInegration = new apigw.LambdaIntegration( + forumThreadsFunctions.getAllFunction, + { proxy: true }, + ); + const getBoardIntegration = new apigw.LambdaIntegration( + forumThreadsFunctions.getBoardFunction, + { proxy: true }, + ); + const getThreadIntegration = new apigw.LambdaIntegration( + forumThreadsFunctions.getSingleFunction, + { proxy: true }, + ); + const postIntegration = new apigw.LambdaIntegration( + forumThreadsFunctions.postFunction, + { proxy: true }, + ); + const patchIntegration = new apigw.LambdaIntegration( + forumThreadsFunctions.patchFunction, + { proxy: true }, + ); + const deleteIntegration = new apigw.LambdaIntegration( + forumThreadsFunctions.deleteFunction, + { proxy: true }, + ); -// const getAllForumThreads = root.addMethod( -// apigw2.HttpMethod.GET, -// getAllInegration, -// { -// operationName: "GetAllThreads", -// methodResponses: [ -// { -// statusCode: "200", -// responseModels: { ["application/json"]: getRespModel }, -// responseParameters: lambdaRespParams, -// }, -// ], -// requestValidator: props.validator, -// } -// ); + const getAllForumThreads = root.addMethod( + apigw2.HttpMethod.GET, + getAllInegration, + { + operationName: 'GetAllThreads', + methodResponses: [ + { + statusCode: '200', + responseModels: { ['application/json']: getRespModel }, + responseParameters: lambdaRespParams, + }, + ], + requestValidator: props.validator, + }, + ); -// const getBoardForumThreads = boardResource.addMethod( -// apigw2.HttpMethod.GET, -// getBoardIntegration, -// { -// operationName: "GetBoardThreads", -// methodResponses: [ -// { -// statusCode: "200", -// responseModels: { ["application/json"]: getRespModel }, -// responseParameters: lambdaRespParams, -// }, -// ], -// requestValidator: props.validator, -// } -// ); + const getBoardForumThreads = boardResource.addMethod( + apigw2.HttpMethod.GET, + getBoardIntegration, + { + operationName: 'GetBoardThreads', + methodResponses: [ + { + statusCode: '200', + responseModels: { ['application/json']: getRespModel }, + responseParameters: lambdaRespParams, + }, + ], + requestValidator: props.validator, + }, + ); -// const getForumThread = threadResource.addMethod( -// apigw2.HttpMethod.GET, -// getThreadIntegration, -// { -// requestParameters: { -// "method.request.path.thread_id": true, -// }, -// operationName: "GetSingleThread", -// methodResponses: [ -// { -// statusCode: "200", -// responseModels: { ["application/json"]: getRespModel }, -// responseParameters: lambdaRespParams, -// }, -// ], -// requestValidator: props.validator, -// } -// ); -// const postForumThreads = boardResource.addMethod( -// apigw2.HttpMethod.POST, -// postIntegration, -// { -// operationName: "PostThread", -// requestModels: { ["application/json"]: postReqModel }, -// methodResponses: [ -// { -// statusCode: "200", -// responseParameters: lambdaRespParams, -// }, -// ], -// authorizer: props.authorizer, -// requestValidator: props.validator, -// } -// ); -// const patchForumThreads = threadResource.addMethod( -// apigw2.HttpMethod.PATCH, -// patchIntegration, -// { -// operationName: "UpdateThread", -// requestParameters: { -// "method.request.querystring.ts": true, -// }, -// requestModels: { ["application/json"]: patchReqModel }, -// methodResponses: [ -// { -// statusCode: "200", -// responseParameters: lambdaRespParams, -// }, -// ], -// authorizer: props.authorizer, -// requestValidator: props.validator, -// } -// ); -// const deleteForumThreads = threadResource.addMethod( -// apigw2.HttpMethod.DELETE, -// deleteIntegration, -// { -// operationName: "DeleteThread", -// requestParameters: { -// "method.request.querystring.ts": true, -// }, -// methodResponses: [ -// { -// statusCode: "200", -// responseParameters: lambdaRespParams, -// }, -// ], -// authorizer: props.authorizer, -// requestValidator: props.validator, -// } -// ); + const getForumThread = threadResource.addMethod( + apigw2.HttpMethod.GET, + getThreadIntegration, + { + requestParameters: { + 'method.request.path.thread_id': true, + }, + operationName: 'GetSingleThread', + methodResponses: [ + { + statusCode: '200', + responseModels: { ['application/json']: getRespModel }, + responseParameters: lambdaRespParams, + }, + ], + requestValidator: props.validator, + }, + ); + const postForumThreads = boardResource.addMethod( + apigw2.HttpMethod.POST, + postIntegration, + { + operationName: 'PostThread', + requestModels: { ['application/json']: postReqModel }, + methodResponses: [ + { + statusCode: '200', + responseParameters: lambdaRespParams, + }, + ], + authorizer: props.authorizer, + requestValidator: props.validator, + }, + ); + const patchForumThreads = threadResource.addMethod( + apigw2.HttpMethod.PATCH, + patchIntegration, + { + operationName: 'UpdateThread', + requestParameters: { + 'method.request.querystring.ts': true, + }, + requestModels: { ['application/json']: patchReqModel }, + methodResponses: [ + { + statusCode: '200', + responseParameters: lambdaRespParams, + }, + ], + authorizer: props.authorizer, + requestValidator: props.validator, + }, + ); + const deleteForumThreads = threadResource.addMethod( + apigw2.HttpMethod.DELETE, + deleteIntegration, + { + operationName: 'DeleteThread', + requestParameters: { + 'method.request.querystring.ts': true, + }, + methodResponses: [ + { + statusCode: '200', + responseParameters: lambdaRespParams, + }, + ], + authorizer: props.authorizer, + requestValidator: props.validator, + }, + ); -// this.resourceMapping = { -// "/forum": { -// [apigw2.HttpMethod.GET]: getAllForumThreads, -// [apigw2.HttpMethod.OPTIONS]: optionsForumHome, -// }, -// "/forum/{board_id}": { -// [apigw2.HttpMethod.GET]: getBoardForumThreads, -// [apigw2.HttpMethod.POST]: postForumThreads, -// [apigw2.HttpMethod.OPTIONS]: optionsForumBoards, -// }, -// "/forum/{board_id}/{thread_id}": { -// [apigw2.HttpMethod.GET]: getForumThread, -// [apigw2.HttpMethod.OPTIONS]: optionsForumThreads, -// [apigw2.HttpMethod.PATCH]: patchForumThreads, -// [apigw2.HttpMethod.DELETE]: deleteForumThreads, -// }, -// }; -// } -// } + this.resourceMapping = { + '/forum': { + [apigw2.HttpMethod.GET]: getAllForumThreads, + [apigw2.HttpMethod.OPTIONS]: optionsForumHome, + }, + '/forum/{board_id}': { + [apigw2.HttpMethod.GET]: getBoardForumThreads, + [apigw2.HttpMethod.POST]: postForumThreads, + [apigw2.HttpMethod.OPTIONS]: optionsForumBoards, + }, + '/forum/{board_id}/{thread_id}': { + [apigw2.HttpMethod.GET]: getForumThread, + [apigw2.HttpMethod.OPTIONS]: optionsForumThreads, + [apigw2.HttpMethod.PATCH]: patchForumThreads, + [apigw2.HttpMethod.DELETE]: deleteForumThreads, + }, + }; + } +} export class ForumCommentsApiService extends RestApiService { readonly resourceMapping: { diff --git a/lib/constructs/business/service.ts b/lib/constructs/business/service.ts index f95fdacf0..c72e61c23 100644 --- a/lib/constructs/business/service.ts +++ b/lib/constructs/business/service.ts @@ -12,7 +12,7 @@ export type RestApiServiceId = | 'course-reviews' | 'career' | 'timetable' - // | 'thread' + | 'thread' | 'comment' | 'graphql'; @@ -23,7 +23,7 @@ export const restApiServiceMap: { 'course-reviews': rest.CourseReviewsApiService, 'career': rest.CareerApiService, 'timetable': rest.TimetableApiService, - // 'thread': rest.ForumThreadsApiService, + 'thread': rest.ForumThreadsApiService, 'comment': rest.ForumCommentsApiService, 'graphql': rest.GraphqlApiService, }; diff --git a/lib/constructs/common/lambda-functions.ts b/lib/constructs/common/lambda-functions.ts index 93fd32106..6190515b6 100644 --- a/lib/constructs/common/lambda-functions.ts +++ b/lib/constructs/common/lambda-functions.ts @@ -484,156 +484,156 @@ export class SyllabusUpdateFunction extends Construct { } } -// export class ForumThreadFunctions extends Construct { -// readonly getAllFunction: lambda.Function; -// readonly getBoardFunction: lambda.Function; -// readonly getSingleFunction: lambda.Function; -// readonly postFunction: lambda.Function; -// readonly patchFunction: lambda.Function; -// readonly deleteFunction: lambda.Function; - -// constructor(scope: Construct, id: string, props: FunctionsProps) { -// super(scope, id); - -// const dynamoDBReadRole: iam.LazyRole = new iam.LazyRole( -// this, -// 'dynamo-read-role', -// { -// assumedBy: new iam.ServicePrincipal(AwsServicePrincipal.LAMBDA), -// description: -// 'Allow lambda function to perform crud operation on dynamodb', -// path: `/service-role/${AwsServicePrincipal.LAMBDA}/`, -// roleName: 'dynamodb-lambda-read-thread', -// managedPolicies: [ -// iam.ManagedPolicy.fromManagedPolicyArn( -// this, -// 'basic-exec', -// 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', -// ), -// iam.ManagedPolicy.fromManagedPolicyArn( -// this, -// 'db-read-only', -// 'arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess', -// ), -// ], -// }, -// ); - -// const dynamoDBPutRole: iam.LazyRole = new iam.LazyRole( -// this, -// 'dynamo-put-role', -// { -// assumedBy: new iam.ServicePrincipal(AwsServicePrincipal.LAMBDA), -// description: -// 'Allow lambda function to perform crud operation on dynamodb', -// path: `/service-role/${AwsServicePrincipal.LAMBDA}/`, -// roleName: 'dynamodb-lambda-write-thread', -// managedPolicies: [ -// iam.ManagedPolicy.fromManagedPolicyArn( -// this, -// 'basic-exec1', -// 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', -// ), -// iam.ManagedPolicy.fromManagedPolicyArn( -// this, -// 'db-full-access', -// 'arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess', -// ), -// ], -// }, -// ); - -// this.getAllFunction = new lambda_py.PythonFunction( -// this, -// 'get-all-threads', -// { -// entry: 'src/lambda/get-all-threads', -// description: 'Get all forum threads from the database.', -// functionName: 'get-all-threads', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 128, -// role: dynamoDBReadRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(3), -// environment: props.envVars, -// }, -// ); - -// this.getBoardFunction = new lambda_py.PythonFunction( -// this, -// 'get-board-threads', -// { -// entry: 'src/lambda/get-board-threads', -// description: 'Get forum threads from the database.', -// functionName: 'get-board-threads', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 128, -// role: dynamoDBReadRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(3), -// environment: props.envVars, -// }, -// ); - -// this.getSingleFunction = new lambda_py.PythonFunction( -// this, -// 'get-single-thread', -// { -// entry: 'src/lambda/get-single-thread', -// description: 'Gets a single forum thread from the database.', -// functionName: 'get-single-thread', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 128, -// role: dynamoDBReadRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(3), -// environment: props.envVars, -// }, -// ); - -// this.postFunction = new lambda_py.PythonFunction(this, 'post-thread', { -// entry: 'src/lambda/post-thread', -// description: 'Save forum thread into the database.', -// functionName: 'post-forum-thread', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 256, -// role: dynamoDBPutRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(5), -// environment: props.envVars, -// }).addEnvironment( -// 'GOOGLE_API_SERVICE_ACCOUNT_INFO', -// GOOGLE_API_SERVICE_ACCOUNT_INFO, -// ); - -// this.patchFunction = new lambda_py.PythonFunction(this, 'patch-thread', { -// entry: 'src/lambda/patch-thread', -// description: 'Update forum thread in the database.', -// functionName: 'patch-forum-thread', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 256, -// role: dynamoDBPutRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(5), -// environment: props.envVars, -// }).addEnvironment( -// 'GOOGLE_API_SERVICE_ACCOUNT_INFO', -// GOOGLE_API_SERVICE_ACCOUNT_INFO, -// ); - -// this.deleteFunction = new lambda_py.PythonFunction(this, 'delete-thread', { -// entry: 'src/lambda/delete-thread', -// description: 'Delete forum thread in the database.', -// functionName: 'delete-forum-thread', -// logRetention: logs.RetentionDays.ONE_MONTH, -// memorySize: 128, -// role: dynamoDBPutRole, -// runtime: lambda.Runtime.PYTHON_3_9, -// timeout: Duration.seconds(3), -// environment: props.envVars, -// }); -// } -// } +export class ForumThreadFunctions extends Construct { + readonly getAllFunction: lambda.Function; + readonly getBoardFunction: lambda.Function; + readonly getSingleFunction: lambda.Function; + readonly postFunction: lambda.Function; + readonly patchFunction: lambda.Function; + readonly deleteFunction: lambda.Function; + + constructor(scope: Construct, id: string, props: FunctionsProps) { + super(scope, id); + + const dynamoDBReadRole: iam.LazyRole = new iam.LazyRole( + this, + 'dynamo-read-role', + { + assumedBy: new iam.ServicePrincipal(AwsServicePrincipal.LAMBDA), + description: + 'Allow lambda function to perform crud operation on dynamodb', + path: `/service-role/${AwsServicePrincipal.LAMBDA}/`, + roleName: 'dynamodb-lambda-read-thread', + managedPolicies: [ + iam.ManagedPolicy.fromManagedPolicyArn( + this, + 'basic-exec', + 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', + ), + iam.ManagedPolicy.fromManagedPolicyArn( + this, + 'db-read-only', + 'arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess', + ), + ], + }, + ); + + const dynamoDBPutRole: iam.LazyRole = new iam.LazyRole( + this, + 'dynamo-put-role', + { + assumedBy: new iam.ServicePrincipal(AwsServicePrincipal.LAMBDA), + description: + 'Allow lambda function to perform crud operation on dynamodb', + path: `/service-role/${AwsServicePrincipal.LAMBDA}/`, + roleName: 'dynamodb-lambda-write-thread', + managedPolicies: [ + iam.ManagedPolicy.fromManagedPolicyArn( + this, + 'basic-exec1', + 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', + ), + iam.ManagedPolicy.fromManagedPolicyArn( + this, + 'db-full-access', + 'arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess', + ), + ], + }, + ); + + this.getAllFunction = new lambda_py.PythonFunction( + this, + 'get-all-threads', + { + entry: 'src/lambda/get-all-threads', + description: 'Get all forum threads from the database.', + functionName: 'get-all-threads', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 128, + role: dynamoDBReadRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(3), + environment: props.envVars, + }, + ); + + this.getBoardFunction = new lambda_py.PythonFunction( + this, + 'get-board-threads', + { + entry: 'src/lambda/get-board-threads', + description: 'Get forum threads from the database.', + functionName: 'get-board-threads', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 128, + role: dynamoDBReadRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(3), + environment: props.envVars, + }, + ); + + this.getSingleFunction = new lambda_py.PythonFunction( + this, + 'get-single-thread', + { + entry: 'src/lambda/get-single-thread', + description: 'Gets a single forum thread from the database.', + functionName: 'get-single-thread', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 128, + role: dynamoDBReadRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(3), + environment: props.envVars, + }, + ); + + this.postFunction = new lambda_py.PythonFunction(this, 'post-thread', { + entry: 'src/lambda/post-thread', + description: 'Save forum thread into the database.', + functionName: 'post-forum-thread', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 256, + role: dynamoDBPutRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(5), + environment: props.envVars, + }).addEnvironment( + 'GOOGLE_API_SERVICE_ACCOUNT_INFO', + GOOGLE_API_SERVICE_ACCOUNT_INFO, + ); + + this.patchFunction = new lambda_py.PythonFunction(this, 'patch-thread', { + entry: 'src/lambda/patch-thread', + description: 'Update forum thread in the database.', + functionName: 'patch-forum-thread', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 256, + role: dynamoDBPutRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(5), + environment: props.envVars, + }).addEnvironment( + 'GOOGLE_API_SERVICE_ACCOUNT_INFO', + GOOGLE_API_SERVICE_ACCOUNT_INFO, + ); + + this.deleteFunction = new lambda_py.PythonFunction(this, 'delete-thread', { + entry: 'src/lambda/delete-thread', + description: 'Delete forum thread in the database.', + functionName: 'delete-forum-thread', + logRetention: logs.RetentionDays.ONE_MONTH, + memorySize: 128, + role: dynamoDBPutRole, + runtime: lambda.Runtime.PYTHON_3_9, + timeout: Duration.seconds(3), + environment: props.envVars, + }); + } +} export class ForumCommentFunctions extends Construct { readonly getFunction: lambda.Function; diff --git a/lib/constructs/persistence/database.ts b/lib/constructs/persistence/database.ts index 788eb7848..eea20643a 100644 --- a/lib/constructs/persistence/database.ts +++ b/lib/constructs/persistence/database.ts @@ -8,7 +8,7 @@ export enum Collection { FEEDS, SYLLABUS, TIMETABLE, - // THREAD, + THREAD, COMMENT, } @@ -82,34 +82,34 @@ export class DynamoDatabase extends Construct { }, ); - // this.tables[Collection.THREAD] = new dynamodb.Table( - // this, - // 'dynamodb-thread-table', - // { - // partitionKey: { - // name: 'board_id', - // type: dynamodb.AttributeType.STRING, - // }, - // billingMode: dynamodb.BillingMode.PROVISIONED, - // encryption: dynamodb.TableEncryption.DEFAULT, - // removalPolicy: RemovalPolicy.RETAIN, - // sortKey: { name: 'created_at', type: dynamodb.AttributeType.STRING }, - // tableName: 'forum-threads', - // readCapacity: 15, - // writeCapacity: 15, - // pointInTimeRecovery: true, - // }, - // ); + this.tables[Collection.THREAD] = new dynamodb.Table( + this, + 'dynamodb-thread-table', + { + partitionKey: { + name: 'board_id', + type: dynamodb.AttributeType.STRING, + }, + billingMode: dynamodb.BillingMode.PROVISIONED, + encryption: dynamodb.TableEncryption.DEFAULT, + removalPolicy: RemovalPolicy.RETAIN, + sortKey: { name: 'created_at', type: dynamodb.AttributeType.STRING }, + tableName: 'forum-threads', + readCapacity: 15, + writeCapacity: 15, + pointInTimeRecovery: true, + }, + ); // this.tables[Collection.THREAD].addLocalSecondaryIndex({ - // indexName: 'GroupIndex', - // sortKey: { name: 'group_id', type: dynamodb.AttributeType.STRING }, + // indexName: "GroupIndex", + // sortKey: { name: "group_id", type: dynamodb.AttributeType.STRING }, // projectionType: dynamodb.ProjectionType.ALL, // }); // this.tables[Collection.THREAD].addLocalSecondaryIndex({ - // indexName: 'TagIndex', - // sortKey: { name: 'tag_id', type: dynamodb.AttributeType.NUMBER }, + // indexName: "TagIndex", + // sortKey: { name: "tag_id", type: dynamodb.AttributeType.NUMBER }, // projectionType: dynamodb.ProjectionType.ALL, // }); diff --git a/lib/stacks/persistence.ts b/lib/stacks/persistence.ts index 445656b97..9be88516d 100644 --- a/lib/stacks/persistence.ts +++ b/lib/stacks/persistence.ts @@ -60,10 +60,10 @@ export class WasedaTimePersistenceLayer extends PersistenceLayer { DataEndpoint.SYLLABUS, syllabusDataPipeline.dataWarehouse.bucketName, ); - // this.dataInterface.setEndpoint( - // DataEndpoint.THREAD, - // dynamoDatabase.tables[Collection.THREAD].tableName, - // ); + this.dataInterface.setEndpoint( + DataEndpoint.THREAD, + dynamoDatabase.tables[Collection.THREAD].tableName, + ); this.dataInterface.setEndpoint( DataEndpoint.COMMENT, dynamoDatabase.tables[Collection.COMMENT].tableName,