A comprehensive full-stack application for tracking job applications and managing user profiles. Built with React, TypeScript, AWS Serverless Architecture, and Infrastructure as Code.
I built CTrackr to replace spreadsheets and manual tracking for job applications with a secure, scalable, cloud-native system. It focuses on real requirements like status tracking, profile-driven document management, and integration with AWS services for resilient infrastructure.
This project demonstrates:
- Full-stack development with modern React and TypeScript
- Serverless architecture using AWS Lambda, API Gateway, and DynamoDB
- Infrastructure as Code with Terraform for reproducible deployments
- Production-ready features including authentication, file management, and user data isolation
- Best practices in security, scalability, and maintainability
- CRUD Operations: Create, read, update, and delete job applications
- Status Tracking: Track applications through various stages (Applied, Interview, Offer, Rejected, etc.)
- Advanced Filtering: Filter applications by status, company, date, and more
- Detailed Information: Store company details, position, salary, location, contact information, notes, and more
- Interview Management: Track interview dates, times, places, and links
- File Attachments: Upload and manage CV and Cover Letter files for each application
- S3 File Management: Automatic file deletion when applications are removed
- Comprehensive Profile: Manage personal information, contact details, and professional links
- Categorized Skills: Organize technical skills by categories with descriptions
- Work Experience: Track employment history with detailed descriptions
- Education: Manage educational background
- Certifications: Store professional certifications
- Projects: Showcase academic and technical projects with achievements
- Languages: Track language proficiencies
- PDF Generation: Generate professional CV/Resume PDFs from profile data (client-side)
- AWS Bedrock Integration: AI-assisted CV and cover letter tailoring using Amazon Bedrock
- ATS-Optimized Content: Designs ATS-aware keywords and content structure based on user profile and job requirements
- Smart Drafting: Generates personalized drafts for users to review and finalize
- Context-Aware: Leverages job descriptions and requirements to create targeted documents
- AWS Cognito Integration: Secure user authentication and authorization
- Email Verification: Email-based account verification via AWS SES
- Protected Routes: Secure access to application features
- User-Specific Data: All data is isolated per user
- Framework: React 18 + TypeScript
- Build Tool: Vite
- Routing: React Router
- State Management: React Context API
- UI Components: Custom components with modern CSS
- PDF Generation: jsPDF for client-side PDF generation
- Authentication: AWS Amplify (Cognito)
- Compute: AWS Lambda (Node.js 20)
- API: AWS API Gateway (HTTP API)
- Database: AWS DynamoDB
- File Storage: AWS S3
- CDN: AWS CloudFront
- DNS: AWS Route 53
- SSL/TLS: AWS Certificate Manager (ACM)
- Email: AWS SES (Simple Email Service)
- Authentication: AWS Cognito
- IaC: Terraform
- Region: ca-central-1 (primary), us-east-1 (CloudFront certificates)
- Domain: Custom domain support via Route 53
CTrackr/
βββ src/ # React frontend source
β βββ components/ # Reusable React components
β β βββ Layout.tsx # Main layout with navigation
β β βββ ProtectedRoute.tsx # Route protection component
β βββ pages/ # Page components
β β βββ Home.tsx # Landing page
β β βββ Login.tsx # Authentication page
β β βββ Applications.tsx # Application list page
β β βββ ApplicationDetail.tsx # Application detail page
β β βββ NewApplication.tsx # Create application page
β β βββ Profile.tsx # User profile management
β βββ contexts/ # React contexts
β β βββ AuthContext.tsx # Authentication context
β βββ utils/ # Utility functions
β β βββ api.ts # API client functions
β β βββ auth.ts # Authentication utilities
β βββ types/ # TypeScript type definitions
β β βββ application.ts # Application types
β β βββ user.ts # User profile types
β βββ vite-env.d.ts # Vite environment types
βββ lambda/ # AWS Lambda functions
β βββ create-application/ # Create new application
β βββ get-application/ # Get single application
β βββ list-applications/ # List applications (with user filtering)
β βββ update-application/ # Update application
β βββ delete-application/ # Delete application + S3 files
β βββ get-profile/ # Get user profile
β βββ update-profile/ # Update user profile
β βββ get-upload-url/ # Generate S3 presigned URLs
β βββ delete-file/ # Delete files from S3
βββ terraform/ # Infrastructure as Code
β βββ main.tf # Main Terraform configuration
β βββ variables.tf # Variable definitions
β βββ outputs.tf # Output values
β βββ terraform.tfvars.example # Example configuration
βββ public/ # Static assets
β βββ logo.svg # Application logo
βββ package.json # Frontend dependencies
- Node.js: 18+ (for frontend and Lambda functions)
- AWS CLI: Configured with appropriate credentials
- Terraform: >= 1.0
- Git: For version control
- AWS Account: With appropriate permissions
- Domain: (Optional) For custom domain setup
- Clone the repository:
git clone https://github.com/SinanCirak/CTrackr.git
cd CTrackr- Install frontend dependencies:
npm install- Install Lambda function dependencies:
cd lambda/create-application && npm install && cd ../..
cd lambda/get-application && npm install && cd ../..
cd lambda/list-applications && npm install && cd ../..
cd lambda/update-application && npm install && cd ../..
cd lambda/delete-application && npm install && cd ../..
cd lambda/get-profile && npm install && cd ../..
cd lambda/update-profile && npm install && cd ../..
cd lambda/get-upload-url && npm install && cd ../..
cd lambda/delete-file && npm install && cd ../..- Configure Terraform variables:
cd terraform
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your AWS details:
# - aws_region: ca-central-1
# - domain_name: your-domain.com (optional)
# - ses_sender_email: your-verified-email@domain.com- Deploy infrastructure:
terraform init
terraform plan
terraform apply- Configure frontend environment:
After deployment, create a
.envfile in the root directory:
VITE_API_BASE_URL=https://your-api-gateway-url.execute-api.ca-central-1.amazonaws.com
VITE_COGNITO_USER_POOL_ID=ca-central-1_xxxxx
VITE_COGNITO_USER_POOL_CLIENT_ID=xxxxx
VITE_AWS_REGION=ca-central-1- Build and deploy frontend:
npm run build
# Upload to S3 (bucket name from Terraform outputs)
aws s3 sync dist/ s3://ctrackr-website-prod --delete
# Invalidate CloudFront cache
aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"npm run devThe application will be available at http://localhost:5173
Create a .env file in the root directory:
VITE_API_BASE_URL=https://your-api-gateway-url.execute-api.ca-central-1.amazonaws.com
VITE_COGNITO_USER_POOL_ID=your-user-pool-id
VITE_COGNITO_USER_POOL_CLIENT_ID=your-client-id
VITE_AWS_REGION=ca-central-1POST /applications- Create a new job applicationGET /applications?userId={userId}- List applications (filtered by user)GET /applications/{id}- Get a specific applicationPUT /applications/{id}- Update an applicationDELETE /applications/{id}- Delete an application and associated S3 files
GET /profile?userId={userId}- Get user profilePUT /profile?userId={userId}- Update user profile
POST /upload-url- Generate presigned URL for S3 upload- Body:
{ fileName, fileType, userId, companyName, fileCategory, timezoneOffset } - Returns:
{ uploadUrl, fileUrl, fileKey }
- Body:
DELETE /file- Delete file from S3- Body:
{ fileKey }
- Body:
- Partition Key:
id(String) - Attributes:
userId(String) - User identifiercompany(String) - Company nameposition(String) - Job positionstatus(String) - Application statusappliedDate(String) - Application datecvUrl(String) - CV file URLcvFileKey(String) - S3 key for CV filecoverLetterUrl(String) - Cover letter file URLcoverLetterFileKey(String) - S3 key for cover letter filecreatedAt(String) - Creation timestampupdatedAt(String) - Last update timestamp- And more...
- Partition Key:
userId(String) - Attributes:
fullName(String)email(String)phone(String)address(String)linkedinUrl(String)githubUrl(String)portfolioUrl(String)summary(String)skillCategories(List) - Categorized skillsexperience(List) - Work experienceeducation(List) - Education historycertifications(List) - Certificationsprojects(List) - Projectslanguages(List) - LanguagescreatedAt(String)updatedAt(String)
- Static website files (HTML, CSS, JS)
- Served via CloudFront CDN
- Origin Access Control (OAC) for secure access
- User-uploaded files organized by user ID
- Structure:
{userId}/{fileCategory}_{companyName}_{DDMMYYYY}_{HHMM}.{ext} - Example:
user-123/CV_Google_07012026_1615.pdf - Versioning enabled
- CORS configured for browser uploads
- AWS Cognito:
- User Pool (
${project_name}-user-pool):- Email-based authentication
- Auto-verified email attributes
- Password policy (min 8 chars, uppercase, lowercase, numbers, symbols)
- Account recovery via verified email
- Email verification with custom templates
- Email sending via AWS SES
- User Pool Client (
${project_name}-client):- OAuth 2.0 flows (code, implicit)
- OAuth scopes (email, openid, profile)
- Callback URLs for domain and localhost
- Logout URLs configured
- User password authentication enabled
- Refresh token authentication enabled
- User Pool Domain (
${project_name}-auth):- Hosted UI for authentication
- Custom domain support (if domain provided)
- User Pool (
- AWS Lambda (9 functions):
create-application- Create new job applicationsget-application- Retrieve single applicationlist-applications- List applications with user filteringupdate-application- Update application detailsdelete-application- Delete application and S3 filesget-profile- Get user profileupdate-profile- Update user profileget-upload-url- Generate S3 presigned URLsdelete-file- Delete files from S3
- AWS API Gateway (HTTP API):
- 9 API routes
- CORS enabled
- Auto-deploy stage
- Lambda integrations
- AWS DynamoDB (2 tables):
ctrackr-applications- Job applications datactrackr-user-profiles- User profile data- Pay-per-request billing mode
- AWS S3 (2 buckets):
ctrackr-website-prod- Frontend static files- Website configuration
- Public access block (CloudFront only)
- Bucket policy for CloudFront OAC
ctrackr-uploads-prod- User file uploads- CORS configuration
- Versioning enabled
- AWS CloudFront:
- Distribution for website bucket
- Origin Access Control (OAC)
- Custom domain support
- SSL/TLS via ACM
- IPv4 and IPv6 support
- AWS Route 53:
- Hosted zone lookup
- A record for CloudFront
- AAAA record for IPv6
- CNAME records for certificate validation
- AWS Certificate Manager (ACM):
- SSL/TLS certificate for CloudFront
- Certificate validation via Route 53
- Region: us-east-1 (required for CloudFront)
- AWS SES (Simple Email Service):
- Email identity for Cognito
- Email verification codes
- Account recovery emails
- AWS IAM:
- Lambda execution role
- IAM role policy for:
- DynamoDB access (applications & user_profiles tables)
- S3 access (uploads bucket)
- Bedrock access (for AI-assisted document generation)
- Lambda Permissions:
- API Gateway invoke permissions for all Lambda functions
- Terraform Providers:
- AWS Provider (v5.0+)
- Archive Provider (for Lambda packaging)
- Terraform Resources: 71+ resources
- Terraform Data Sources: 10+ data sources
- AWS Cognito: User authentication and authorization
- IAM Roles: Least privilege access for Lambda functions
- S3 Bucket Policies: Secure file access via presigned URLs
- CORS Configuration: Proper CORS setup for API Gateway and S3
- Origin Access Control: CloudFront OAC for S3 access
- User Data Isolation: All queries filtered by userId
- Password Policy: Strong password requirements via Cognito
- Email Verification: Secure email-based verification
Landing page with hero section, feature highlights, and call-to-action buttons
Applications dashboard with summary statistics and application cards
Filtered view showing applications by status
Status filter tabs for easy navigation
Main form fields for company, position, dates, and contact information
Job details section with description and requirements fields
Notes section for additional application information
File upload section for CV and Cover Letter
Documents section with uploaded files displayed
Application detail page with status management and editing capabilities
Clean login interface with email/password authentication
User registration form with password requirements
- Login Page: Clean, modern login interface with email/password authentication
- Create Account: User-friendly registration form with password requirements
- Email Verification: Secure account verification via AWS Cognito
- Home Page:
- Hero section with clear call-to-action buttons
- Feature highlights (Track Everything, Status Management, Easy Search)
- Modern purple gradient design with intuitive navigation
- Navigation Bar:
- Responsive header with logo and main navigation links
- User menu dropdown with profile and settings access
- Mobile-friendly hamburger menu
- Applications Dashboard:
- Summary statistics cards (Total Applications, In Interview, Offers)
- Status filter tabs (All, Applied, Interview, Offer, Rejected)
- Application cards with company, position, date, location, and document indicators
- Interactive status dropdown for quick updates
- New Application Form:
- Comprehensive form with company, position, dates, location, salary fields
- Job details section for descriptions and requirements
- File upload areas for CV and Cover Letter with drag-and-drop support
- Real-time file upload progress and management
- Application Detail/Edit:
- Modal or dedicated page for editing application details
- Status management with dropdown selector
- Date pickers for applied, interview, and offer dates
- Notes section for additional information
- Profile Page:
- Comprehensive profile editor with categorized sections
- Skills management with categories and descriptions
- Work experience, education, certifications, and projects sections
- PDF generation for CV/Resume export
- Color Scheme: Purple gradient primary colors with white backgrounds
- Icons: Consistent icon library (React Icons) throughout the application
- Typography: Clear hierarchy with bold headings and readable body text
- Responsive Design: Mobile-first approach with adaptive layouts
- User Experience: Intuitive navigation, clear visual feedback, and smooth interactions
- Presigned URLs: Secure, time-limited upload URLs
- Structured Naming: Automatic file naming with user ID, category, company, date, and time
- Timezone Support: Local timezone-aware file naming
- Automatic Cleanup: Files deleted when applications are removed
- Versioning: S3 versioning enabled for file recovery
- Categorized Skills: Organize skills into categories (e.g., "Frontend", "Backend", "DevOps")
- Rich Text Support: Detailed descriptions for experience, projects, etc.
- PDF Export: Generate professional CVs with all profile data
- Real-time Updates: Instant profile updates with DynamoDB
- Status Workflow: Track applications through multiple stages
- Interview Scheduling: Store interview details (date, time, place, link)
- File Attachments: Associate CV and cover letter with each application
- Notes & Requirements: Store job descriptions and requirements
- React 18: UI framework
- TypeScript: Type safety
- Vite: Build tool and dev server
- React Router: Client-side routing
- jsPDF: PDF generation
- AWS Amplify: Cognito integration
- React Icons: Icon library
- AWS Lambda: Serverless compute (Node.js 20)
- AWS API Gateway: REST API (HTTP API)
- AWS DynamoDB: NoSQL database
- AWS S3: File storage
- AWS CloudFront: CDN
- AWS Cognito: Authentication
- AWS SES: Email service
- AWS Route 53: DNS management
- AWS ACM: SSL/TLS certificates
- AWS IAM: Access management
- Terraform: Infrastructure as Code
- Archive Provider: Lambda function packaging
VITE_API_BASE_URL=https://api-gateway-url.execute-api.ca-central-1.amazonaws.com
VITE_COGNITO_USER_POOL_ID=ca-central-1_xxxxx
VITE_COGNITO_USER_POOL_CLIENT_ID=xxxxx
VITE_AWS_REGION=ca-central-1aws_region = "ca-central-1"
domain_name = "ctrackr.example.com"
ses_sender_email = "noreply@example.com"
project_name = "ctrackr"
environment = "prod"
bucket_name = "ctrackr-website-prod"- Deploy Infrastructure:
cd terraform
terraform init
terraform apply- Build Frontend:
npm run build- Deploy Frontend:
aws s3 sync dist/ s3://ctrackr-website-prod --delete
aws cloudfront create-invalidation --distribution-id E3OJLQS0UXAUC5 --paths "/*"Lambda functions are automatically deployed via Terraform when you run terraform apply. The Terraform configuration packages and uploads each Lambda function.
After making frontend changes:
npm run build
aws s3 sync dist/ s3://ctrackr-website-prod --delete
aws cloudfront create-invalidation --distribution-id YOUR_DISTRIBUTION_ID --paths "/*"- User registration and login
- Create new application
- Upload CV and Cover Letter files
- Delete files from S3
- Update application details
- Filter applications by status
- Create and update user profile
- Generate PDF CV from profile
- Delete application (should also delete S3 files)
After deployment, Terraform provides the following outputs:
api_gateway_url- API Gateway endpoint URLdynamodb_table_name- Applications table namedynamodb_user_profiles_table_name- User profiles table names3_bucket_name- Website bucket names3_uploads_bucket_name- Uploads bucket names3_bucket_website_url- S3 website URLcloudfront_distribution_url- CloudFront distribution URLcloudfront_distribution_id- CloudFront distribution IDcognito_user_pool_id- Cognito User Pool IDcognito_user_pool_client_id- Cognito User Pool Client IDcognito_user_pool_domain- Cognito User Pool Domain
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
MIT
Sinan Cirak
- AWS for serverless infrastructure
- React team for the amazing framework
- Terraform for Infrastructure as Code
- All open-source contributors