
Teladoc Health
Two builds of one telemedicine product: the partner-distributed app, taken through version 2.0 and a null-safety migration, and its consumer fork.Duas versões de um mesmo produto de telemedicina: o app distribuído por parceiros, levado à versão 2.0 e à migração para null safety, e o seu fork de consumo.
ProjectsProjetos
B2B App
2022 – 20232022 – 2023- Android
- iOS
The Teladoc build distributed through corporate and health-plan partners, where a patient’s access comes from their employer or insurer rather than a sign-up of their own: video and audio consultations with certified doctors, appointment scheduling with specialists, in-app chat, and sharing of medical documents and test results. It was the largest codebase I had worked on, and the oldest: several Flutter releases behind and written before null safety. My first long assignment was version 2.0 — a rework of the interface and the experience that also had to carry new content — built with a senior developer in Jira sprints, while production defects arrived on a separate board and went back out as hotfix builds. This is the build published on Google Play and the App Store.A versão do Teladoc distribuída por parceiros corporativos e planos de saúde, em que o acesso do paciente vem do empregador ou da operadora, e não de um cadastro próprio: consultas por vídeo e áudio com médicos certificados, agendamento com especialistas, chat dentro do app e compartilhamento de documentos médicos e resultados de exames. Era a maior base de código em que eu já tinha trabalhado, e também a mais antiga: várias versões do Flutter atrás e escrita antes do null safety. Minha primeira frente longa foi a versão 2.0 — uma reformulação da interface e da experiência que ainda precisava acomodar conteúdo novo — feita com um desenvolvedor sênior em sprints no Jira, enquanto defeitos de produção chegavam em um board separado e voltavam como builds de correção. É esta a versão publicada no Google Play e na App Store.
- MobileMobile
- Flutter
- Dart
- Provider
- built_value
- build_runner
- Method channels
A codebase several Flutter releases behind and written before null safety, with Provider for dependency injection and models generated through built_value and build_runner. Version 2.0 reworked the interface over that, and the booking flow was where the rework stopped being cosmetic: the app asked for a kind of professional, then the professional, then a slot on that professional’s calendar, which is the wrong order for a patient who cares more about when than about whom. I proposed the inverse — kind, slot, professional — and took it to the POs with the endpoints it would need, because nothing on the existing API answered the question that way round. Plugin work reached across the platform channel boundary too: I never published a package of my own, but I updated third-party ones’ native dependencies and, where no fix existed upstream, their implementations.Uma base de código várias versões do Flutter atrás e escrita antes do null safety, com Provider para injeção de dependências e modelos gerados por built_value e build_runner. A versão 2.0 reformulou a interface sobre isso, e o fluxo de agendamento foi onde a reformulação deixou de ser cosmética: o app pedia o tipo de profissional, depois o profissional, depois um horário na agenda dele, que é a ordem errada para o paciente que se importa mais com quando do que com quem. Propus o inverso — tipo, horário, profissional — e levei aos POs junto com os endpoints que aquilo exigiria, porque nada na API existente respondia a pergunta nessa ordem. O trabalho com plugins também alcançou a fronteira dos method channels: nunca publiquei um pacote meu, mas atualizei dependências nativas de pacotes de terceiros e, quando não havia correção upstream, a implementação deles.
- Real-time & MediaTempo real e mídia
- OpenTok (Vonage Video)
- WebRTC
- Pusher
- OneSignal
Consultations ran on OpenTok, Vonage’s WebRTC platform, and had to hold up on the unreliable mobile connections patients actually call from. Chat ran over Pusher, and that is where the most time went: we were on an unofficial client, and when an official one was finally released I moved to it and found it could not disconnect and resubscribe to a different channel. The supported package was the wrong answer, so we stayed on the unofficial one. Push notifications went out through OneSignal.As consultas rodavam sobre o OpenTok, a plataforma WebRTC da Vonage, e precisavam se sustentar nas conexões móveis instáveis de onde os pacientes realmente ligam. O chat rodava sobre Pusher, e foi aí que se foi mais tempo: estávamos em um cliente não oficial e, quando um oficial enfim saiu, migrei para ele e descobri que não conseguia desconectar e se inscrever em outro canal. O pacote com suporte era a resposta errada, então ficamos no não oficial. As notificações push saíam pelo OneSignal.
- Stability & ReleaseEstabilidade e publicação
- Firebase Crashlytics
- Firebase Analytics
Upgrading Flutter and migrating to null safety began as curiosity and a static-analysis argument, done in my own time on a branch I kept current alongside the 2.0 work. It stopped being a developer-experience question once store requirements moved: builds from the old version were no longer accepted, and the upgraded branch was what got through. Production defects came in on their own board, sometimes with steps to reproduce, sometimes with a patient’s account of a consultation that failed halfway; Crashlytics and Analytics narrowed what those reports could not, and the fixes went out as hotfix builds off branches kept separate from the release line.Atualizar o Flutter e migrar para null safety começou como curiosidade e argumento de análise estática, feito em tempo próprio numa branch que eu mantinha em dia ao lado do trabalho da 2.0. Deixou de ser questão de produtividade quando as exigências das lojas mudaram: builds da versão antiga não eram mais aceitas, e foi a branch atualizada que passou. Os defeitos de produção chegavam em um board próprio, às vezes com passos de reprodução, às vezes com o relato de um paciente cuja consulta falhou pela metade; Crashlytics e Analytics delimitaram o que esses relatos não davam conta, e as correções saíam como builds de hotfix em branches separadas da linha de release.
B2C App
2022 – 20232022 – 2023- Android
- iOS
A fork of the B2B build for patients arriving on their own, with no employer or health plan behind them — which meant this version had to collect payment for the consultation, where the partner build never did. That flow was settled on the backend and had been built before I joined the team. It was the newer and healthier of the two codebases: Flutter and the libraries were already current and the code was null-safe, so none of the upgrade work the B2B app needed applied here. I passed through it in short stretches rather than as a main assignment, updating interface components and fixing production defects.Um fork da versão B2B para o paciente que chega por conta própria, sem empregador nem plano de saúde por trás — o que obrigava esta versão a cobrar a consulta, coisa que a versão via parceiro nunca precisou fazer. Esse fluxo era resolvido no backend e já existia antes de eu entrar no time. Era a mais nova e a mais saudável das duas bases de código: Flutter e bibliotecas já em dia e o código null-safe, então nada do trabalho de atualização que a versão B2B exigiu se aplicava aqui. Passei por ele em períodos curtos, e não como frente principal, atualizando componentes de interface e corrigindo defeitos de produção.
- MobileMobile
- Flutter
- Dart
- freezed
The consultation, scheduling and file-sharing surfaces are the ones from the B2B build, but the codebase around them was in better shape: current Flutter, current libraries, null-safe, and models generated through freezed rather than the built_value setup on the B2B side — none of the migration the partner app was still owed. My work here was narrow — interface components and production defects — and the defects were the part worth keeping: a bug in a fork is usually still a bug in what it was forked from, which is how fixing one app kept turning into fixing two.As telas de consulta, agendamento e envio de arquivos são as da versão B2B, mas a base de código em volta delas estava em melhor estado: Flutter em dia, bibliotecas em dia, null-safe e modelos gerados por freezed, em vez do arranjo com built_value do lado B2B — nada da migração que a versão via parceiro ainda devia. Meu trabalho aqui foi estreito — componentes de interface e defeitos de produção — e os defeitos foram a parte que vale guardar: um bug em um fork em geral ainda é um bug naquilo de que ele saiu, e foi assim que corrigir um app virava corrigir dois.