Skip to content

danielgom/fds-aws-coding-exercise

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

21 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽธ Fender Digital โ€ข AWS Coding Exercise โ˜๏ธ

๐ŸŒ Overview

You are developing the backend system for a music streaming platform based on subscriptions and plans.

The AWS infrastructure is already provisioned for you. You will receive access to a dedicated AWS account containing:

  • An empty Lambda function: fender_digital_code_exercise (you'll write and deploy the code)
  • A DynamoDB table for data storage
  • An API Gateway REST API: fender_digital_code_exercise
arch.svg
Cloud architecture diagram

๐Ÿ“ Your Task

Write the Lambda function code to support two operations:

  1. Get subscription data for a user
  2. Process subscription webhook events (creation, renewal, cancellation)

Configure API Gateway to expose the following endpoints:

  • GET /api/v1/subscriptions/{userId}
  • POST /api/v1/webhooks/subscriptions

Deploy your code using the provided deployment scripts.

Write E2E tests to validate the subscription flow.

Detailed Steps

  1. Configure the API Gateway endpoints with Lambda proxy integration
  2. Create a deployment and stage for the REST API
  3. Create an API key and usage plan, and connect it to the stage
  4. Implement the Lambda function handler code
  5. Deploy your code using the provided scripts
  6. Test the complete subscription flow

๐ŸŽฏ Technical requirements

  • Each user can only have one active subscription at a time

  • The subscription status field must be derived from the data using the following rules:

    • The status is active if the canceledAt field is not set
    • The status is pending if the cancelledAt field is set, but current date is before the expiresAt date
    • The status is cancelled if the cancelledAt field is set, and current date is after the expiresAt date
  • Subscriptions cannot be created for plans with inactive status

  • plan items must be created manually in the AWS Console DynamoDB service

  • The response of the GET /api/v1/subscriptions/{userId} should also contain the associated plan data

๐Ÿ“Œ Sample objects

sub DynamoDB item

Field name Description DynamoDB type
pk Partition key of the item (e.g. user:<userId>) String
sk Sort key of the item (e.g. sub:<subId>}) String
type Item type (always sub) String
planSku SKU of the subscription plan String
startDate ISO-8601 string of subscription start datetime String
expiresAt ISO-8601 string of subscription expiration datetime String
canceledAt ISO-8601 string of subscription cancelation datetime String
lastModifiedAt ISO-8601 string of last modified datetime String
attributes Extra attributes for the subscription (metadata) Map

plan DynamoDB item

Field name Description DynamoDB type
pk Partition key of the item (e.g. plan:<sku>). String
sk Sort key of the item (e.g. meta) String
type Item type (always plan) String
name Name of the plan String
price Price of the plan Number
currency Currency of the plan price String
billingCycle Billing cycle of the plan (monthy or yearly) String
features List of features (as strings) List
status Status of the plan (active or inactive) String
lastModifiedAt ISO-8601 string of last modified datetime String

GET /api/v1/subscriptions/{userId} response

{
  "userId": "123",
  "subscriptionId": "sub_456789",
  "plan": {
    "sku": "PREMIUM_MONTHLY",
    "name": "Premium Monthly",
    "price": 9.99,
    "currency": "USD",
    "billingCycle": "MONTHLY",
    "features": [
      "HD Streaming",
      "Offline Downloads",
      "Ad Free"
    ],
  },
  "startDate": "2024-03-20T10:00:00Z",
  "expiresAt": "2024-04-20T10:00:00Z",
  "cancelledAt": null,
  "status": "ACTIVE",
  "attributes": {
    "autoRenew": true,
    "paymentMethod": "CREDIT_CARD"
  }
}

