About the project
A side project I built entirely on my own — from the idea and the data model to a working online service. The goal was to make the job hunt organized and to automate the part of it that is normally done by hand.
How it works
You paste a link to a posting and the system collects the title, company, salary, location and requirements itself. The vacancy becomes a card on a kanban board whose stages you configure yourself.
- Interesting → Applied → Recruiter replied → Interview → Offer
- Old vacancies can be archived and brought back when needed
- Statistics: applications sent, replies received, interviews held, offers landed
The AI assistant
AI here is not a chat window — it is a tool bound to one specific vacancy.
- Skills analysis
- Compares your CV against the posting: what matches, what is missing, and which requirements your experience already covers.
- Cover letter
- Generates a letter for that specific vacancy in a chosen tone. You can edit the text and ask for a new version that takes your edits into account.
- Tailored CV
- Produces a version of your CV for the posting, making relevant experience more prominent, scores it against ATS expectations, and exports to Word.
- Interview prep
- Generates likely questions from the posting and your background. Notes you write after an interview are stored and feed into later preparation.
Technical decisions
The key technologies were chosen for specific product problems, not out of habit.
- PostgreSQL + pgvector
- For the system to understand that “REST APIs” in a CV and “REST API design” in a posting mean the same thing, text is turned into vector representations. Instead of a separate vector database (Pinecone, Weaviate) I keep the vectors next to the main data: one database, one backup, less infrastructure to run.
- Redis
- Generating a tailored CV takes 10–15 seconds and costs tokens. Results are cached under a hash of their inputs, so an identical repeat request returns instantly — and the moment the CV or the posting changes, the hash changes too, so the cache never needs clearing by hand.
- Spring AI
- Claude handles the heavy text work, OpenAI produces the embeddings. A single interface means a model can be swapped for a cheaper or better one without rewriting the application logic.
- Apache Tika
- CVs arrive as PDF and Word. Tika extracts text from both through one tool instead of two separate libraries.
- Testcontainers
- 372 automated tests. The integration tests run against a real PostgreSQL in Docker rather than an in-memory stand-in — slower, but it verifies how the system actually behaves.
Frontend
React 19 + TypeScript + Vite. Card dragging uses dnd-kit (react-beautiful-dnd is no longer maintained). TanStack Query caches server data and gives optimistic updates: a card moves to another column immediately, and if the server returns an error the change rolls back. The interface is built with shadcn/ui and Tailwind CSS.
Infrastructure
Backend on Railway, frontend on Vercel, PostgreSQL on Neon, Redis on Upstash. New versions deploy automatically on push.