Allan Chien
GitHub Repo Back to Portfolio
Work in Progress · AWS · AI

AI-Powered Job Application Tailoring Platform

An intelligent platform that helps job seekers generate tailored CVs and cover letters for specific roles. Users enter their background once, and the app uses Amazon Bedrock to analyze a job description, match the most relevant experience, and produce customized application materials grounded in real information.

The goal is to eliminate the repetitive work of rewriting the same experience for every application — especially useful for students, graduates, and early-career professionals applying to many roles at once.

Architecture diagram

MVP Architecture diagram showing API Gateway, three Lambda services (Profile, Job, Tailoring), RDS Multi-AZ, Secret Manager, and Amazon Bedrock inside a VPC across two availability zones

Request flow

1. User sends a request (profile save, job save, or tailor) to the API Gateway endpoint.

2. API Gateway routes the request to the correct Lambda — Profile Service, Job Service, or Tailoring Service — based on the path and method.

3. The Lambda fetches RDS credentials from Secrets Manager via a VPC Interface Endpoint (no public internet traversal).

4. The Lambda connects to RDS Primary through an ENI in the private subnet of the active AZ (AZ-A or AZ-B).

5. Profile Service writes or reads the user's profile. Job Service stores or retrieves the target job description. Both persist to RDS PostgreSQL.

6. Tailoring Service reads both the profile and job description from RDS, extracts requirements, and scores skill and project matches.

7. The matched context is assembled into a structured prompt and sent to Amazon Bedrock, which generates the tailored CV and cover letter.

8. RDS Primary continuously synchronises to RDS Standby in the second AZ, ensuring Multi-AZ durability without manual intervention.

9. Bedrock's response travels back through the Tailoring Lambda → API Gateway → User.

How it was built

1

Foundation — API Gateway and Lambda with CDK

Used AWS CDK to define the API Gateway and Lambda function as Infrastructure as Code. This gave a repeatable, version-controlled deployment rather than manually clicking through the AWS console.

After deploying, the profile service endpoint was verified with a simple curl request:

curl -X PUT "https://<api-id>.execute-api.us-east-1.amazonaws.com/profile" {"message": "Profile service API is running"}

Lambda code was then updated to use Code.fromAsset instead of inline code, which lets CDK bundle the function into a zip and upload it to the CDK bootstrap S3 bucket automatically.

2

RDS Integration — storing profiles and job descriptions

Added an RDS PostgreSQL database inside a private VPC subnet. The Lambda needed a VPC Interface Endpoint for Secrets Manager so it could retrieve database credentials without going over the public internet — an architecture fix required after hitting a connectivity issue with the isolated subnet.

Once resolved, the profile service could write to and read from RDS:

curl "https://<api-id>.execute-api.us-east-1.amazonaws.com/profile?email=allan@example.com" {"profile_id": 1, "email": "allan@example.com", "full_name": "Allan Chien", ...}

A separate job description endpoint was also added to store the role details that the AI will tailor against:

curl -X PUT ".../job-description" -d '{"company_name": "Catalyst Cloud", "job_title": "Junior DevOps Engineer", ...}' {"message": "Job description saved successfully", "job_id": 1}
3

AI Tailoring Lambda — matching and generation

Built a tailoring Lambda that accepts an email and job ID, fetches both the user profile and job description from RDS, extracts the key requirements from the raw job description, and scores each skill and project in the profile against those requirements.

The matched context is then assembled into a structured prompt payload ready to be sent to Amazon Bedrock for CV and cover letter generation:

curl -X POST ".../tailor-preview" -d '{"email": "allan@example.com", "job_id": 1}' { "extracted_requirements": ["aws", "linux", "ci/cd"], "matched_skills": ["aws"], "matched_projects": [{"name": "2048 CI/CD Project", "score": 10, "matched_terms": ["ci/cd", "aws"]}], "prompt_context": { ... } }

The next phase connects this prompt context to Bedrock to generate the final application documents.

Why I built this

Job applications are repetitive. Every role needs a slightly different CV and a new cover letter, but the underlying experience stays the same. I wanted to build something that automates the tailoring step while keeping the output grounded in real, structured data rather than hallucinated content.

This project also gave me a reason to work with a more complex AWS architecture — VPCs, private subnets, Secrets Manager, RDS, and CDK all working together — rather than just Lambda and S3 in isolation.

The platform is still in progress. Phase 2 will complete the Bedrock integration and add document export, with a frontend planned after the backend is solid.

What I learned

This project pushed me into areas I had not worked with before, including private networking in AWS, CDK-managed infrastructure, and building a multi-Lambda API from scratch.

  • Learned how to use AWS CDK to define and deploy API Gateway and Lambda as Infrastructure as Code.
  • Gained hands-on experience with VPC private subnets and why Lambdas in isolated subnets need Interface Endpoints to reach Secrets Manager.
  • Understood the difference between psycopg binary and Python implementations and why Lambda packaging matters for native dependencies.
  • Built a multi-endpoint REST API across two Lambdas (profile service and tailoring service) behind a single API Gateway.
  • Learned how to extract and score structured requirements from unstructured job description text programmatically.
  • Gained practical experience designing a prompt context payload to feed into a generative AI model (Amazon Bedrock).