POST /api/v1/webhooks/subscriptions request body

  • Subscription creation event (subscription.created)
{
  "eventId": "evt_123456789",
  "eventType": "subscription.created",
  "timestamp": "2024-03-20T10:00:00Z",
  "provider": "STRIPE",
  "subscriptionId": "sub_456789",
  "paymentId": "pm_123456",
  "userId": "123",
  "customerId": "cus_789012",
  "expiresAt": "2024-04-20T10:00:00Z",
  "metadata": {
    "planSku": "PREMIUM_MONTHLY",
    "autoRenew": true,
    "paymentMethod": "CREDIT_CARD"
  }
}
  • Subscription renewal event (subscription.renewed)
{
  "eventId": "evt_987654321",
  "eventType": "subscription.renewed",
  "timestamp": "2024-04-20T10:00:00Z",
  "provider": "STRIPE",
  "subscriptionId": "sub_456789",
  "paymentId": "pm_654321",
  "userId": "123",
  "customerId": "cus_789012",
  "expiresAt": "2024-05-20T10:00:00Z",
  "metadata": {
    "planSku": "PREMIUM_MONTHLY",
    "autoRenew": true,
    "paymentMethod": "CREDIT_CARD"
  }
}
  • Subscription cancelation event (subscription.cancelled)
{
  "eventId": "evt_456789123",
  "eventType": "subscription.cancelled",
  "timestamp": "2024-05-20T10:00:00Z",
  "provider": "STRIPE",
  "subscriptionId": "sub_456789",
  "paymentId": null,
  "userId": "123",
  "customerId": "cus_789012",
  "expiresAt": "2024-05-20T10:00:00Z",
  "cancelledAt": "2024-05-20T10:00:00Z",
  "metadata": {
    "planSku": "PREMIUM_MONTHLY",
    "autoRenew": false,
    "paymentMethod": "CREDIT_CARD",
    "cancelReason": "USER_REQUESTED"
  }
}

โš™๏ธ Setting up

โฎ๏ธ Prerequisites

๐Ÿด Setting up the repo

To set up your local environment, start by creating a fork of this repository and cloning that into your local machine.

โ˜๏ธ Configuring the AWS CLI

Some steps in the coding exercise process require interaction with AWS through the AWS CLI. You will need to create a new profile called fender. You can do so by running the following command and entering the variables.

aws configure --profile fender
AWS Access Key ID: <your access key id>
AWS Secret Access Key: <your secret access key>
Default region name: us-east-1
Default output format: json

To ensure correct configuration, run the following command

aws lambda list-functions --profile fender

You should see a function called fender_digital_code_exercise

๐ŸŒณ Environment variables

To manage environment variables, create a .env file in the root directory of the repository. This file will be used to sync the Lambda runtime environment variables when deployed.

The .env file MUST follow the traditional convention of KEY=VALUE in order for the deployment to work. Here's an example:

VARIABLE_ONE=Hello
VARIABLE_TWO=World!

# Comments and newlines are allowed
ANOTHER_ONE=foo

LAST_ONE=bar

๐Ÿ–ฅ๏ธ Development and deployment

๐Ÿง  Developing your solution

We provide detailed instructions on development for the following languages.

If you want to use a different language, create a new folder in the app directory and manage it however you want.

๐Ÿš€ Deploying to AWS

The first step is to deploy any environment variables to the Lambda runtime. Make sure you have a .env file in the repository root and run the following command.

make deploy-env

This will take all of the variables in the .env file you created and add them to the Lambda runtime.

If you used one of the supported languages, run one of the following commands to deploy your code. These will only work if the development instructions for each language were followed and the AWS CLI was correctly set up.

make deploy-node    # For Node.js runtime
make deploy-python  # For Python runtime
make deploy-go      # For Go runtime

If you decided to use a different language, you will have to manually configure and deploy the Lambda function.

๐Ÿงช Testing

To test your integration, create and configure an API Gateway stage, and call the Invoke URL with the desired path.

An E2E test should be created and should do the following operations.

  • Create a new test plan (done manually)
  • Call the POST /api/v1/webhooks/subscriptions endpoint to create a new subscription
  • Call the GET /api/v1/subscriptions/{userId} endpoint to retrieve data for the newly created subscription
  • Call the POST /api/v1/webhooks/subscriptions endpoint to renew the subscription
  • Call the GET /api/v1/subscriptions/{userId} endpoint to verify the renewal
  • Call the POST /api/v1/webhooks/subscriptions endpoint to cancel the subscription
  • Call the GET /api/v1/subscriptions/{userId} endpoint to verify the cancelation
  • Clean up all of the test data from the table (done manually)

You can use cURL commands or a tool like Postman to write your tests.

โœ… Submitting

When the exercise is complete, send a pull request from your fork to the parent repository. The forked repository should contain your Lambda source code somewhere in the app folder.

About

Repository for the Fender Digital AWS Coding Exercise for hiring candidates

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 85.4%
  • Shell 11.9%
  • Makefile 1.1%
  • Other 1.6%