Project 2 of ~34

πŸŽ“ Interview Ace β€” Architecture

Technical specification for Interview Ace β€” daily AI-powered interview practice via Telegram/email, with job posting scrapers and personalized feedback.

Telegram Bot Resume Parsing Job Scraping Mac-native

πŸ—οΈ Architecture Overview

Interview Ace has three main backend systems: (1) a Telegram bot that handles user interactions, (2) a scraper service that collects job postings, and (3) an AI pipeline that generates questions and feedback. All run on the Mac Mini or Deno Deploy.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ USER INTERFACE β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Telegram Bot β”‚ β”‚ Email Flow β”‚ β”‚ Web UI β”‚ β”‚ β”‚ β”‚ (Primary) β”‚ β”‚ (Fallback) β”‚ β”‚Dashboardβ”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ APPLICATION CORE (Deno) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ User Mgmt β”‚ β”‚Question Gen β”‚ β”‚ Feedback Eng β”‚ β”‚ β”‚ β”‚ (Supabase) β”‚ β”‚ AI Pipeline β”‚ β”‚ AI Pipeline β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Daily Queueβ”‚ β”‚ Resume Parseβ”‚ β”‚ Score Trackerβ”‚ β”‚ β”‚ β”‚ (QStash) β”‚ β”‚ (Ollama) β”‚ β”‚ (Redis) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β–Ό β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ SCRAPER SERVICE β”‚ β”‚ DATA STORES β”‚ β”‚ (Playwright/Cheerioβ”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ on Mac Mini) β”‚ β”‚ β”‚ Supabase (Postgres) β”‚ β”‚ β”‚ │◄────│ β”‚ Users, Questions, β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Answers, Feedback, β”‚ β”‚ β”‚ β”‚ LinkedIn API β”‚ β”‚ β”‚ β”‚ Job Postings Cache β”‚ β”‚ β”‚ β”‚ Indeed API β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ Glassdoor β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Company Pages β”‚ β”‚ β”‚ β”‚ Upstash Redis β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ Sessions, Queues β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Cloudflare R2 β”‚ β”‚ β”‚ β”‚ Resume PDF storage β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Tech Stack

Telegram Bot + Backend

ComponentTechnologyWhy
RuntimeDeno 2TypeScript-first, secure, runs on Mac Mini. All backend logic in one codebase.
Telegram BotDeno Telegram Bot APILightweight, stateless bot. Handles /start, /question, /answer, /dashboard commands.
EmailResendEmail delivery for users who prefer email over Telegram. Same Deno backend.
DatabaseSupabase (PostgreSQL)User data, question bank, answer history, feedback storage.
QueueUpstash QStashCron jobs for daily question delivery, weekly re-scrape, feedback reminder.
CacheUpstash RedisDaily question queue per user, streak tracking, rate limiting.
Resume StorageCloudflare R2Encrypted PDF storage for uploaded resumes.

Scraping Stack

ComponentTechnologyWhy
Headless BrowserPlaywright (Chromium)Renders JavaScript-heavy job sites (LinkedIn, Glassdoor). Runs on Mac Mini.
HTML ParsingCheerio (Deno)Fast HTML parsing for simpler sites (Indeed, company career pages).
LinkedInLinkedIn API (Scout vs. RapidAPI)Official API for job postings. Fall back to scraping if quota exhausted.
IndeedIndeed Publisher APILimited free access for job aggregation.
GlassdoorScraping (respectful)Interview review data. Only what is publicly available. Rate limited.
ProxyBright Data or Oxylabs (optional)If LinkedIn blocks scraping. Paid, only if needed at scale.

AI Stack β€” Local First

πŸ€– AI Philosophy
  • Draft questions: Ollama (Mistral 7B) on Mac Mini β€” fast, free, good enough for question generation
  • Feedback quality: MiniMax M2.1 API β€” higher quality for nuanced interview feedback
  • Resume parsing: Ollama (Llama 3.1 8B) β€” extracts structured data from PDF resume
  • Voice transcription: Whisper API or local Whisper (via Ollama if available)

Frontend

ComponentTechnologyWhy
DashboardSvelteKitProgress dashboard, profile setup, billing. Minimal UI β€” Telegram is the main interface.
Telegram Mini AppTelegram WebAppRich interactive UI inside Telegram (question display, voice recording). Embedded SvelteKit.

πŸ—„οΈ Data Model

users
iduuidPrimary key
telegram_chat_idvarchar(50)Telegram unique ID, indexed
emailvarchar(255)Login email
user_profiles
user_iduuid (FK)Ref users
target_rolesvarchar[]Array of role titles
target_companiesvarchar[]Array of company names (max 5)
industryvarchar(100)Primary industry
seniorityenum('entry','mid','senior','lead','exec')
resume_urlvarchar(500)R2 URL to stored PDF
resume_parsed_jsonjsonbStructured resume data (skills, exp, edu)
preferred_delivery_timetimeDaily question delivery time
delivery_channelenum('telegram','email','both')
streak_daysintegerCurrent streak
question_banks
iduuidPrimary key
industryvarchar(100)tech, finance, healthcare, consulting
question_typeenum('behavioral','technical','case','situational')
difficultyenum('easy','medium','hard')
question_texttextThe question itself
model_answertextIdeal response (AI-generated)
evaluation_criteriatextWhat to look for in answer
tagsvarchar[]Leadership, communication, etc.
job_postings
iduuidPrimary key
companyvarchar(255)
rolevarchar(255)
urlvarchar(500)Original posting URL
sourceenum('linkedin','indeed','glassdoor','company')
raw_texttextFull job description
skills_requiredvarchar[]Extracted skills
experience_yearsintegerRequired years
salary_rangevarchar(100)If available
interview_processtextKnown interview stages
scraped_attimestamp
last_updated_attimestampFor cache invalidation
daily_questions
iduuidPrimary key
user_iduuid (FK)Ref users
job_posting_iduuid (FK, nullable)Ref job_postings
question_bank_iduuid (FK, nullable)Ref question_banks
question_texttextThe generated question
question_typeenum('behavioral','technical','case')
scheduled_fortimestampWhen to deliver
deliveredboolean
answered_attimestamp
answer_texttextUser's answer
voice_transcriptiontextIf voice note
feedbacktextAI feedback
scoreinteger1–10
company_pipeline
iduuidPrimary key
user_iduuid (FK)Ref users
companyvarchar(255)
rolevarchar(255)
stageenum('applied','phone_screen','technical','behavioral','final','offer','rejected')
interview_datedateIf scheduled
notestext

