cloudwithshad
๐Ÿ“„
GROUP PROJECT ยท 1 WEEK ยท MINI-AWARDS

DocSmart โ€” AI CV & Document Analyzer

A web app that reads any CV, transcript, or scholarship application โ€” extracts skills, matches them to job descriptions, scores the document, and suggests improvements. Built in groups. Deployed on EC2. The one everyone in the cohort will actually use.

3-4
PER TEAM
1 week
TO BUILD
4 services
AWS USED
5
AWARDS
1
The vision โ€” what you're building
10 min

Every job seeker has the same problem: your CV gets 6 seconds of attention. Recruiters skim. ATS bots scan for keywords. Most CVs never reach a human reader.

DocSmart fixes this. Upload your CV (PDF or image). Paste a job description. The app returns:

  • ๐Ÿ“Š Match score โ€” "Your CV matches 67% of the job's required skills"
  • โœ… Matched skills โ€” what you have that the job wants (Python, AWS, React, etc.)
  • โš ๏ธ Missing skills โ€” what's in the job description but not in your CV
  • ๐Ÿ“ Improvement suggestions โ€” "Add 'Lambda' explicitly", "Quantify your achievements"
  • ๐Ÿท๏ธ Extracted entities โ€” names, companies, dates, certifications detected automatically
๐ŸŽฏ Why this one feels different

The other group projects are for hypothetical users. This one is for YOU. Every student in this cohort has a CV they're trying to improve. After demo day, you'll run your own CV through your own app. So will your friends. So will future bootcamp cohorts. Build it well โ€” it'll keep getting used.

2
Team roles โ€” who does what
15 min
1. UI Lead
"The Experience Designer"
  • Owns the upload + paste-job-description flow
  • Designs the score visualization (match circle, bar charts)
  • Picks fonts that say "professional, hireable"
  • Handles result presentation (skill chips, callouts)
2. Textract Engineer
"The Document Whisperer"
  • Wires Textract to handle PDFs and images
  • Cleans the extracted text intelligently
  • Detects sections (Education, Experience, Skills)
  • Handles edge cases (scans, low-res, multi-column)
3. Matching Engineer
"The Skill Detector"
  • Builds the skills taxonomy (Python, AWS, React, etc.)
  • Wires Comprehend for entity + key phrase extraction
  • Writes the matching/scoring algorithm
  • Designs the improvement-suggestions logic
4. AWS & Polish Lead
"The Operator"
  • Provisions EC2 + IAM + S3
  • Sets up deployment + restart policies
  • Owns demo day prep + presentation deck
  • Curates demo CVs (real ones, anonymized)
Your secret weapon

Every team member has their own CV. Use each other as test data. Your team owns 4 real CVs out of the gate โ€” more than any other team. Anonymize them (remove email/phone for demos), and you'll have a much better app by Friday than teams using only public sample CVs.

3
Architecture โ€” simple but powerful
10 min
Job Seeker uploads CV EC2 + Streamlit port 8501 upload form + match results ๐Ÿ“ S3 bucket ๐Ÿ“„ Textract extracts CV text ๐Ÿง  Comprehend entities + key phrases ๐Ÿท๏ธ skills.json your team's curated skills taxonomy โšก Match Engine match score ยท gaps suggestions (your code, no AWS!)
CV โ†’ Textract (extract) + Comprehend (analyze) + skills.json (compare) โ†’ Match Engine scores it โ†’ Streamlit shows results.
ComponentWhat it does
EC2 t2.microStreamlit app โ€” upload form + results display
S3 bucketTemporary storage for uploaded CVs (delete after processing)
TextractExtracts text + table data from PDF and image CVs
ComprehendExtracts entities (people, companies, dates) + key phrases
skills.json (local)Your curated taxonomy โ€” Python, AWS, React, Project Mgmt, etc.
Match engine (Python)Compares extracted skills to job description, scores, suggests
4
Build it locally โ€” upload + display
3 hours

Set up the project:

