Job Application Tracker
A web app that gives job seekers one clear view of every application and where it stands.
The problem
A job search means dozens of applications at different stages. Tracked in a spreadsheet, it quickly goes out of date and hides what needs attention next.
What I built
- A four-stage pipeline (Applied, Online assessment, Interview, Offer or rejected) that mirrors how hiring actually works.
- Private accounts: every user signs in and only sees their own data, enforced by JWT authentication across a 40-endpoint REST API.
- A data model built to grow: normalized PostgreSQL schema, numbered SQL migrations that moved existing data without breaking the old API, and pooled connections.
- Shipped, not just coded: containerized with Docker Compose, deployed through a GitHub Actions CI/CD pipeline and live online.
- Full-stack development
- React
- FastAPI
- REST API
- JWT authentication
- PostgreSQL
- Data modeling
- Docker
- CI/CD
- Cloud deployment
Live demo
Double-Entry Ledger API
A ledger API that records every movement of money so every balance stays traceable and is never wrong.
The problem
Payment apps fail in quiet ways: a lost response plus a retry charges a customer twice, and two transfers at the same moment can overdraw an account. I wanted to build the engine that prevents it.
What I built
- Double-entry rules enforced twice: in Java for clear 422 errors, and in PostgreSQL with constraints and deferred triggers so debits always equal credits.
- Append-only history: mistakes are fixed with a reversing entry, once, never by editing the past.
- Idempotency keys so a retried payment posts exactly once: 8 simultaneous requests with one key create a single entry.
- Row locks taken in id order to stop overdrafts and deadlocks, proven by 52 Testcontainers tests that run in GitHub Actions on every push.
- Java
- Spring Boot
- PostgreSQL
- REST API
- Transactions
- Idempotency
- Concurrency control
- Integration testing
- Testcontainers
- CI/CD
GitHub
RAG Document Q&A
An app that answers questions from your own PDFs and shows the passages it used.
The problem
A language model on its own answers from memory and can make things up. Retrieval-augmented generation (RAG) grounds the answer in real documents. I first built every step from scratch to understand what the tools do, then rebuilt the system on those tools.
What I built
- A Streamlit app: upload PDFs, ask a question and get an answer with its sources and their scores.
- A retrieve, augment, generate pipeline: LlamaIndex chunking, MiniLM embeddings, a Chroma index that persists across restarts and Claude through LangChain.
- An extractive fallback answer when no LLM API key is set, so the app stays usable.
- The first version, built from scratch: hashing-based embeddings and top-k cosine-similarity search, with no external libraries.
- Generative AI
- Retrieval-augmented generation
- Embeddings
- Vector search
- Cosine similarity
- Information retrieval
- LlamaIndex
- LangChain
- Chroma
- Streamlit
- Python
GitHub
Grade Manager
A command-line tool that computes a student's GPA on Concordia's 4.3 scale.
The problem
Working out a GPA by hand, across letter grades and different credit weights, is slow and easy to get wrong.
What I built
- Credit-weighted GPA, earned credits and highest grade on Concordia's 4.3 scale.
- Custom checked exceptions that reject invalid grades and duplicate courses.
- Courses written to MySQL through JDBC (add, update, delete).
- Object-oriented design with JUnit tests on the core logic, built with Maven.
- Java
- Object-oriented design
- Data validation
- MySQL
- JDBC
- Unit testing
- JUnit
- Maven
GitHub