Skip to content
TARUN S / PORTFOLIOTAP OR PRESS ANY KEY TO SKIP

Developer

000

Peppy Pick

TYPE
AI career platform
STACK
22 COMPONENTS
STATUS
SOURCE AVAILABLE
FEATURED
YES

01 / OVERVIEW

A career platform that parses your resume, LinkedIn, and GitHub, scores your portfolio site, and then runs you through AI-generated mock interviews built from either a job title or a pasted job description.

Peppy Pick is a full-scale career-development backend I built end-to-end: a modular Flask service organised into ten+ Blueprints, backed by Firebase Firestore, that turns raw career artifacts — a PDF resume, a LinkedIn URL, a GitHub username, a portfolio website, a pasted job description — into structured, scored, AI-generated feedback. Every long-running piece of work (resume parsing, LinkedIn/GitHub/portfolio analysis) runs through a custom-built TaskManager that spins up background threads, persists progress to Firestore, and exposes polling endpoints so the client never blocks on a slow AI call. On top of that sits a two-mode AI interview simulator (role-based and job-description-based) that mixes a curated question bank with dynamic OpenAI Assistant/GPT-generated follow-ups, automatically rewrites 'write me the code for X' questions into video-interview-appropriate conceptual questions, and tracks session history, skills coverage, and a candidate-to-JD compatibility score. The platform layers in three independent authentication paths (email/password, phone OTP over SMS/WhatsApp, and OAuth SSO for Google/LinkedIn/GitHub), a weighted profile-completion and XP/leveling gamification system with milestone emails, a lightweight community forum (posts, likes, threaded replies, trending/search), and a resume-vs-job-description match scorer that calls the Claude API directly over HTTP (bypassing the official SDK to dodge dependency conflicts) with a fully deterministic keyword-based fallback whenever the AI call fails. The whole thing is documented with a 40+ endpoint Postman collection and ships with defensive Firestore query patterns (in-memory fallback filtering) to avoid composite-index requirements in production.

02/ STACK & ARCHITECTURE

FRONTEND

  • React
  • JavaScript
  • REST/JSON API consumer

BACKEND

  • Python
  • Flask
  • Flask-Blueprints
  • Firebase Admin SDK
  • Firebase Firestore
  • Anthropic Claude API (HTTP)
  • OpenAI GPT / Assistants API
  • Threading / custom TaskManager
  • JWT
  • OAuth 2.0 (Google, LinkedIn, GitHub)
  • Twilio SMS
  • MSG91
  • WhatsApp Business API
  • SMTP / smtplib
  • BeautifulSoup / web scraping
  • PyPDF2
  • Werkzeug security
  • Gunicorn
  • Postman

