Thiago Bueno Garcia
← All projects

Falar: one product, three architectures

Three repositories, one Brazilian Portuguese learning product, one shared domain model. Presented separately they read as three small projects. Presented together, the point is the architecture, not any single client.

Desktop client

portuguese-learning

Electron + React

Event-sourced domain, in-process

Shared contract

falar-portuguese-mobile-backend

Apollo Server + PostgreSQL

GraphQL API over HTTP

Mobile client

falar-portuguese-mobile

Flutter + Riverpod

Fake repo today, GraphQL when live

Why one product, three times

The desktop app owns the reference implementation: an event-sourced learning domain that persists every review and mistake rather than overwriting state. That domain model — what a review session is, how mastery is scored — is the thing being reused, not the code. The mobile client and the backend service each re-express those same rules under a different set of constraints: a backend that exposes them over GraphQL instead of an in-process call, and a mobile client that consumes them the same way any external client would, defaulting to fake data until the real backend is reachable.

The architecture is deliberately not identical across the three. Desktop event-sources because a learning domain's history has real value. The backend persists current state directly and skips event sourcing, because a GraphQL API answering "what is true right now" doesn't need a replayable log. Same author, same instinct toward separated layers, calibrated to what each piece actually needs — not reused wholesale because it worked once.

Each repository is public: portuguese-learning (opens in a new tab), falar-portuguese-mobile-backend (opens in a new tab), falar-portuguese-mobile (opens in a new tab).