mkdir docsmart cd docsmart python -m venv venv source venv/bin/activate pip install streamlit boto3 pandas plotly

The two-column layout: left = upload, right = results. Create app.py:

import streamlit as st from aws_helpers import extract_cv_text, analyze_cv from matcher import match_cv_to_job, suggest_improvements st.set_page_config(page_title="DocSmart โ€” AI CV Analyzer", page_icon="๐Ÿ“„", layout="wide") st.title("๐Ÿ“„ DocSmart โ€” AI CV Analyzer") st.markdown("_Upload your CV. Paste a job description. Get matched, scored, and improved in 30 seconds._") col_left, col_right = st.columns([1, 1]) with col_left: st.subheader("๐Ÿ“ Your CV") cv_file = st.file_uploader("Upload (PDF or image)", type=["pdf", "png", "jpg", "jpeg"]) st.subheader("๐Ÿ’ผ The job you want") job_desc = st.text_area("Paste the full job description", height=250, placeholder="e.g., 'We're hiring a Cloud Engineer with 2+ years experience in AWS, Python, Lambda, and CI/CD...'") analyze_btn = st.button("๐Ÿ” Analyze my match", use_container_width=True, type="primary") with col_right: if analyze_btn and cv_file and job_desc: with st.spinner("Reading your CV..."): cv_bytes = cv_file.read() cv_text = extract_cv_text(cv_bytes, cv_file.type) cv_analysis = analyze_cv(cv_text) with st.spinner("Matching against the job..."): match_result = match_cv_to_job(cv_analysis, job_desc) suggestions = suggest_improvements(cv_analysis, match_result) # Render results โ€” score circle, matched/missing skill chips, suggestions score = match_result['score'] color = '#2EA043' if score >= 70 else ('#F4B942' if score >= 50 else '#C62828') st.markdown(f""" <div style="text-align:center; padding:20px; background:#0A1628; border-radius:12px;"> <div style="font-size:80px; font-weight:800; color:{color};">{score}%</div> <div style="color:#fff; font-size:14px;">Match Score</div> </div>""", unsafe_allow_html=True) st.subheader("โœ… Skills you have") st.markdown(" ".join([f"`{s}`" for s in match_result['matched']])) st.subheader("โš ๏ธ Missing from your CV") st.markdown(" ".join([f"`{s}`" for s in match_result['missing']])) st.subheader("๐Ÿ“ Improvements") for s in suggestions: st.info(s) else: st.info("๐Ÿ‘ˆ Upload a CV and paste a job description to see your match.")

Run with streamlit run app.py. The empty-state shows on the right until the user uploads + analyzes.

5
Wire up Textract & Comprehend
3 hours

Create aws_helpers.py:

import boto3 textract = boto3.client('textract') comprehend = boto3.client('comprehend') def extract_cv_text(file_bytes, mime_type): """Pull text from a PDF or image CV via Textract.""" response = textract.detect_document_text(Document={'Bytes': file_bytes}) lines = [] for block in response['Blocks']: if block['BlockType'] == 'LINE': lines.append(block['Text']) return '\n'.join(lines) def analyze_cv(cv_text): """Run Comprehend to extract entities + key phrases.""" # Truncate to Comprehend's 5000-byte limit safe_text = cv_text[:4900] entities = comprehend.detect_entities(Text=safe_text, LanguageCode='en') key_phrases = comprehend.detect_key_phrases(Text=safe_text, LanguageCode='en') return { 'full_text': cv_text, 'entities': [ {'text': e['Text'], 'type': e['Type'], 'score': e['Score']} for e in entities['Entities'] ], 'key_phrases': [ {'text': p['Text'], 'score': p['Score']} for p in key_phrases['KeyPhrases'] ] }

Test it locally with a sample PDF. Print the output to check what Textract extracts before moving on.

Textract handles multi-page PDFs differently

For PDFs over 1 page, use the async start_document_text_detection API instead. For demo simplicity, accept single-page PDFs OR images only โ€” that's what 95% of CVs are anyway. Mention this in your demo as a "v2 improvement".

