EYThe LogEmre Yakut
← all entries
Simulation · Systems · Debugging

What can you cook with what you have — and a site that publishes itself

Mutfaksim tells you what comes out of whatever is in your fridge. Then moving its content to social media by hand felt absurd, so the site started publishing itself — along with three bugs.

tarif sitede yayımlandı kart üret görsel + metin Graph API iki ayrı yol Instagram gönderi site kendi kendini yayımlayabilir — ama bunu yaparken yalan söylememeliyarış durumu: yayın, Instagram’ın kendi görsel çekişini geçiyordu → görsel boş gidiyorduve bir hata, konuyu sonsuza kadar kilitliyordu. kuru çalıştırma aynı hikâyeyi iki kez saydı.

Mutfaksim started with a simple question: these are in the fridge, what comes out?

That is a different question from searching for a recipe. When you search, you know what you are making and you complete the ingredients. Here it is the reverse: ingredients fixed, outcome variable.

What is in it

  • Matching what you have — you enter ingredients and see what is possible and what is missing.
  • Scaling — taking a recipe for four up to seven is not a decimal multiplication: some ingredients scale linearly (flour, milk), some do not (salt, raising agents, cooking time).
  • A technique library — separate explanations and short clips for steps like searing, resting or marinating.
  • A private note — being able to write “leave it in the oven ten minutes longer” instead of rating a recipe out of five. People do not score recipes, they correct them.
a content bug I found

Five recipes salted the food but did not list salt in the ingredients. The sort of thing everyone assumes is “already there” while writing.

For a user this is the most infuriating kind of error: you take the list to the shop and discover something missing at home. I added an automatic check — every ingredient mentioned in the steps must appear in the list.

Then: let the site publish itself

Content is produced regularly and was being moved to social media by hand: take a screenshot, copy the text, open the app, paste. Five minutes each time, and a little more reluctance each time.

A classic automation candidate. It came with three bugs.

The first surprise: two paths, two permission names

The platform has two different integration paths, and which you have depends on your account type. More annoying: the permission names differ between them. The documentation does not say so clearly; you find out from the error message.

The fix was to support both: the system discovers which path is available and proceeds accordingly.

Bug 1: a race condition

The publishing flow is two steps: first you declare where the image lives, then you say “publish”. At the second step the platform fetches the image itself from the address you gave. And my code did not wait for that fetch.

1. render the card image and write it to the server
2. declare the address
3. immediately say "publish"
   ↑ the platform has not fetched the image yet → the post goes out empty

Sometimes it worked — if the image was cached or the network was fast. Sometimes it did not. The classic signature of an intermittent bug.

The fix: step two now polls the resource’s processing status and waits until it is ready. Ask the state rather than “wait and hope”. A blind delay is not a fix; it only makes the failure rarer.

Bug 2: a subject locked forever

To stop the same content being published twice there was a lock: before publishing, the subject is marked “processing”, and released when done.

The problem: it was not released on failure. When a publish failed, the subject stayed “processing” forever and was never published again. Silently.

the rule of lock design

A lock must be guaranteed to be released under every condition — on success, on error, and on process crash. The last is the hardest, because none of your code runs. The answer is to give the lock an expiry.

The lock is now released on the error path and also expires. Both are needed.

Bug 3: the dry run was lying

There was a dry-run mode showing what would happen before actually publishing. It listed the same item twice.

The cause: the dry run used its own code path. It gathered candidates with a different query and skipped deduplication. So what it showed was not what the real flow would do — which is worse than not having it, because I trusted it.

// wrong
if (dry) { computeCandidatesSeparately(); print(); return; }
realFlow();

// right
const plan = planRealFlow();        // the same code, always
if (dry) { print(plan); return; }   // only the final step is skipped
apply(plan);

And a rule: do not lie while publishing

The easiest mistake in automated publishing is the system believing it did something it did not.

A “post published” notification must not be sent until the platform has actually accepted it. The last step of the flow is recording the post identifier the platform returns. With no identifier, the publish did not happen — even if the request looked successful.

That is the same rule as the voice assistant verifying before saying “I turned the light off”.

Other small things in the same period

  • Turkish characters came out corrupted on the server while fine locally. The encoding setting differed between environments.
  • The profile picture became unrecognisable at 32 pixels. At small sizes what reads is not detail but silhouette.
  • A section heading had stopped being true after the text below it changed, and stayed wrong for months.
  • Eight flat links became three groups; sections that had never appeared in the menu surfaced.

The third is the most instructive. Forgetting the heading while updating the text is very easy, and nobody complains — the page just becomes a little less meaningful.

What I learned

Automation does not remove work; it changes the kind of work. Five minutes of manual copying went away; a race condition, a lock design and dry-run correctness arrived.

Worth it? Yes — but not because of time. The manual step was sometimes skipped; the automatic one is not. Automation’s real gain is not speed, it is consistency.

SimulationSystemsDebugging