IvyCV — Founder · Case study
An AI CV platform, built end-to-end. Twice.
After four years designing data-heavy SaaS for other people's roadmaps, I wanted the whole loop: research, strategy, interface — and the code that ships it. IvyCV is that bet, built across two product generations and live in production at ivycv.com.
Why a CV platform
CV tools split into two camps: template editors that leave all the thinking to you, and "AI magic" buttons that rewrite your experience into someone you wouldn't recognise. Tailoring a CV to a real job listing is neither — it's a structured reasoning problem: understand the role, align it with what the candidate has actually done, surface the gaps, and typeset the result so both recruiters and ATS parsers can read it.
That framing — structure over magic — became the product thesis, and it shaped every design and engineering decision that followed.
Generation one — CVD
The first build validated the core loop on a pragmatic stack: Next.js, Supabase, Stripe and the Claude API. A five-step pipeline — upload, interview, tailor, preview, download — took users from a raw document to a tailored CV, with real pricing live behind Stripe.
CVD worked — and taught the lesson that defined the rebuild: single-shot LLM calls don't earn trust. A black box in the middle of your own product can't be debugged, only guessed at.
Generation two — IvyCV
IvyCV is the rebuild around that lesson. Every meaningful flow is built from small, named stages with explicit input and output contracts — a rule the codebase enforces, not a slideware diagram. Tailoring a CV runs as a pipeline: extract the job listing → plan the adjustment → draft header, summary, skills and bullets → a final anti-AI-voice pass that detects model-sounding phrasing and rewrites it in the candidate's register. A feature exposes one endpoint, but internally every stage can be inspected on its own when something looks off. No black boxes, by architecture.
Models are routed per stage in two tiers — Gemini on Vertex AI as primary with Anthropic Claude as a typed fallback chain — and every AI call lands in a usage ledger with its stage, provider, tokens and latency. When generation misbehaves in production, the question is never "what did the AI do?" — it's "which stage, which call, which contract?"
- The journey: CV upload → AI parsing → interview → role targeting → template → generate → review → export — one continuous flow, capped at five clicks on the happy path.
- Anonymous-first: the whole journey works before creating an account (bot-gated by Turnstile); signing up later merges the anonymous work cleanly instead of losing it.
- The visual system: palette, typography, components and micro-interactions built in Tailwind + shadcn/ui; same system from marketing page to editor.
- The business: three subscription tiers on Stripe, priced in three currencies (USD / EUR / PLN), metered by generation credits.
The vault — a career graph, not a form
The heart of the product is the vault: the user's whole career stored as a skill graph — skills linked to the experience bullets that prove them — instead of a flat form. Each tailored CV aligns that graph against a specific listing, and the interview only asks about what's genuinely missing, in descending order of value for that role.
The vault also keeps negative knowledge — things the user has confirmed they don't have or don't want — so the system never re-asks and never silently invents. The whole loop ships behind 18 named acceptance gates, each an executable test: a requirement the vault already covers never triggers a discovery question, identical answers submitted twice land exactly once, and no question or generated line is ever blind to dates.
Design principles
- Align and ask — never grade. The system aligns your experience with the listing and asks about gaps. It never scores you, labels you, or shames you. People polishing a CV are often at a vulnerable moment; the product respects that.
- Sound like the candidate, not the model. A dedicated pipeline stage hunts down AI-voice phrasing and rewrites it before the user ever sees a draft.
- Show the work. Staged AI means the interface can show progress as meaningful steps instead of a spinner and a prayer.
- Defaults first, depth on demand. The same progressive-disclosure discipline I learned designing for Voluum's novices and experts.
Print is the product
Export isn't an afterthought bolted onto a web editor — it's a custom Typst-based PDF engine with ten typeset templates, from strict single-column to two-column and compact layouts. Every template carries a typed ATS tier (strict / balanced / visual) so users trade visual character against parser-safety knowingly, and a page-fit solver keeps real careers on real pages instead of orphaning a section header onto page three.
Built bilingual
IvyCV generates in Polish and English as equals, not English with a translation layer. A language-parity gate ties output language to the listing's language, per-stage guards catch an English fallback leaking into a Polish summary (and vice versa), and the database speaks Polish too — down to Polish-aware full-text search.
Shipping solo, with discipline
Solo doesn't mean casual. Every merge to main runs a verify chain — secret scan, four custom audits (dead code, runtime contracts, app state, fault visibility), typecheck and the full test suite — then deploys straight to production behind health and deep-health gates. Every change lands with a numbered dev-changelog entry and a changeset; CI blocks the PR otherwise. I work AI-natively — orchestrating coding agents daily — which is less about speed and more about process design: defining stages, contracts and review gates so quality survives the pace.
What this proves
The same person who runs the user interviews writes the production code. For a product designer, that closes the most expensive gap in the process — between what gets designed and what actually ships. It's the way I want to work on any team: end-to-end, evidence-driven, and accountable for the outcome, not the handoff.