Skip to content
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
25 changes: 25 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
75 changes: 57 additions & 18 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,20 +1,59 @@
.terraform/
.shelltool/
makefiles/
passwd

.npm/
.esbuild/
.serverlessrc
.npmrc
.config/
.yarn/
.cache/
node_modules
**/node_modules
.dccache
# compiled output
/dist
/node_modules
/.build
/.serverless

package-lock.json

# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# dotenv environment variable files
.env
coverage/
.vscode
.env.development.local
.env.test.local
.env.production.local
.env.local

# temp directory
.temp
.tmp

# Runtime data
pids
*.pid
*.seed
*.pid.lock

dist/
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"singleQuote": true,
"trailingComma": "all",
"editor.formatOnSave": true,
"tabWidth": 2,
"useTabs": false,
"indent_style": "space",
"indent_size": 2
}
82 changes: 82 additions & 0 deletions .serverless/cloudformation-template-create-stack.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "The AWS CloudFormation template for this Serverless application",
"Resources": {
"ServerlessDeploymentBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
}
}
},
"ServerlessDeploymentBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "ServerlessDeploymentBucket"
},
"PolicyDocument": {
"Statement": [
{
"Action": "s3:*",
"Effect": "Deny",
"Principal": "*",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":s3:::",
{
"Ref": "ServerlessDeploymentBucket"
},
"/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":s3:::",
{
"Ref": "ServerlessDeploymentBucket"
}
]
]
}
],
"Condition": {
"Bool": {
"aws:SecureTransport": false
}
}
}
]
}
}
}
},
"Outputs": {
"ServerlessDeploymentBucketName": {
"Value": {
"Ref": "ServerlessDeploymentBucket"
}
}
}
}
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Reto técnico iO - Backend

## Pre-requisitos para la instalacion y despliegue
- nodejs v20
- Tener el Access Key ID y Secret Access Key de su cuenta de AWS

## Instalacion
- npm install
- configure aws

## Ejecución en local
- npm run start:dev

## Ejecución Unit Test
- npm run test

## Despliegue en AWS
- comentar/quitar la funcion activities del archivo config/functions.yaml para el primer despliegue, esto por un problema con el stream de dynamo. Al no existir, no se puede referenciar
- npm run sls-deploy
- descomentar o agregar las funcion activities que se indico en el primer paso, para volver a desplegar
- npm run sls-deploy


## Descripción:
Se requiere implementar un proyecto serverless de registro de pagos y consulta de transacciones. A continuación se muestran los diagramas correspondientes:

Expand Down
3 changes: 3 additions & 0 deletions config/common-custom-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
logRetentionInDays:
DESA: 7
PROD: 30
5 changes: 5 additions & 0 deletions config/dynamodb-seed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
seedUsersTable:
table: ${self:provider.environment.DYNAMODB_TABLE_USERS}
sources:
- config/seeders/${self:provider.stage}/users/seed-user-1.json
- config/seeders/${self:provider.stage}/users/seed-user-2.json
37 changes: 37 additions & 0 deletions config/dynamodb-tables.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
usersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.DYNAMODB_TABLE_USERS}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH

transactionsTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.DYNAMODB_TABLE_TRANSACTIONS}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: transactionId
AttributeType: S
KeySchema:
- AttributeName: transactionId
KeyType: HASH
StreamSpecification:
StreamViewType: NEW_IMAGE

ActivityTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.DYNAMODB_TABLE_ACTIVITY}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: activityId
AttributeType: S
KeySchema:
- AttributeName: activityId
KeyType: HASH
3 changes: 3 additions & 0 deletions config/environments.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DYNAMODB_TABLE_USERS: TABLE_${self:provider.stage}_USERS
DYNAMODB_TABLE_TRANSACTIONS: TABLE_${self:provider.stage}_TRANSACTIONS
DYNAMODB_TABLE_ACTIVITY: TABLE_${self:provider.stage}_ACTIVITY
23 changes: 23 additions & 0 deletions config/functions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
payments:
handler: src/Payments/Infrastructure/AppLambda.handler
name: LMB_${self:provider.stage}_PAYMENTS
transactions:
handler: src/Transactions/Infrastructure/AppLambda.handler
name: LMB_${self:provider.stage}_TRANSACTIONS
events:
- http:
method: GET
path: 'V1/transactions'
# Comentar la siguiente function 'activities' en el primer despliegue
# luego descomentar y volver a desplegar
# por un problema del stream que no existe inicialmente (no se puede referenciar)
# pendiente de revisar y mejorar
activities:
handler: src/Activities/Infrastructure/AppLambda.handler
name: LMB_${self:provider.stage}_ACTIVITIES
events:
- stream:
type: dynamodb
batchSize: 1
startingPosition: LATEST
arn: ${fetchStreamARN(${self:provider.environment.DYNAMODB_TABLE_TRANSACTIONS})}
3 changes: 3 additions & 0 deletions config/http-response.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
headers:
Content-Type: "'application/json'"
template: ${file(config/response.vm)}
9 changes: 9 additions & 0 deletions config/iam-role-statements.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:DescribeStream
- dynamodb:ListStreams
Resource: '*'
5 changes: 5 additions & 0 deletions config/request/request-stepfunction-payments.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#set($input = $input.json('$'))
{
"input": "$util.escapeJavaScript($input).replaceAll("\\'", "'")",
"stateMachineArn": "arn:aws:states:${self:provider.region}:$context.accountId:stateMachine:SF_PAYMENT_WORKFLOW"
}
8 changes: 8 additions & 0 deletions config/resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Resources:
DynamoDBUsersTable: ${file(config/dynamodb-tables.yaml):usersTable}
DynamoDBTransactionsTable: ${file(config/dynamodb-tables.yaml):transactionsTable}
DynamoDBActivityTable: ${file(config/dynamodb-tables.yaml):ActivityTable}
StepFuncLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/stepfunctions/${self:service}-${self:provider.stage}
1 change: 1 addition & 0 deletions config/response.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$input.json("$")
11 changes: 11 additions & 0 deletions config/response/response-stepfunction-payments.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#set( $output = $util.parseJson($input.json('$.output')) )
#if( "$output" == "" )
{
"message": "Something was wrong"
}
#else
{
"message": "Payment registered successfully",
"transactionId": $output
}
#end
5 changes: 5 additions & 0 deletions config/seeders/DESA/users/seed-user-1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"userId": "f529177d-0521-414e-acd9-6ac840549e97",
"name": "Pedro",
"lastName": "Suarez"
}
5 changes: 5 additions & 0 deletions config/seeders/DESA/users/seed-user-2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"userId": "15f1c60a-2833-49b7-8660-065b58be2f89",
"name": "Andrea",
"lastName": "Vargas"
}
4 changes: 4 additions & 0 deletions config/stepfunctions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
stateMachines:
PaymentWorkFlow: ${file(config/stepfunctions/sf-paymentworkflow.yaml)}

validate: true
Loading