AWS Full-Stack Social Media Platform
A production-ready, cloud-native social media platform demonstrating enterprise-grade AWS architecture, advanced DynamoDB patterns, and modern full-stack development practices.
TODO:<ADD_IMAGE - Architecture diagram showing the complete system: CloudFront -> S3 (React SPA) -> API Gateway -> Lambda -> DynamoDB, with Cognito for auth and CloudWatch for observability>
Project Overview
This is an Instagram-like social media application built as a portfolio project to showcase senior software engineering skills across cloud architecture, infrastructure as code, and modern full-stack development. The project emphasizes scalability, observability, developer experience, and production-ready patterns.
Key Highlights
- Monorepo Architecture: Nx-powered workspace with intelligent build caching and affected project detection
- Serverless-First: 100% serverless AWS architecture with automatic scaling and pay-per-use pricing
- Advanced Data Modeling: Single-table DynamoDB design with strategic GSIs for optimal query patterns
- Multi-Environment CI/CD: GitFlow-based deployment pipeline with automated testing and validation
- Production Observability: Comprehensive logging, tracing, and metrics using AWS Lambda Powertools
- Enterprise Security: AWS Cognito authentication with OIDC-based GitHub Actions deployment
Architecture & Design Patterns
System Architecture
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ CloudFront │─────▶│ S3 Bucket │ │ API Gateway │
│ (CDN) │ │ (React SPA) │ │ (REST API) │
└─────────────┘ └──────────────┘ └────────┬────────┘
│
┌───────────────────────────────┼────────────┐
│ │ │
┌────▼────┐ ┌────▼─────┐ ┌────▼─────┐
│ Lambda │ │ Lambda │ │ Lambda │
│ Auth │ │ Posts │ │ Photos │
└────┬────┘ └────┬─────┘ └────┬─────┘
│ │ │
┌────────────────┴──────────────────────────────┴────────────┴─────┐
│ DynamoDB (Single Table) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ PK │ SK │ GSI1PK │ GSI2PK │ │
│ │ USER#123 │ PROFILE │ ... │ ... │ │
│ │ POST#456 │ METADATA │ ... │ ... │ │
│ │ POST#456 │ LIKE#user789 │ ... │ ... │ │
│ │ POST#456 │ COMMENT#ts#commentId │ ... │ ... │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│
┌────▼────────┐
│ DynamoDB │
│ Streams │
└────┬────────┘
│
┌────▼─────────┐
│ Lambda │
│ (Aggregation)│
└──────────────┘
TODO:<ADD_IMAGE - Detailed architecture diagram with all AWS services, security groups, and data flow>
Technology Stack
Backend
- Runtime: Node.js 20.x with TypeScript 5.9
- Infrastructure: AWS CDK 2.x for infrastructure as code
- Compute: AWS Lambda with esbuild bundling
- Database: DynamoDB with single-table design
- Storage: S3 for image storage with presigned URLs
- API: API Gateway REST API with Lambda proxy integration
- Auth: AWS Cognito User Pools with JWT tokens
- Observability: AWS Lambda Powertools (Logger, Tracer, Metrics)
- Middleware: Middy for Lambda middleware composition
Frontend
- Framework: React 19 with TypeScript
- Routing: React Router 7 with file-based routing
- State Management: TanStack Query for server state
- Forms: TanStack Form with Zod validation
- UI Components: Radix UI primitives with Tailwind CSS
- Auth: AWS Amplify UI for authentication flows
- Build Tool: Rsbuild (Rspack-based)
- Hosting: CloudFront + S3 with CDK deployment
DevOps & Tools
- Monorepo: Nx 22 with intelligent caching
- CI/CD: GitHub Actions with OIDC authentication
- Workflows: GitFlow with multi-environment deployments
- Testing: Vitest for unit/integration tests
- Linting: ESLint with TypeScript rules
- Code Quality: Prettier, TypeScript strict mode
Advanced Patterns & Best Practices
1. Single-Table DynamoDB Design
One of the most complex aspects of this project is the sophisticated single-table design pattern:
// Example: Efficient querying with composite keys
// Get all comments for a post (chronologically sorted)
PK: POST#<postId>
SK: COMMENT#<timestamp>#<commentId>
// Get all posts by a user (via GSI)
GSI1PK: USER#<userId>
GSI1SK: POST#<timestamp>
// Check if user liked a post (single GetItem)
PK: POST#<postId>
SK: LIKE#<userId>
Key Design Decisions:
- Denormalized Counts: Like/comment counts stored on post entity for O(1) reads
- Strategic GSIs: 3 global secondary indexes for different access patterns
- Composite Sort Keys: Enable range queries and chronological ordering
- Condition Expressions: Prevent duplicate likes/follows at the database level
See Database ERD Documentation for complete schema design.
TODO:<ADD_IMAGE - DynamoDB table structure visualization with access patterns>
2. Lambda Middleware Pattern
Custom middleware composition using Middy for cross-cutting concerns:
// apps/social-be/src/lambda/middleware/apiHandler.ts
export const apiHandler = (handler: Handler) =>
middy(handler)
.use(httpHeaderNormalizer())
.use(httpEventNormalizer())
.use(httpJsonBodyParser())
.use(validator({ eventSchema }))
.use(httpCors({ origins: [...] }))
.use(httpErrorHandler())
.use(injectLambdaContext(logger))
.use(captureLambdaHandler(tracer))
Benefits:
- Consistent error handling across all Lambda functions
- Automatic CORS configuration with dynamic origins
- Built-in request/response validation
- Structured logging and distributed tracing
- Request normalization and parsing
3. Nx Monorepo Optimization
Intelligent build and deployment optimization using Nx affected commands:
# Only build/test/deploy what changed
- name: Check affected projects
run: npx nx show projects --affected --type=app
# Smart caching for faster builds
- name: Build affected projects
run: npx nx affected -t build
Performance Gains:
- ~70% reduction in CI time by skipping unaffected projects
- Shared dependency caching across builds
- Parallel execution of independent tasks
- Type-safe shared libraries (
@chahm/types,@chahm/ui-components)
TODO:<ADD_IMAGE - Nx dependency graph visualization>
4. Multi-Environment GitFlow Pipeline
Production-grade deployment workflow with environment promotion:
feature/* ──PR──> develop ──auto──> DEV environment
│
└──release/*──> STAGING environment
│
└──PR+approval──> main ──> PRODUCTION
Environment Isolation:
- Separate AWS accounts/roles per environment
- Environment-specific configuration via CDK context
- Automated deployment with manual production approval
- Stack naming convention:
{Project}-{env}(e.g.,BeStack-prod)
See GitFlow Deployment Guide for implementation details.
5. Infrastructure as Code Best Practices
CDK Patterns Used:
- Custom constructs for reusable infrastructure patterns
- Environment-aware stack configuration
- Removal policies and lifecycle management
- Cross-stack references with CloudFormation outputs
- CDK Aspects for tagging and compliance
// Example: Environment-aware configuration
const table = new Table(this, 'Table', {
billingMode: isProduction
? BillingMode.PROVISIONED
: BillingMode.PAY_PER_REQUEST,
removalPolicy: isProduction
? RemovalPolicy.RETAIN
: RemovalPolicy.DESTROY,
});
Getting Started
Prerequisites
- Node.js: >= 20.x
- AWS Account: With appropriate IAM permissions
- AWS CLI: Configured with credentials
- Git: For version control
Installation
# Clone the repository
git clone https://github.com/gchahm/aws-full-stack.git
cd aws-full-stack
# Install dependencies
npm install
# Bootstrap AWS CDK (one-time setup)
npx cdk bootstrap aws://ACCOUNT-ID/REGION
Local Development
Backend Development
# Start local API with SAM CLI
nx run be:dev
# Watch mode (auto-synth on changes)
nx run be:dev:watch
# The API will be available at http://localhost:3000
Frontend Development
# Start React development server
nx run social-fe:dev
# The app will be available at http://localhost:5173
Run Tests
# Test all affected projects
nx affected -t test
# Test specific project
nx run be:test
nx run social-fe:test
# Type check
nx affected -t typecheck
Deployment
Deploy to Dev Environment
# Deploy backend
nx run be:deploy
# Deploy frontend (requires backend to be deployed first)
nx run social-fe:deploy
Deploy to Staging/Production
Deployments to staging and production are automated through GitHub Actions:
- Staging: Push to
release/*branch - Production: Merge to
mainbranch (requires approval)
Monitoring & Observability
AWS Lambda Powertools Integration
All Lambda functions include:
- Structured Logging: JSON logs with correlation IDs
- Distributed Tracing: X-Ray tracing for request flows
- Custom Metrics: Business metrics published to CloudWatch
import { Logger } from '@aws-lambda-powertools/logger';
import { Tracer } from '@aws-lambda-powertools/tracer';
import { Metrics } from '@aws-lambda-powertools/metrics';
const logger = new Logger({ serviceName: 'posts' });
const tracer = new Tracer({ serviceName: 'posts' });
const metrics = new Metrics({ namespace: 'SocialApp' });
// Automatic correlation of logs, traces, and metrics
logger.info('Processing post creation', { postId, userId });
tracer.putAnnotation('userId', userId);
metrics.addMetric('PostCreated', MetricUnits.Count, 1);
TODO:<ADD_IMAGE - CloudWatch dashboard screenshot showing metrics, logs, and traces>
Key Metrics Tracked
- API request latency (p50, p90, p99)
- Lambda cold start duration
- DynamoDB read/write capacity usage
- Error rates by endpoint
- Custom business metrics (posts created, likes, etc.)
Security
Authentication & Authorization
- User Authentication: AWS Cognito User Pools with MFA support
- API Security: JWT token validation on all protected endpoints
- CORS: Dynamic CORS origins based on environment
- IAM Roles: Least-privilege IAM roles for Lambda functions
- Secrets Management: AWS Secrets Manager for sensitive data
Infrastructure Security
- OIDC Authentication: GitHub Actions uses OIDC (no long-lived credentials)
- Network Isolation: VPC configuration for production environments
- Encryption: Data encrypted at rest (DynamoDB, S3) and in transit (TLS)
- Security Headers: CloudFront configured with security headers
Project Structure
aws-full-stack/
├── apps/
│ ├── be/ # Backend application
│ │ ├── src/
│ │ │ ├── lambda/ # Lambda function handlers
│ │ │ │ ├── posts/ # Post-related endpoints
│ │ │ │ ├── photos/ # Photo upload endpoints
│ │ │ │ ├── auth/ # Authentication handlers
│ │ │ │ └── middleware/ # Shared middleware
│ │ │ └── database/ # DynamoDB data access layer
│ │ ├── infra/ # CDK infrastructure code
│ │ └── project.json # Nx project configuration
│ │
│ └── social-fe/ # Frontend application
│ ├── src/
│ │ ├── routes/ # File-based routing
│ │ ├── components/ # React components
│ │ └── lib/ # Utilities and hooks
│ ├── infra/ # Frontend CDK stack
│ └── project.json
│
├── libs/ # Shared libraries
│ ├── types/ # Shared TypeScript types
│ ├── ui-components/ # Reusable UI components
│ └── ui-logic/ # Shared UI logic
│
├── .github/
│ ├── workflows/ # GitHub Actions workflows
│ │ ├── ci.yml # Continuous integration
│ │ └── deploy.yml # Multi-environment deployment
│ ├── actions/ # Reusable composite actions
│ └── scripts/ # Deployment scripts
│
├── docs/ # Documentation
│ ├── database-erd.md # Database design
│ └── gitflow-deployment-guide.md
│
├── nx.json # Nx workspace configuration
└── package.json # Root dependencies
Performance Optimizations
Backend Optimizations
- Lambda Bundling: esbuild for fast, minimal bundles (~500KB avg)
- Connection Reuse: DynamoDB client connection pooling
- Denormalized Data: Pre-computed counts to avoid aggregations
- Strategic Indexes: GSIs designed for specific query patterns
- Presigned URLs: Direct S3 uploads bypassing API Gateway limits
Frontend Optimizations
- Code Splitting: Route-based code splitting with React Router
- Image Optimization: CloudFront CDN with edge caching
- React Query: Aggressive caching and background refetching
- Lazy Loading: Component-level lazy loading
- Build Optimization: Rsbuild for fast bundling with Rspack
TODO:<ADD_IMAGE - Lighthouse performance scores screenshot>
Testing Strategy
Test Coverage
# Unit tests for business logic
nx run be:test
# Integration tests for API endpoints
nx run be:test:integration
# E2E tests for critical user flows
nx run social-fe:test:e2e
Testing Patterns
- Unit Tests: Pure functions, data access layer, utilities
- Integration Tests: Lambda handlers with mocked AWS services
- E2E Tests: Critical user flows (auth, post creation, likes)
- CDK Tests: Infrastructure snapshot testing
Key Features Implemented
User Management
- User registration and authentication via Cognito
- User profiles with bio and profile images
- Follow/unfollow functionality
- Follower/following counts
Posts & Content
- Create posts with image uploads to S3
- Like/unlike posts with optimistic updates
- Comment on posts with real-time counts
- Delete posts and comments
- Paginated feeds
Image Handling
- Presigned S3 URLs for secure direct uploads
- Automatic image metadata storage in DynamoDB
- CloudFront CDN for fast image delivery
CI/CD Pipeline
Continuous Integration (Pull Requests)
- Check affected projects (Nx)
- Lint affected code
- Type check
- Run tests
- Build affected projects
- Validate CDK synthesis
- Comment PR with results
Continuous Deployment (Branch Push)
- Determine environment (develop/release/main)
- Check affected projects
- Synthesize CDK templates
- Deploy to AWS (backend)
- Deploy to AWS (frontend)
- Run health checks
- Validate deployment
TODO:<ADD_IMAGE - GitHub Actions workflow visualization>
Summary
Architecture & Design
- Cloud-native serverless architecture
- Event-driven patterns with DynamoDB Streams
- Advanced single-table NoSQL design
- Microservices separation of concerns
- Infrastructure as Code (IaC)
Code Quality & Maintainability
- TypeScript strict mode with comprehensive types
- Monorepo architecture with shared libraries
- Consistent error handling and logging
- Middleware composition for cross-cutting concerns
- Comprehensive code documentation
DevOps & Operations
- Multi-environment deployment pipeline
- GitFlow workflow with environment promotion
- Intelligent build optimization (Nx affected)
- Infrastructure drift detection via IaC
- Automated testing and validation
Observability & Reliability
- Structured logging with correlation IDs
- Distributed tracing with X-Ray
- Custom CloudWatch metrics and dashboards
- Health check endpoints
- Error tracking and alerting
Security & Compliance
- OIDC-based CI/CD (no static credentials)
- Least-privilege IAM roles
- Secrets management with AWS Secrets Manager
- Encryption at rest and in transit
- Security headers and CORS configuration
Performance & Scalability
- Serverless auto-scaling
- Database query optimization with GSIs
- CDN edge caching
- Connection pooling and reuse
- Bundle size optimization
Documentation
- Database Design & ERD - Comprehensive DynamoDB schema design
- GitFlow Deployment Guide - Multi-environment CI/CD setup
Contributing
This is a portfolio project, but contributions and suggestions are welcome:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
About
This project was built to demonstrate production-ready full-stack development skills for senior software engineering roles. It showcases:
- Deep understanding of AWS cloud architecture
- Advanced database design patterns
- Modern frontend development practices
- DevOps and CI/CD expertise
- Production observability and monitoring
- Security best practices
- Code quality and maintainability
Built by Gustavo Chahm
TODO:<ADD_IMAGE - Personal logo or headshot>