Software engineer — backend & product

Bernard Odon

Brazil · RemoteGitHubLinkedIn
Runtime · api: prod-apps-01
ytlearndevelopment
not public yetcase study →
correndodevelopment
not public yetcase study →
foto3x4facildevelopment
not public yetcase study →
Probed every 30sFull status →
← All projects

Correndo

A running coach whose weekly prescriptions come from an LLM but are validated before an athlete ever sees them.

Go · PostgreSQL · LLM worker · React · Vite · PWA · 2026

Go API, PostgreSQL, worker · React/Vite PWA · 2026 — ongoing

Correndo is a personal training tool: it holds one athlete's run history, symptoms and adherence, and a worker generates that athlete's next week of training by calling an LLM. The interesting engineering problem isn't the LLM call — it's everything around it that makes a generated training plan safe to actually follow.

Problem

A running plan is a set of claims about what a body can safely do this week, based on what it did last week. Get it wrong — too much volume, too soon, after symptoms were logged — and the cost isn't a bad UI, it's an injury. An LLM is good at producing a plausible-looking week of training. It has no way to know whether that week is safe for this specific athlete's last month of adherence and symptom history, and it will confidently produce an unsafe plan that reads exactly like a safe one.

Constraints

  • Single athlete. The system is scoped to one ATLETA_ID, read from environment. No multi-tenant auth, no account system — building that would have used the time better spent on the actual hard problem: is a generated week trustworthy.
  • The LLM provider isn't fixed. Providers change pricing and quality over time, and locking to one raises real switching cost later.
  • No production posture yet. The API does not authenticate requests, and there is no tested backup or deploy pipeline. That's true today, not a claim about the finished system — see What broke.

Mechanism

invalid → retry, never writtenWorkerweekly tickContexthistory, symptoms, adherenceLLM portprovider behind interfaceValidatorschema + rulesPostgresprescription
One weekly-prescription run: context assembled from Postgres, sent through an LLM behind a port interface, checked by a validator, and only written back on success.

The worker doesn't hand raw history to the model and hope. It assembles a bounded context object — recent sessions, logged symptoms, adherence — calls the LLM through an adapter, and the response has to pass a validator before it touches the database. A response that fails validation is a retry, not a prescription. The athlete only ever sees a week that was assembled, checked, and persisted — never the raw model output.

Decisions

LLM access goes through a port, not a direct SDK call

Chose
An adapter interface the worker calls, with the concrete provider swapped in behind it.
Rejected
Calling a specific provider's SDK directly from the worker.
Cost
One more layer of indirection and a slightly more abstract worker for a system that, on day one, only had a single provider anyway.

Structured, validated output instead of trusting the model's free text

Chose
A schema the LLM's response must satisfy, checked before persistence — and a retry path when it doesn't.
Rejected
Storing the model's output directly, or validating loosely after the fact.
Cost
Prompts have to be written toward a schema the model can reliably fill, which is more constraining than free-form generation.

One athlete, not a multi-tenant product

Chose
A single `ATLETA_ID` read from environment, no account system.
Rejected
Building auth and multi-athlete support up front.
Cost
The system can't be handed to a second athlete without real engineering work — a deliberate trade, not an oversight.

What broke

The project's own README says it plainly: the API does not authenticate requests, and there is no proxy/TLS configuration, deploy pipeline, tested backup, or automatic recovery for failed jobs. None of that is hidden — it's the honest state of a personal system that has so far spent its engineering budget on the part that mattered most: making sure a generated week of training is one a person could actually trust. Production hardening is real, known, unstarted work, not a surprise.

What I'd change

I'd move the validator's rules out of the worker and into something an athlete (or a coach) could read and reason about directly — right now, trusting the plan means trusting the code that checks it, and those should be easier to pull apart.

On this page