feat: Update .gitignore, add Lambda layer configuration, and refactor DynamoDB handlers to use AWS SDK v3

This commit is contained in:
2024-11-23 06:28:02 +02:00
parent 86c671ccd8
commit f57d963453
19 changed files with 2877 additions and 102 deletions

10
.gitignore vendored
View File

@@ -22,7 +22,13 @@
**/next-env.d.ts **/next-env.d.ts
# images # images
**/public/** tasker-client/public/**
# terraform # terraform
**/**/.terraform** **/.terraform**
# serverless
**/.serverless/**
# zipped layers
**/layers/**.zip

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
{
"name": "nodejs",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@aws-sdk/client-dynamodb": "^3.699.0",
"@aws-sdk/lib-dynamodb": "^3.699.0",
"@types/uuid": "^10.0.0",
"uuid": "^11.0.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,21 @@
"scripts": { "scripts": {
"infra:init": "cd terraform && AWS_PROFILE=default terraform init", "infra:init": "cd terraform && AWS_PROFILE=default terraform init",
"infra:plan": "cd terraform && AWS_PROFILE=default terraform plan", "infra:plan": "cd terraform && AWS_PROFILE=default terraform plan",
"infra:apply": "cd terraform && AWS_PROFILE=default terraform apply" "infra:apply": "cd terraform && AWS_PROFILE=default terraform apply",
"infra:destroy": "cd terraform && AWS_PROFILE=default terraform destroy",
"sls:package": "AWS_PROFILE=default sls package",
"sls:deploy": "AWS_PROFILE=default sls deploy",
"sls:remove": "AWS_PROFILE=default sls remove"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"description": "", "description": "",
"dependencies": { "dependencies": {
"@aws-sdk/client-dynamodb": "^3.699.0",
"@aws-sdk/lib-dynamodb": "^3.699.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"aws-sdk": "^2.1692.0" "aws-sdk": "^2.1692.0",
"uuid": "^11.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^22.9.1", "@types/node": "^22.9.1",

View File

@@ -6,7 +6,7 @@ plugins:
provider: provider:
stackName: ${self:service} stackName: ${self:service}
name: aws name: aws
region: ${opt:region, 'eu-north-1'} region: "eu-north-1"
runtime: nodejs20.x runtime: nodejs20.x
environment: environment:
SLS_REGION: ${self:provider.region} SLS_REGION: ${self:provider.region}
@@ -15,6 +15,8 @@ provider:
TASKER_USER_TABLE_NAME: ${ssm:/tasker/dynamodb/user-table-name} TASKER_USER_TABLE_NAME: ${ssm:/tasker/dynamodb/user-table-name}
TASKER_TASK_EXTRA_TABLE_NAME: ${ssm:/tasker/dynamodb/task-extra-table-name} TASKER_TASK_EXTRA_TABLE_NAME: ${ssm:/tasker/dynamodb/task-extra-table-name}
TASKER_TEAM_TABLE_NAME: ${ssm:/tasker/dynamodb/team-table-name} TASKER_TEAM_TABLE_NAME: ${ssm:/tasker/dynamodb/team-table-name}
layers:
- ${ssm:/tasker/layers/tasker-layer-arn}
iam: iam:
role: role:
statements: statements:
@@ -32,6 +34,14 @@ provider:
] ]
functions: functions:
postSignUp:
handler: src/handlers/postSignUp.handler
memorySize: 1024
timeout: 60
events:
- cognitoUserPool:
pool: ${ssm:/tasker/cognito/user-pool-id}
trigger: PostConfirmation
# POST /users # POST /users
createUser: createUser:
handler: src/handlers/createUser.handler handler: src/handlers/createUser.handler
@@ -42,9 +52,6 @@ functions:
path: users path: users
method: post method: post
cors: true cors: true
authorizer:
type: COGNITO_USER_POOLS
arn: ${ssm:/tasker/cognito/user-pool-arn}
# POST /projects # POST /projects
createProject: createProject:
handler: src/handlers/createProject.handler handler: src/handlers/createProject.handler

View File

@@ -1,16 +1,18 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, PutCommandInput } from "@aws-sdk/lib-dynamodb";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || ""; const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { name, description, startDate, endDate } = event.body; const { name, description, startDate, endDate } = event.body;
try { try {
const newProject = { const newProject = {
type: "projects", category: "projects",
projectId: `project#${uuidv4()}`, projectId: `project#${uuidv4()}`,
name, name,
description, description,
@@ -18,12 +20,12 @@ export const handler = async (event: any): Promise<any> => {
endDate, endDate,
}; };
const params = { const params: PutCommandInput = {
TableName: TASKER_PROJECT_TABLE_NAME, TableName: TASKER_PROJECT_TABLE_NAME,
Item: newProject, Item: newProject,
}; };
await docClient.put(params).promise(); await docClient.put(params);
return { return {
status: 201, status: 201,

View File

@@ -1,10 +1,12 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, PutCommandInput } from "@aws-sdk/lib-dynamodb";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || ""; const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { const {
@@ -22,7 +24,7 @@ export const handler = async (event: any): Promise<any> => {
} = event.body; } = event.body;
try { try {
const newTask = { const newTask = {
type: "tasks", category: "tasks",
taskId: `task#${uuidv4()}`, taskId: `task#${uuidv4()}`,
title, title,
description, description,
@@ -37,12 +39,12 @@ export const handler = async (event: any): Promise<any> => {
assignedUserId, assignedUserId,
}; };
const params = { const params: PutCommandInput = {
TableName: TASKER_TASK_TABLE_NAME, TableName: TASKER_TASK_TABLE_NAME,
Item: newTask, Item: newTask,
}; };
await docClient.put(params).promise(); await docClient.put(params);
return { return {
status: 201, status: 201,

View File

@@ -1,32 +1,34 @@
import { fetchRandomTeamId } from "@/lib/util"; import { fetchRandomTeamId } from "@/lib/util";
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, PutCommandInput } from "@aws-sdk/lib-dynamodb";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || ""; const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { username, cognitoId, profilePictureUrl = "i0.jpg" } = event.body; const { username, cognitoId } = event.body;
const teamId = fetchRandomTeamId(); const teamId = fetchRandomTeamId();
try { try {
const newUser = { const newUser = {
type: "users", category: "users",
cognitoId, cognitoId,
userId: `user#${uuidv4()}`, userId: `user#${uuidv4()}`,
username, username,
profilePictureUrl, profilePictureUrl: "i0.jpg",
teamId, teamId,
}; };
const params = { const params: PutCommandInput = {
TableName: TASKER_USER_TABLE_NAME, TableName: TASKER_USER_TABLE_NAME,
Item: newUser, Item: newUser,
}; };
await docClient.put(params).promise(); await docClient.put(params);
return { return {
status: 201, status: 201,

View File

@@ -1,21 +1,23 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || ""; const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
try { try {
const params = { const params: QueryCommandInput = {
TableName: TASKER_PROJECT_TABLE_NAME, TableName: TASKER_PROJECT_TABLE_NAME,
KeyConditionExpression: "type = :type", KeyConditionExpression: "category = :category",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "projects", ":category": "projects",
}, },
}; };
const projects = await docClient.query(params).promise(); const projects = await docClient.query(params);
return { return {
status: 200, status: 200,

View File

@@ -3,27 +3,29 @@ import {
fetchComments, fetchComments,
fetchUserWithUserId, fetchUserWithUserId,
} from "@/lib/util"; } from "@/lib/util";
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || ""; const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { projectId } = event.queryStringParameters; const { projectId } = event.queryStringParameters;
try { try {
const params = { const params: QueryCommandInput = {
TableName: TASKER_TASK_TABLE_NAME, TableName: TASKER_TASK_TABLE_NAME,
KeyConditionExpression: "type = :type AND projectId = :projectId", KeyConditionExpression: "category = :category AND projectId = :projectId",
IndexName: "GSI-project-id", IndexName: "GSI-project-id",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "tasks", ":category": "tasks",
":projectId": projectId, ":projectId": projectId,
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
const tasks = result.Items || []; const tasks = result.Items || [];
const tasksWithDetails = await Promise.all( const tasksWithDetails = await Promise.all(

View File

@@ -1,22 +1,24 @@
import { fetchUserWithUserId } from "@/lib/util"; import { fetchUserWithUserId } from "@/lib/util";
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_TEAM_TABLE_NAME = process.env.TASKER_TEAM_TABLE_NAME || ""; const TASKER_TEAM_TABLE_NAME = process.env.TASKER_TEAM_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
try { try {
const params = { const params: QueryCommandInput = {
TableName: TASKER_TEAM_TABLE_NAME, TableName: TASKER_TEAM_TABLE_NAME,
KeyConditionExpression: "type = :type", KeyConditionExpression: "category = :category",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "teams", ":category": "teams",
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
const teams = result.Items || []; const teams = result.Items || [];
const teamsWithUsernames = await Promise.all( const teamsWithUsernames = await Promise.all(

View File

@@ -1,23 +1,25 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || ""; const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { cognitoId } = event.pathParameters; const { cognitoId } = event.pathParameters;
try { try {
const params = { const params: QueryCommandInput = {
TableName: TASKER_USER_TABLE_NAME, TableName: TASKER_USER_TABLE_NAME,
KeyConditionExpression: "type = :type AND cognitoId = :cognitoId", KeyConditionExpression: "category = :category AND cognitoId = :cognitoId",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "users", ":category": "users",
":cognitoId": cognitoId, ":cognitoId": cognitoId,
}, },
}; };
const user = await docClient.query(params).promise(); const user = await docClient.query(params);
return { return {
status: 200, status: 200,

View File

@@ -1,21 +1,23 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || ""; const TASKER_USER_TABLE_NAME = process.env.TASKER_USER_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
try { try {
const params = { const params: QueryCommandInput = {
TableName: TASKER_USER_TABLE_NAME, TableName: TASKER_USER_TABLE_NAME,
KeyConditionExpression: "type = :type", KeyConditionExpression: "category = :category",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "users", ":category": "users",
}, },
}; };
const users = await docClient.query(params).promise(); const users = await docClient.query(params);
return { return {
status: 200, status: 200,

View File

@@ -0,0 +1,34 @@
import https from "https";
export const handler = async (event: any): Promise<any> => {
const postData = JSON.stringify({
username:
event.request.userAttributes["preferred_username"] || event.userName,
cognitoId: event.userName,
});
const options = {
hostname: process.env.API_URL,
port: 443,
path: "/users",
method: "POST",
headers: {
"Content-category": "application/json",
"Content-Length": Buffer.byteLength(postData),
},
};
const responseBody = new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
res.setEncoding("utf8");
let responseBody = "";
res.on("data", (chunk) => (responseBody += chunk));
res.on("end", () => resolve(responseBody));
});
req.on("error", (error) => reject(error));
req.write(postData);
req.end();
});
return event;
};

View File

@@ -1,18 +1,20 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, UpdateCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || ""; const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const handler = async (event: any): Promise<any> => { export const handler = async (event: any): Promise<any> => {
const { taskId } = event.pathParameters; const { taskId } = event.pathParameters;
const { status } = event.body; const { status } = event.body;
try { try {
const params = { const params: UpdateCommandInput = {
TableName: TASKER_TASK_TABLE_NAME, TableName: TASKER_TASK_TABLE_NAME,
Key: { Key: {
type: "tasks", category: "tasks",
taskId, taskId,
}, },
UpdateExpression: "set #status = :status", UpdateExpression: "set #status = :status",
@@ -25,7 +27,7 @@ export const handler = async (event: any): Promise<any> => {
ReturnValues: "ALL_NEW", ReturnValues: "ALL_NEW",
}; };
const updatedTask = await docClient.update(params).promise(); const updatedTask = await docClient.update(params);
return { return {
status: 200, status: 200,

View File

@@ -1,4 +1,5 @@
import { DynamoDB } from "aws-sdk"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocument, QueryCommandInput } from "@aws-sdk/lib-dynamodb";
const SLS_REGION = process.env.SLS_REGION; const SLS_REGION = process.env.SLS_REGION;
const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || ""; const TASKER_PROJECT_TABLE_NAME = process.env.TASKER_PROJECT_TABLE_NAME || "";
@@ -7,18 +8,19 @@ const TASKER_TASK_TABLE_NAME = process.env.TASKER_TASK_TABLE_NAME || "";
const TASKER_TASK_EXTRA_TABLE_NAME = const TASKER_TASK_EXTRA_TABLE_NAME =
process.env.TASKER_TASK_EXTRA_TABLE_NAME || ""; process.env.TASKER_TASK_EXTRA_TABLE_NAME || "";
const docClient = new DynamoDB.DocumentClient({ region: SLS_REGION }); const client = new DynamoDBClient({ region: SLS_REGION });
const docClient = DynamoDBDocument.from(client);
export const fetchRandomTeamId = async () => { export const fetchRandomTeamId = async () => {
const params = { const params = {
TableName: TASKER_PROJECT_TABLE_NAME, TableName: TASKER_PROJECT_TABLE_NAME,
KeyConditionExpression: "type = :type", KeyConditionExpression: "category = :category",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "teams", ":category": "teams",
}, },
}; };
const projects = await docClient.query(params).promise(); const projects = await docClient.query(params);
if (!projects.Items) { if (!projects.Items) {
return null; return null;
} }
@@ -28,47 +30,47 @@ export const fetchRandomTeamId = async () => {
}; };
export const fetchUserWithUserId = async (userId: string): Promise<any> => { export const fetchUserWithUserId = async (userId: string): Promise<any> => {
const params: DynamoDB.DocumentClient.QueryInput = { const params: QueryCommandInput = {
TableName: TASKER_USER_TABLE_NAME, TableName: TASKER_USER_TABLE_NAME,
KeyConditionExpression: "type = :type AND userId = :userId", KeyConditionExpression: "category = :category AND userId = :userId",
IndexName: "GSI-user-id", IndexName: "GSI-user-id",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "users", ":category": "users",
":userId": userId, ":userId": userId,
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
return result.Items?.[0]; return result.Items?.[0];
}; };
export const fetchComments = async (taskId: string): Promise<any> => { export const fetchComments = async (taskId: string): Promise<any> => {
const params: DynamoDB.DocumentClient.QueryInput = { const params: QueryCommandInput = {
TableName: TASKER_TASK_EXTRA_TABLE_NAME, TableName: TASKER_TASK_EXTRA_TABLE_NAME,
KeyConditionExpression: "type = :type AND taskId = :taskId", KeyConditionExpression: "category = :category AND taskId = :taskId",
IndexName: "GSI-task-id", IndexName: "GSI-task-id",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "comments", ":category": "comments",
":taskId": taskId, ":taskId": taskId,
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
return result.Items; return result.Items;
}; };
export const fetchAttachments = async (taskId: string): Promise<any> => { export const fetchAttachments = async (taskId: string): Promise<any> => {
const params: DynamoDB.DocumentClient.QueryInput = { const params: QueryCommandInput = {
TableName: TASKER_TASK_EXTRA_TABLE_NAME, TableName: TASKER_TASK_EXTRA_TABLE_NAME,
KeyConditionExpression: "type = :type AND taskId = :taskId", KeyConditionExpression: "category = :category AND taskId = :taskId",
IndexName: "GSI-task-id", IndexName: "GSI-task-id",
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "attachments", ":category": "attachments",
":taskId": taskId, ":taskId": taskId,
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
return result.Items; return result.Items;
}; };
@@ -76,13 +78,13 @@ export const queryTasks = async (
userId: string, userId: string,
indexName: string, indexName: string,
key: string key: string
): Promise<DynamoDB.ItemList> => { ): Promise<any> => {
const params = { const params: QueryCommandInput = {
TableName: TASKER_TASK_TABLE_NAME, TableName: TASKER_TASK_TABLE_NAME,
KeyConditionExpression: "type = :type AND #key = :userId", KeyConditionExpression: "category = :category AND #key = :userId",
IndexName: indexName, IndexName: indexName,
ExpressionAttributeValues: { ExpressionAttributeValues: {
":type": "tasks", ":category": "tasks",
":userId": userId, ":userId": userId,
}, },
ExpressionAttributeNames: { ExpressionAttributeNames: {
@@ -90,6 +92,6 @@ export const queryTasks = async (
}, },
}; };
const result = await docClient.query(params).promise(); const result = await docClient.query(params);
return result.Items ?? []; return result.Items ?? [];
}; };

View File

@@ -1,11 +1,11 @@
resource "aws_dynamodb_table" "tasker_project_table" { resource "aws_dynamodb_table" "tasker_project_table" {
name = "tasker-project-table" name = "tasker-project-table"
billing_mode = "PAY_PER_REQUEST" billing_mode = "PAY_PER_REQUEST"
hash_key = "type" hash_key = "category"
range_key = "projectId" range_key = "projectId"
attribute { attribute {
name = "type" name = "category"
type = "S" type = "S"
} }
@@ -30,11 +30,11 @@ resource "aws_ssm_parameter" "tasker_project_table_arn" {
resource "aws_dynamodb_table" "tasker_user_table" { resource "aws_dynamodb_table" "tasker_user_table" {
name = "tasker-user-table" name = "tasker-user-table"
billing_mode = "PAY_PER_REQUEST" billing_mode = "PAY_PER_REQUEST"
hash_key = "type" hash_key = "category"
range_key = "cognitoId" range_key = "cognitoId"
attribute { attribute {
name = "type" name = "category"
type = "S" type = "S"
} }
@@ -50,7 +50,7 @@ resource "aws_dynamodb_table" "tasker_user_table" {
global_secondary_index { global_secondary_index {
name = "GSI-user-id" name = "GSI-user-id"
hash_key = "type" hash_key = "category"
range_key = "userId" range_key = "userId"
projection_type = "ALL" projection_type = "ALL"
} }
@@ -71,11 +71,11 @@ resource "aws_ssm_parameter" "tasker_user_table_arn" {
resource "aws_dynamodb_table" "tasker_team_table" { resource "aws_dynamodb_table" "tasker_team_table" {
name = "tasker-team-table" name = "tasker-team-table"
billing_mode = "PAY_PER_REQUEST" billing_mode = "PAY_PER_REQUEST"
hash_key = "type" hash_key = "category"
range_key = "teamId" range_key = "teamId"
attribute { attribute {
name = "type" name = "category"
type = "S" type = "S"
} }
@@ -100,11 +100,11 @@ resource "aws_ssm_parameter" "tasker_team_table_arn" {
resource "aws_dynamodb_table" "tasker_task_table" { resource "aws_dynamodb_table" "tasker_task_table" {
name = "tasker-task-table" name = "tasker-task-table"
billing_mode = "PAY_PER_REQUEST" billing_mode = "PAY_PER_REQUEST"
hash_key = "type" hash_key = "category"
range_key = "taskId" range_key = "taskId"
attribute { attribute {
name = "type" name = "category"
type = "S" type = "S"
} }
@@ -130,21 +130,21 @@ resource "aws_dynamodb_table" "tasker_task_table" {
global_secondary_index { global_secondary_index {
name = "GSI-project-id" name = "GSI-project-id"
hash_key = "type" hash_key = "category"
range_key = "projectId" range_key = "projectId"
projection_type = "ALL" projection_type = "ALL"
} }
global_secondary_index { global_secondary_index {
name = "GSI-author-user-id" name = "GSI-author-user-id"
hash_key = "type" hash_key = "category"
range_key = "authorUserId" range_key = "authorUserId"
projection_type = "ALL" projection_type = "ALL"
} }
global_secondary_index { global_secondary_index {
name = "GSI-assigned-user-id" name = "GSI-assigned-user-id"
hash_key = "type" hash_key = "category"
range_key = "assignedUserId" range_key = "assignedUserId"
projection_type = "ALL" projection_type = "ALL"
} }
@@ -165,11 +165,11 @@ resource "aws_ssm_parameter" "tasker_task_table_arn" {
resource "aws_dynamodb_table" "tasker_task_extra_table" { resource "aws_dynamodb_table" "tasker_task_extra_table" {
name = "tasker-task-extra-table" name = "tasker-task-extra-table"
billing_mode = "PAY_PER_REQUEST" billing_mode = "PAY_PER_REQUEST"
hash_key = "type" hash_key = "category"
range_key = "id" range_key = "id"
attribute { attribute {
name = "type" name = "category"
type = "S" type = "S"
} }
@@ -185,7 +185,7 @@ resource "aws_dynamodb_table" "tasker_task_extra_table" {
global_secondary_index { global_secondary_index {
name = "GSI-task-id" name = "GSI-task-id"
hash_key = "type" hash_key = "category"
range_key = "taskId" range_key = "taskId"
projection_type = "ALL" projection_type = "ALL"
} }

View File

@@ -0,0 +1,24 @@
resource "aws_s3_bucket" "tasker_lambda_layer" {
bucket = "tasker-lambda-layer"
}
resource "aws_s3_object" "tasker_lambda_layer_zip" {
bucket = aws_s3_bucket.tasker_lambda_layer.id
key = "layers/tasker-layer.zip"
source = "../layers/tasker-layer.zip"
}
resource "aws_lambda_layer_version" "tasker_layer" {
layer_name = "tasker-layer"
s3_bucket = aws_s3_object.tasker_lambda_layer_zip.bucket
s3_key = aws_s3_object.tasker_lambda_layer_zip.key
compatible_runtimes = ["nodejs20.x"]
description = "Tasker Lambda Layer with shared dependencies"
}
resource "aws_ssm_parameter" "tasker_layer_arn" {
name = "/tasker/layers/tasker-layer-arn"
type = "String"
value = aws_lambda_layer_version.tasker_layer.arn
}