03 / WHAT WAS ACTUALLY HARD

  1. 01

    Custom async TaskManager for every heavy operation

    Built a TaskManager service from scratch that wraps any long-running job (resume parsing, LinkedIn/GitHub/portfolio analysis) in a daemon thread, writes a task document (status, progress, timestamps, error_message, results) to Firestore the moment it starts, and updates it through pending → running → completed/failed. Every analysis endpoint returns a task_id instantly and the client polls a /status/<user_id> endpoint, so a 30+ second Claude/GitHub/scraping call never blocks the request thread. Includes task history, per-type stats (success rate, average duration), cancellation, and a scheduled cleanup routine for tasks older than N days.

  2. 02

    Resume ingestion pipeline: PDF → structured JSON → interview questions → JD match score

    Uploads are validated (type, 10MB size cap, hash-deduped), text is extracted from PDF via PyPDF2 with a multi-strategy fallback for stubborn files, and the raw text is sent to Claude (via a hand-rolled HTTP client, model claude-3-sonnet) with a strict JSON schema to extract personal info, education, work experience, projects, certifications, and skills. A second Claude call verifies the document is actually a resume before processing continues. From that structured data the system independently generates five tailored interview questions (behavioral/technical/problem-solving mix) and, if a job description was supplied, a 0–100 match score with strengths/gaps — all with a fully deterministic non-AI fallback (keyword overlap + experience/education heuristics) so the feature degrades gracefully instead of failing.

  3. 03

    Two-mode AI interview simulator with video-interview-safe question rewriting

    Role-based mode draws from a 60+ question bank spanning Software Engineer up through CTO, matched by role/level/topic, and falls back to an OpenAI Assistants thread when no predefined question fits. JD-based mode extracts role/level/skills/technologies/industry from a pasted job description via GPT-3.5, scores every bank question for relevance (role, level, skill/technology overlap, industry, company type) and selects a diverse top-N set, generating new AI questions when the bank runs dry. Both modes run every candidate-facing question through a regex-based rewriter that converts 'write a function to…' / 'show me the code for…' into 'explain your approach to…', since this is a video interview with no code editor. Both modes implement the same ending logic (min/max question count, vague-answer and off-topic detection) and persist every Q&A turn to Firestore for later playback.

  4. 04

    Skills-coverage assessment & candidate–JD compatibility scoring

    After a JD-based interview, the system re-reads the full answer transcript and computes two independent numbers: a skills/technology coverage percentage (which required skills and technologies were actually mentioned in the candidate's answers) and a weighted compatibility score (role fit 30%, skills match 40%, experience-level match 20%, cultural-fit signal words 10%) that maps to a plain-English hiring recommendation.

  5. 05

    Three independent authentication systems, unified behind one X-User-ID contract

    Email/password with Werkzeug password hashing, forgot/reset-password tokens (SHA-256 hashed, 1-hour expiry) and change-password email notifications; phone auth with OTP delivered over Twilio SMS, MSG91, or WhatsApp Business API, 6-digit codes hashed with the phone number, rate-limited to one request/minute, max 3 verification attempts, auto-cleanup of expired codes; and OAuth SSO for LinkedIn and GitHub with CSRF-safe server-side state tokens (stored in Firestore with TTL) and full profile/repo/organisation ingestion on first login. All three converge on the same user document schema so every other feature (resume, interviews, community) only ever needs an X-User-ID header, a Bearer JWT, or a Firebase ID token.

  6. 06

    LinkedIn, GitHub, and portfolio-site analysis with Claude-scored feedback

    GitHub analysis pulls live data from the GitHub REST API (profile, up to 30 non-fork repos, languages, stars, orgs) and asks Claude to score profile completeness, repository quality, activity consistency, technical skills, and community engagement out of 100, with career-specific project recommendations. Portfolio analysis runs a full BeautifulSoup scrape (projects, work history, education, skills, testimonials, blog posts, SEO tags, responsive-design detection, CSS-framework fingerprinting, load time) and feeds a condensed summary to Claude for a six-factor weighted score (content, technical, design/UX, branding, career alignment, completeness). All three analyzers (LinkedIn, GitHub, portfolio) ship with hand-written deterministic fallback scorers so a Claude outage degrades to a rules-based grade instead of a 500.

  7. 07

    Weighted profile-completion engine with XP, levels, and milestone emails

    Profile completion is calculated as a precise weighted sum (name 10%, profession 10%, career choices 10%, college name 10%, college email 15%, GitHub link 15%, LinkedIn link 15%, resume upload 15%) recalculated on every relevant update. Crossing a milestone (10/20/30/40/55/70/85/100%) awards XP, recalculates level (100 XP/level), unlocks a badge, and — for the 55/85/100 milestones — triggers an HTML/plain-text celebration email via the SMTP email service.

  8. 08

    Community forum with likes, threaded replies, search, and a trending algorithm

    Posts support toggleable likes and threaded replies stored as nested maps for O(1) access, full author-only delete, keyword search across content and author name, and a trending endpoint that computes an engagement score (likes × 1 + replies × 2) over a configurable recent-days window — all written to avoid Firestore composite-index requirements by filtering/sorting in Python when a compound query would otherwise fail.

  9. 09

    Direct-HTTP Claude client to sidestep SDK/dependency conflicts

    Rather than depending on the official Anthropic Python SDK (which was conflicting with other pinned dependencies in the stack), I wrote a minimal ClaudeHTTPClient wrapping raw requests.post calls to the /v1/messages endpoint, matching the SDK's response shape (message.content[0].text) so the rest of the codebase — resume parsing, resume-to-JD matching, LinkedIn/GitHub/portfolio analysis — could be written against a familiar interface with zero SDK dependency risk.

  10. 10

    Firestore-index-safe query patterns throughout

    Nearly every list/query method (interview history, community posts, tasks, analyses) is written with a 'try the modern filtered+ordered query, fall back to fetching the collection and filtering/sorting in Python' pattern, specifically to avoid Firestore's composite-index requirement blocking production traffic the first time a new query shape is deployed — a defensive pattern applied consistently across ~10 different models/services.

  11. 11

    Full observability and documentation surface

    Ships with a 40+ endpoint POSTMAN.md covering every route with example bodies, pre/post-request scripts for chaining IDs across requests, and dedicated error/rate-limit/large-file test scenarios; a suite of live debug endpoints (/api/debug/interview-system, /api/debug/email-config, /api/debug/profile-completion/<id>, OTP debug info) that surface exact environment-variable and service-availability state in production without needing shell access; and structured logging to logs/app.log across every service.