6
The skill matching engine
4 hours

This is the brain of the app. Create skills.json โ€” your curated taxonomy:

{ "languages": ["Python", "JavaScript", "TypeScript", "Java", "Go", "Rust", "C++", "C#", "PHP", "Ruby", "SQL", "Bash"], "cloud": ["AWS", "Azure", "GCP", "EC2", "S3", "Lambda", "VPC", "RDS", "DynamoDB", "CloudFront", "IAM", "CloudFormation", "Terraform"], "web": ["React", "Vue", "Angular", "Next.js", "Django", "Flask", "FastAPI", "Node.js", "Express", "HTML", "CSS", "Tailwind"], "data": ["Pandas", "NumPy", "PyTorch", "TensorFlow", "Scikit-learn", "Spark", "Airflow", "Tableau", "Power BI"], "devops": ["Docker", "Kubernetes", "CI/CD", "Jenkins", "GitHub Actions", "GitLab CI", "Linux", "Git", "Nginx"], "soft": ["Leadership", "Communication", "Project Management", "Agile", "Scrum", "Mentoring", "Public Speaking"] }

Now create matcher.py:

import json import re with open('skills.json') as f: SKILL_TAXONOMY = json.load(f) ALL_SKILLS = [skill for category in SKILL_TAXONOMY.values() for skill in category] def extract_skills(text): """Find which known skills appear in the given text.""" text_lower = text.lower() found = [] for skill in ALL_SKILLS: # Use word boundaries to avoid 'Java' matching 'JavaScript' pattern = r'\b' + re.escape(skill.lower()) + r'\b' if re.search(pattern, text_lower): found.append(skill) return found def match_cv_to_job(cv_analysis, job_description): """Compare CV skills to job-description skills. Score 0-100.""" cv_skills = set(extract_skills(cv_analysis['full_text'])) job_skills = set(extract_skills(job_description)) if not job_skills: return {'score': 0, 'matched': [], 'missing': [], 'extra': list(cv_skills)} matched = cv_skills & job_skills missing = job_skills - cv_skills extra = cv_skills - job_skills score = int(round(len(matched) / len(job_skills) * 100)) return { 'score': score, 'matched': sorted(matched), 'missing': sorted(missing), 'extra': sorted(extra) } def suggest_improvements(cv_analysis, match_result): """Generate 3-5 actionable suggestions based on the analysis.""" suggestions = [] if match_result['missing']: top_missing = match_result['missing'][:3] suggestions.append( f"๐Ÿ“Œ Add these missing skills if you have them: {', '.join(top_missing)}" ) if match_result['score'] < 50: suggestions.append( "โš ๏ธ Match is below 50%. Consider if this role is the right fit, or rewrite your CV around its key requirements." ) if len(cv_analysis['full_text']) < 500: suggestions.append( "๐Ÿ“ Your CV seems short. Aim for 1-2 pages with quantified achievements." ) has_metrics = any(c.isdigit() for c in cv_analysis['full_text']) if not has_metrics: suggestions.append( "๐Ÿ“Š Add numbers! 'Increased revenue by 30%' beats 'increased revenue'." ) if match_result['score'] >= 70: suggestions.append( "๐ŸŽฏ Strong match โ€” apply with confidence. Customize the cover letter using the matched skills." ) return suggestions[:5]
Hint: making your skills.json richer (huge differentiator)

The basic taxonomy above is a starting point. Real differentiators: add aliases (e.g., "JavaScript" โ†” "JS" โ†” "ECMAScript"), related skills ("Lambda" implies "AWS"), and seniority indicators ("Senior", "Lead", "Manager"). The team with the smartest taxonomy delivers the smartest results โ€” and that's what wins Most Innovative.

7
Deploy & polish
4 hours

Same EC2 setup as Projects 1 & 2: t2.micro, Amazon Linux 2023, port 8501 open, IAM role attached with AmazonTextractFullAccess + ComprehendFullAccess + S3ReadOnly.

