Skip to content

Šta za ručak?

Java · Spring Boot · Next.js · Postgres

A Serbian recipe site. You can search in Latin or Cyrillic, with or without diacritics, and filter recipes for Orthodox fasting days.

Live site Source is private.

Why I built it

When I lived at home, my mom asked me "Šta za ručak?" every day. It means "What's for lunch?". That's where the name comes from.

I also wanted a real site to work on, with the parts most backends have: accounts, sessions, search, photo uploads and moderation.

What it runs on

Caddy is the reverse proxy. It sends /api to the API and everything else to Next.js, which renders the pages.

The API is Java 25 and Spring Boot. It talks to Postgres with plain SQL through JdbcClient, without an ORM, because the SQL does most of the work. Saving a recipe is a single statement, and a trigger works out its fasting level from the ingredients.

Passwords are hashed with Argon2id. A session is a row in Postgres and the cookie only holds its id, so logging out deletes the session. Rate limits are counted in Postgres too, so a restart doesn't reset them. Uploaded photos are checked to be JPEGs and their EXIF data is removed, because phone photos carry GPS coordinates.

The ingredient parser

Recipes are pasted in as plain text. The parser turns a line like 2 kašike ulja into a quantity, a unit and an ingredient. It understands 1/2, 1,5, ½, pola and ranges like 2-3.

Quantities are stored as fractions, so changing the number of servings keeps ½ as ½. Units carry all three Serbian plural forms, so 2 kašike becomes 5 kašika when you scale up.

A line the parser can't read keeps its text and goes on a list for me to look at. When I add the missing word, every recipe that used it is parsed again, including old ones.