MyApplio
Project Case Study
MyApplio
An AI-assisted job search workspace that connects resumes, applications, and interviews in one pipeline. Next.js 16 and Supabase, with Gemini-powered resume import, job discovery, and cover letter drafting, plus a Chrome extension that captures postings in one click.
View Live Project →Overview
MyApplio is an AI-assisted job search workspace. The positioning is stated on the landing page as "Resume to offer · AI assisted", and the promise underneath it is "Resumes, applications, interviews. Nothing falls through."
Most job seekers run their search across a spreadsheet, a resume file, an email inbox, and a browser full of tabs. Each tool holds one stage and knows nothing about the others. MyApplio's premise is that the stages are the product: a captured posting becomes an application, an application pulls from a resume, a resume gets tailored per role, and an interview inherits the context of both.
The Problem
Postings disappear before they are recorded, or get pasted into a spreadsheet without their details
Resumes fork into a dozen near-identical files with no source of truth
Cover letters restart from a blank page for every application
Deadlines and follow-ups depend on memory
Nothing connects a stalled application back to the material that produced it
Information Architecture
The dashboard is organized around the entities of a real search rather than a single flat list:
Capture — ai-job-search for discovery, plus the Chrome extension for one-click clipping
Pipeline — applications, companies, roles, people, events, notes, links
Material — resume, cv, cover-letter, with match scoring a resume against a posting
Preparation — interview-prep, review, ready, goals
Public surface — resume-directory, resume-search, and shareable public resume pages
Technical Implementation
Stack
| Area | Implementation | Notes |
|---|---|---|
| Framework | Next.js 16.2.6 + React 19.2.3 | App Router, React Compiler enabled |
| Data and auth | Supabase (Postgres, Auth, SSR) | 193 migrations; RLS throughout, including read-only demo user |
| Server state | TanStack React Query | Cache and invalidation for dashboard surfaces |
| AI | Google Gemini 2.5 Flash / Flash-Lite | Called directly over REST, no SDK dependency |
| Rate limiting | Upstash Redis + Ratelimit | Protects AI endpoints from abuse |
| Billing | Polar | Raw HTTP; webhooks verified with standardwebhooks |
| Documents | pdfjs-dist, jsPDF, html2canvas, ExcelJS | PDF import and PDF/spreadsheet export |
| Notifications | web-push (VAPID) + Supabase pg_cron | Per-user timezone scheduling, device failure backoff |
Two model tiers, chosen per task
Every AI call is a direct fetch to the Gemini REST endpoint, and each site picks its tier deliberately rather than defaulting to the strongest model:
`gemini-2.5-flash` for open-ended generation — job discovery, cover letter drafting, resume generation, interview feedback
`gemini-2.5-flash-lite` for structured, high-volume extraction — PDF import, notes import, job matching, resume coaching, skills sync
Both are environment-overridable with hardcoded fallbacks, so a model swap is a config change rather than a code change.
Resume PDF import as a two-pass pipeline
Importing a resume is the highest-friction moment in the product, so it gets the most engineering. pdfjs-dist extracts text client-relevant content, then Gemini runs two passes — a draft extraction followed by a repair pass that reconciles the draft against the source. Input text is capped to bound cost and runtime; large files land in the 20–40 second range.
AI credits as a first-class system
Usage is metered rather than trusted. Every call records its provider and token usage metadata, credits are granted on signup and by subscription, and expiry runs on a nightly pg_cron sweep with lazy expiry on the settings page as a backstop.
Scheduling without a cron vendor
There is no vercel.json and no cron library. Jobs are scheduled in Supabase pg_cron + pg_net, checked into the repo as SQL scripts and authenticated with an x-cron-secret header. The daily-events push job was deliberately backed off to hourly under database IO pressure, with a comment warning against dropping below 30 minutes — an operational constraint recorded where the next person will read it.
Security posture
HSTS in production, X-Frame-Options: DENY, nosniff, COOP, and a tight Permissions-Policy are set in next.config.ts. CSP is issued per-request from middleware with a fresh nonce, and violations are collected at a dedicated report endpoint.
The Chrome Extension
MyApplio Job Clipper is a Manifest V3 extension with a service worker and a side panel. It scrapes LinkedIn, Indeed, Glassdoor, Workday and others into MyApplio as draft applications — the extraction logic alone is roughly 82 KB of site-specific code, because every board structures its postings differently. Drafts, not finished records: capture should be one click and cost the user no decisions.
What This Case Study Demonstrates
Designing a multi-entity product where the connections between stages are the value
Running production AI economically by matching model tier to task, metering every call, and capping inputs
Building on Supabase with serious RLS, 193 migrations, and database-native scheduling
Shipping a browser extension and a web app as one coherent product
Making security and cost boundaries explicit in code rather than in a runbook
Live: https://myapplio.com/
Role: Solo delivery (product → schema/RLS → AI pipeline → billing → extension → SEO)