πŸ”Œ API Design

REST API for dashboard, webhook endpoints for Telegram and scraping callbacks.

User Management

POST /auth/signup
Email + password signup, returns JWT
POST /auth/telegram/link
Link Telegram account. Body: {telegram_chat_id, verify_code}
GET /users/me/profile
Get current user's profile
PATCH /users/me/profile
Update profile (targets, delivery prefs)

Resume

POST /users/me/resume
Upload resume PDF. Stores in R2. Triggers async parsing.
GET /users/me/resume/parsed
Get parsed resume JSON (skills, experience, education)

Questions & Practice

POST /questions/answer
Submit answer to a question. Body: {question_id, answer_text, voice_base64?}. Returns async job ID.
GET /questions/:id/feedback
Get feedback for a completed question
GET /questions/today
Get today's question for current user

Company Pipeline

GET /pipeline
List all companies in user's pipeline
POST /pipeline
Add company to pipeline
PATCH /pipeline/:id
Update stage or interview date

Dashboard

GET /dashboard/summary
Overall progress: total answered, avg score, streak, weakest areas
GET /dashboard/report/:company
Prep report for a specific company

Webhooks (Internal)

POST /webhooks/telegram
Telegram bot webhook. Receives all Telegram events.
POST /webhooks/scraper/:company
Triggered by scraper when new job posting found.

πŸ•΅οΈ Scraping Pipeline

LinkedIn Scraping
Use RapidAPI LinkedIn Job Search API (~$30/mo) for reliable job data. Falls back to direct scraping with Playwright on Mac Mini if quota allows. Extract: title, company, description, skills, salary (if available), posted date.
Indeed Scraping
Cheerio parser on Indeed RSS feed + search pages. Rate limit: 1 request/minute per IP. Extract: title, company, description, salary range. No JS rendering needed.
Glassdoor Interview Data
Playwright on Mac Mini. Extract interview questions from company reviews (publicly available). This data is the differentiator β€” real questions real candidates were asked. Respect robots.txt.
Company Career Pages
For target companies (Apple, Stripe, etc.), Cheerio scrapes their careers page directly. Weekly check for new postings. Cache for 24hrs.
Scraper Schedule
Cron job (Upstash QStash): Weekly full re-scrape of all target companies. Daily delta check for new postings. Mac Mini can run scraper scripts via deno task scrape nightly.

πŸ€– AI Pipeline

Question Generation
Daily at the user's delivery time, QStash triggers the question generation job. Process: (1) Load user's profile + resume parsed data + latest job posting for target company. (2) Use Ollama Mistral 7B on Mac Mini to generate a question draft tailored to the intersection of user's background and job requirements. (3) If Mac Mini is busy/slow, fall back to MiniMax M2.1 API. (4) Store in daily_questions table. (5) Deliver via Telegram.
Feedback Generation
When user submits answer, QStash triggers feedback job. Process: (1) Load question, user's answer, resume parsed data, and evaluation criteria. (2) Send to MiniMax M2.1 API for detailed feedback. Prompt includes: the question, user's answer, model answer, resume highlights relevant to the question. (3) Feedback includes: score (1–10), strengths, specific improvements, tip for next time. (4) Store in daily_questions.feedback.
Resume Parsing
When user uploads resume PDF: (1) Store in R2. (2) Extract text (pdf-parse in Deno). (3) Send to Ollama Llama 3.1 8B on Mac Mini to extract structured JSON: skills[], experience[{title, company, duration}], education[], notable_projects[]. (4) Store in user_profiles.resume_parsed_json.
Voice Transcription
Telegram voice notes arrive as .ogg files. Use Whisper API (OpenAI) or local Whisper model via Ollama to transcribe. Then route through normal feedback pipeline.

πŸš€ Deployment

ComponentWhereNotes
Telegram Bot + APIDeno Deploy (free) or Mac MiniPolling or webhook to Deno Deploy
DashboardCloudflare PagesMinimal UI, mostly links to Telegram
ScraperMac Mini (nightly cron)Playwright + Cheerio scripts
AI (local)Mac Mini OllamaMistral 7B for question generation
AI (cloud)MiniMax APIHigh-quality feedback generation
Queue / CronUpstash QStashDaily delivery triggers, scraper schedules
DatabaseSupabaseFree tier sufficient for <10K users

Mac Mini Dev Setup

# Mac Mini Setup for Interview Ace brew install deno brew install ollama ollama pull mistral:7b ollama pull llama3.1:8b # Install Playwright for scraping pip install playwright playwright install chromium # Start everything ollama serve # :11434 deno run -A src/bot.ts # Telegram bot deno task scrape # Nightly scraper job deno task dev # Dashboard dev server

← Requirements  |  All Projects  |  Presentation β†’