Juan Rodríguez

Project Yupibaby

This project is a personal web site to create and share babyshower gift lists, designed to help parents and friends organize and manage gift contributions efficiently. It allows users to create personalized gift lists for baby showers, where they can add items they wish to receive as gifts, along with descriptions and images. They can also add items from a predefined catalog, making it easier for users to find and add popular baby products to their lists.
The frontend is built with React, TypeScript, Tailwind CSS, Radix UI, providing a responsive and user-friendly interface.
The backend is powered by AWS Lambda functions, enabling serverless architecture for scalability and cost-efficiency. API Gateway is used to manage and secure API endpoints, while DynamoDB hosts the database for storing user data and content. User authentication is handled by AWS Cognito, ensuring secure access to the platform.
Overall, this project demonstrates some of my abilities to design and implement a full-stack application using modern web technologies and AWS services. This project is composed of 1 stack that handles all parts of the application, from user authentication to content delivery.
The design structure of the application is organized into several layers, including the database layer, backend layer, and frontend layer. It also includes important components such as the authentication system, event handling, notifications via email and content management, all of which work together to provide a seamless user experience.

URL: yupibaby.com

Design structure
          
Users AWS Cloud CloudFront yupibaby.com DynamoDB Rest Api Lambdas Notifier Website Assets VPC Cognito User Pool WAF CloudWatch DynamoDB Streams SES

CDK / Infrastructure

This code snippet demonstrates how to set up an yupibaby stack. It includes the creation of a Cognito User Pool and a User Pool Client with secure configurations suitable for a Single Page Application (SPA). Also, it outlines the steps to create a VPC, DynamoDB tables, IAM roles, API Gateway REST API, Lambda functions, and CloudFront distributions for both the frontend and API endpoints.

    
export class AuthStack extends Stack { constructor(scope: Construct, id: string, props: AuthStackProps) { super(scope, id, props); // Step 1: Create a Cognito User Pool // for this step, we will create a user pool with secure configurations, such as: // - Enabling self sign-up with email verification // - Setting password policies (e.g., minimum length, require symbols, etc.) // - Configuring account recovery options // - Enabling multi-factor authentication (MFA) if needed // Step 2: Create a User Pool Client // for this step, we will create a user pool client with secure authentication flows and OAuth settings, such as: // - Enabling the authorization code grant flow with PKCE for SPAs // - Setting appropriate token validity periods (e.g., access token, ID token, refresh token) // - Configuring allowed OAuth scopes (e.g., openid, profile, email) // - Specifying callback URLs and logout URLs for the application // Step 3: Create a CfnOutput to share the User Pool ID and Client ID // Step 1: Crear un bucket S3 para almacenar los assets (imágenes, etc.) // This bucket will be used by the backend to store and serve assets, // Those assets are mainly images uploaded by users for their gift lists, but it can also be used to store other types of content if needed. // Step 2: Create a VPC and security groups for the Lambda functions // The VPC will provide network isolation for the Lambda functions, ensuring that they can only communicate with each other and not be accessed from the public internet // We will add Gateway Endpoints for S3 and DynamoDB to allow private communication between the Lambda functions and these services without going through the public internet // Step 3: Create DynamoDB tables for the application // We will create several tables to store different types of data, such as users, gift lists, products, events, etc. // Each table will have appropriate partition keys and sort keys to optimize query performance based on the access patterns of the application // Step 4: Create an IAM role for the Lambda functions // This role will have permissions to access the DynamoDB tables and the S3 bucket, as well as any other AWS services that the Lambdas need to interact with like cloudwatch for logging. // Step 5: Create API Gateway REST API // We will create a REST API to expose the backend functionality to the frontend application. // Step 6: Create Cognito User Pool // We will create a Cognito User Pool to handle user authentication and management for the application. // The User Pool will be configured with secure settings, such as enabling self sign-up with email verification, setting password policies, and configuring account recovery options. // Step 7: Create Lambda functions and API Gateway endpoints // We will create several Lambda functions to handle the backend logic for the application, such as user authentication, gift list management, product catalog management, etc. // Each Lambda function will be integrated with API Gateway to expose its functionality through REST API endpoints. // Step 8: Create notifications with email Lambda functions and integrate them with DynamoDB streams // We will create Lambda functions that will be triggered by DynamoDB streams to send email notifications to users when certain events occur, such as when a contribution is made. // These Lambda functions will use Amazon SES to send emails, and they will be configured with the necessary permissions to access SES and cloudwatch for logging. // Step 9: Create CloudFront distribution for the frontend application // We will create a CloudFront distribution to serve the frontend application, which is built with React and hosted in an S3 bucket. // The distribution will be configured with an SSL certificate from ACM for secure HTTPS access, and it will also include caching policies to optimize performance. // Additionally, we will create a separate CloudFront distribution for the API Gateway endpoints to improve performance and security, and we will configure it with a web ACL from AWS WAF to protect against common web exploits. // The API distribution will also be configured to include the Authorization header in the cache key for authenticated endpoints, ensuring that responses are properly cached based on the user's authentication status. // Step 10: Deploy the React frontend application to the S3 bucket and invalidate the CloudFront cache // We will use the AWS CDK's BucketDeployment construct to deploy the built React application from the local 'dist' directory to the S3 bucket. // After deployment, we will invalidate the CloudFront cache to ensure that users receive the latest version of the frontend application when they access it. } }