Install on the server:

sudo yum install -y git python3-pip pip3 install streamlit boto3 pandas plotly git clone https://github.com/YOUR-TEAM/docsmart.git cd docsmart streamlit run app.py --server.port 8501 --server.address 0.0.0.0

Award-winning polish ideas

  • Skill chip styling โ€” use coloured "chips" instead of plain text. Matched = green, Missing = red, Extra = blue. Looks like Stack Overflow.
  • Animated score circle โ€” use Plotly's gauge chart for the match score
  • "Try it on these sample CVs" โ€” provide 3 ready-to-load sample CVs (anonymized teammates) so demo visitors don't have to upload their own
  • "Try it on these sample jobs" โ€” paste-ready job descriptions for common Ghana roles (cloud engineer, frontend dev, data analyst)
  • Download report โ€” generate a PDF report of the match results (uses Streamlit's st.download_button + reportlab)
  • Privacy notice โ€” "Your CV is processed in-memory and never stored. We delete uploads after analysis." Trust matters.
UX detail that wins awards

Skip the upload+paste form for first-time visitors. Show a landing screen with: "Try DocSmart with one of our sample CVs โ†’" + three big buttons. Lets judges test the app instantly without typing. Frictionless demo = memorable demo.

8
Demo day โ€” make them feel it
2 hours rehearsal

๐ŸŽฌ Your 5-minute demo flow

  • 00:00 โ€” 00:30 ยท The pain. "Everyone in this room has been ghosted by a recruiter. Often, the reason isn't your skill โ€” it's that your CV didn't pass the keyword filter." Make eye contact. People will nod.
  • 00:30 โ€” 01:00 ยท The team. Quick intros โ€” but mention that you used your OWN CVs as test data. Builds trust.
  • 01:00 โ€” 02:00 ยท The live demo. Click "Try a sample CV". Paste a real Ghana cloud engineer job. Watch the score appear, skills get highlighted, suggestions populate. This is your headline moment.
  • 02:00 โ€” 03:00 ยท A second demo โ€” judge's CV (optional!). If a judge consents, run their CV through the app live. "Here's where YOU could improve." Bold move. Massive memorability.
  • 03:00 โ€” 04:00 ยท The architecture. Show your diagram. "Textract reads the doc, Comprehend extracts entities, our matching engine compares to the job. EC2 hosts Streamlit, all under free tier."
  • 04:00 โ€” 05:00 ยท Who uses this. "Every job seeker in Ghana. Every bootcamp cohort. Career services at universities. We've built v1 โ€” v2 would add cover letter generation and salary suggestions." Vision sells.
The killer move

After the demo, share the live URL in the cohort chat. "Try it with your own CV right now โ€” we'll wait." 20 people will try it in 2 minutes. Word will spread. You'll likely win People's Choice this way alone.

๐Ÿ†
The 5 awards
๐ŸŽจ
Most Polished

Looks like a real product. Beautiful score circle, animated chips, professional fonts, "feels like a $20/month tool".

๐Ÿ’ก
Most Innovative

The smartest taxonomy. Or AI-generated improvement suggestions (using Bedrock). Or PDF report generation. Something nobody else thought of.

๐ŸŽค
Best Demo

The team that ran a judge's CV through the app. Or the team that demoed with FIRE on the live narration. Pure showmanship.

๐Ÿ“š
Best Documentation

A README so good it could be a Medium article. Architecture diagram, setup steps, lessons learned, future roadmap.

โค๏ธ
People's Choice

The app the cohort genuinely uses on their own CVs after demo day. The clearest signal โ€” usage doesn't lie.

๐Ÿ“„

You're solving your own problem.

Every line of code you write here is dogfooded by your own team. By demo day, you'll have a tool you genuinely use yourselves โ€” and that's the most powerful signal in startup-land.

Build it. Run your own CV through it. Then watch the cohort do the same.