About this project
Why it is built this way
KarirKalyan tracks job applications. It is also where I settled four questions before writing any of it. Each one had an easier answer than the one I took, so here is what the easier answer would have cost.
01
Why Rails, when I write TypeScript
My working life has been JavaScript. Tokyo runs on Rails, and you learn less about a framework's conventions by reading them than by shipping something inside them. So the API is Rails 8 — API-only, Devise and devise-jwt for auth — while the frontend stayed the Next.js I already knew. The unfamiliar half of the stack is the half I set out to learn, and it is the half with the tests.
02
Why a plain object, not a state-machine gem
ApplicationFSMis a plain Ruby object wrapping a table of legal transitions. A gem would have given the same guarantees and put a DSL between me and them. Thirteen states fit in one readable array — including the revival edges, where ghosted, rejected and withdrawn each return to applied, because real job hunts do that. Transitions run through a service object rather than a model callback, so every status change in the system has a call site you can grep for.03
Why Solid Queue, not Sidekiq and Redis
One job needs to run once a day. Sidekiq would have meant a Redis instance and a worker process — two more things to deploy, monitor and pay for, in service of a single cron. Solid Queue keeps the queue in the Postgres database that already exists, and its workers run inside the Puma process. The deployed system is two services and one database, which is the whole argument.
04
Why resumes live in Postgres
Resumes and cover letters are stored as
bytea, capped at one megabyte, and served through dedicated download endpoints that keep them out of the ordinary JSON. Object storage is the right answer at scale and the wrong one here: a bucket, a set of credentials, and a signed-URL dance, for files that are small and few. Storing them in the row means the file and the record are backed up together — worth more, at this size, than a ceiling I will not reach.
See for yourself
The demo account is seeded with twelve Tokyo tech applications spread across the pipeline. The source is public, and the API documents itself.