RecutCV
A stateless AI service that turns a candidate profile and a specific job advert into a resume tailored to the conventions of the target country. Its defining constraint is truthfulness: the model may select, reorder, rephrase and omit, but it may never introduce a number, employer, technology or date the source document does not contain — and that rule is enforced in code, not only in the prompt. Currently a work-in-progress MVP, not yet deployed.
My Role & Activities
- Product architecture and truthfulness-first design
- Full-stack development (Angular 22 + NestJS 11)
- Dual-channel document extraction (pdf.js text layer + native model PDF reading)
- Hidden-content detection from the divergence between both channels
- Numeric grounding check of the output against the source text layer
- Prompt-injection posture — CV and job advert handled as data, never instructions
- Central LLM service with retry, timeout and model fallback chain
- Market rulesets as content (CZ + US), market and output language as independent axes
- Resume templates in Angular with an ATS-safe single-column variant
- PDF rendering via Angular SSR + Puppeteer, preview/export parity by construction
- Automated ATS round-trip verification of the rendered text layer
Technologies
A TypeScript-based framework for building scalable web applications.
A strongly typed language built on JavaScript with better tooling and maintainability.
Utility-first CSS framework for building custom interfaces quickly.
Progressive Node.js framework for scalable backend services.
JavaScript runtime for backend services, tooling, and automation.
Google's multimodal AI platform for building AI-assisted experiences.
Headless Chrome automation, used here to render server-side HTML into PDF.
Mozilla's PDF engine, used to extract a document's text layer deterministically.
Resource-oriented HTTP API style commonly used for application integration.
Architecture and delivery context
Problem
AI resume tools optimise for keyword coverage, and the fastest way to score well on that metric is to embellish. That produces documents a candidate cannot defend in an interview, and it is the reason employers distrust AI-written applications. The interesting engineering problem is not generating a resume — it is generating one that provably says nothing the source material does not support.
Approach
RecutCV is built around a single non-negotiable rule: every claim in the output must trace back to a fact in the input. The model is allowed to select, reorder, rephrase and omit; it is not allowed to invent. Because numbers are the most dangerous hallucination and the least visible to a reader, they are verified by code rather than trusted from the prompt — extracted from the generated prose and matched against the source document, with anything unmatched reported back to the user instead of silently shipped.
Reading the document
An uploaded CV is read through two independent channels. A deterministic pdf.js pass extracts the text layer; separately, the model reads the PDF natively so it can follow the typesetting of two-column layouts that flatten into nonsense as plain text. The divergence between the two channels is itself the signal: text present in the file but invisible on the page is how keyword-stuffing attacks are hidden, and it is reported rather than ignored. The composer writes from the visual transcription, but the number check always runs against the deterministic text layer — a model's output cannot be the reference a truthfulness check is measured against.
Market conventions
Target market and output language are independent axes. A Czech-language CV for the US market follows US resume conventions — no photo, no date of birth — while the section headings come from the market ruleset rather than being hard-coded into the template, so the document's language never leaks from the UI's.
Legitimate ATS only
The PDF's text layer is the interface an applicant tracking system actually reads, so it is treated as the product's API and verified by an automated round-trip: render to PDF, read the text back, assert the structure survived. There are no hidden tricks — no white text, no keyword stuffing, no invisible divs. They are detectable, they are penalised, and they contradict the one thing the product promises.
Stack and architecture
Angular 22 (standalone, signals, zoneless) with Tailwind v4 on the frontend; NestJS 11 on the backend, stateless with no database. Every LLM call goes through one central service — cost tracking, provider swap, retry and fallback chain in one place — and structured responses are narrowed by runtime guards, because a response schema is a request to the model, not a guarantee. The resume templates live in Angular and the PDF is produced by rendering the same components through Angular SSR into Puppeteer, so the on-screen preview and the downloaded file cannot drift apart.
Privacy
A CV is personal data, so the design assumes it: a no-training model tier, no personal data in logs, error messages or test fixtures, and both the CV and the advert treated as data inside the prompt rather than as instructions.
Status
Work in progress. The pipeline runs end to end — upload (PDF, DOCX, Markdown, plain text) through extraction, composition and rendering to a finished PDF across four templates, one of them single-column ATS-safe. Accounts, a persistent master profile and the full claim-tracing guard are still ahead.