<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CESAR EDUARDO STURMER</title>
    <description>The latest articles on DEV Community by CESAR EDUARDO STURMER (@cesarsturmer).</description>
    <link>https://dev.to/cesarsturmer</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4153198%2F0e71df10-0c0f-4e67-88fa-827c2899c501.jpeg</url>
      <title>DEV Community: CESAR EDUARDO STURMER</title>
      <link>https://dev.to/cesarsturmer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cesarsturmer"/>
    <language>en</language>
    <item>
      <title>Construindo o surfaai do zero: stack, decisões e o que eu faria diferente</title>
      <dc:creator>CESAR EDUARDO STURMER</dc:creator>
      <pubDate>Wed, 30 Sep 2026 22:33:00 +0000</pubDate>
      <link>https://dev.to/cesarsturmer/construindo-o-surfaai-do-zero-stack-decisoes-e-o-que-eu-faria-diferente-33p5</link>
      <guid>https://dev.to/cesarsturmer/construindo-o-surfaai-do-zero-stack-decisoes-e-o-que-eu-faria-diferente-33p5</guid>
      <description>&lt;p&gt;Depois de alguns anos como engenheiro de software em empresas — frontend architecture, sistemas distribuídos, produtos que outras pessoas definiam — decidi construir algo do zero, sozinho: do primeiro commit até estar rodando em produção, com usuários reais e dinheiro de verdade passando pelo sistema.&lt;/p&gt;

&lt;p&gt;Esse algo é o &lt;strong&gt;surfaai&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esta é a primeira de uma série de artigos técnicos sobre as decisões que tomei construindo o surfaai. Não é um tutorial de "como fazer X" — é um relato real de arquitetura: os trade-offs que pesei, os erros que cometi, e o que eu faria diferente se começasse hoje. Se você já pensou em sair de só integrar sistemas dos outros pra construir o seu, ou só curte ver decisão técnica real (com o porquê, não só o resultado final), essa série é pra você.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que o surfaai
&lt;/h2&gt;

&lt;p&gt;O surfaai nasceu de um problema simples: conectar alunos a providers (instrutores/prestadores de serviço) numa plataforma que cuidasse de agendamento, pagamento e repasse automático — sem que cada provider precisasse resolver seu próprio checkout, emissão, taxas e split.&lt;/p&gt;

&lt;p&gt;Toda plataforma que conecta duas pontas com dinheiro no meio esbarra cedo ou tarde na mesma pergunta difícil: quem fica responsável pela parte financeira? Deixar cada provider resolver isso por conta própria significa fricção de onboarding, inconsistência de experiência pro aluno e nenhum controle real sobre a operação. Foi esse o problema que me fez decidir construir a própria camada de pagamento da plataforma, em vez de terceirizar isso pra fora do produto.&lt;/p&gt;

&lt;p&gt;Sou o desenvolvedor principal do projeto — arquitetura, backend, frontend e pagamentos —, e este é o primeiro de uma série de artigos técnicos sobre as decisões que tomamos construindo isso em produção.&lt;/p&gt;

&lt;h2&gt;
  
  
  A stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js + React + TypeScript&lt;/strong&gt; no front e nas rotas de API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind&lt;/strong&gt; pra UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supabase&lt;/strong&gt; (Postgres + Auth + RLS) como backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe Connect (Express)&lt;/strong&gt; para pagamentos e repasse a providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada peça dessa stack foi escolhida pensando em um time pequeno mantendo um produto com dinheiro real passando por ele — ou seja, produtividade de desenvolvimento sem abrir mão de segurança e corretude financeira.&lt;/p&gt;

&lt;h2&gt;
  
  
  O desafio central: marketplace de verdade precisa de split de pagamento
&lt;/h2&gt;

&lt;p&gt;A parte mais delicada de um marketplace não é o cadastro ou o agendamento — é garantir que o dinheiro do aluno chegue certo ao provider, com a taxa da plataforma descontada corretamente, de forma auditável e sem race conditions.&lt;/p&gt;

&lt;p&gt;Isso significou usar &lt;strong&gt;Stripe Connect com destination charges&lt;/strong&gt;: o PaymentIntent é criado na plataforma, com uma taxa de aplicação (&lt;code&gt;application_fee_amount&lt;/code&gt;) e o destino do repasse (&lt;code&gt;transfer_data.destination&lt;/code&gt;) apontando pra conta Connect do provider. O Stripe cuida da transferência líquida automaticamente assim que o pagamento é confirmado.&lt;/p&gt;

&lt;p&gt;Vou detalhar essa arquitetura no próximo artigo da série.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma decisão que valeu a pena: créditos só nascem no webhook
&lt;/h2&gt;

&lt;p&gt;Desde o início, decidimos que créditos de compra &lt;strong&gt;nunca são criados no client-side&lt;/strong&gt; — só no evento &lt;code&gt;payment_intent.succeeded&lt;/code&gt; do webhook do Stripe. Isso evita duplicação de crédito por race condition (por exemplo, usuário atualizando a página de confirmação duas vezes) e torna o sistema auditável: toda criação de crédito tem uma origem única e rastreável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migração de gateway em produção
&lt;/h2&gt;

&lt;p&gt;O surfaai não nasceu no Stripe — começou com Asaas e migramos para Stripe já com usuários ativos. Foi uma das decisões técnicas mais arriscadas do projeto, e vou contar como fizemos isso sem quebrar nada em outro artigo desta série.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que vem a seguir
&lt;/h2&gt;

&lt;p&gt;Nos próximos posts vou destrinchar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como funciona destination charges na prática (com código)&lt;/li&gt;
&lt;li&gt;Por que idempotência em webhook de pagamento não é opcional&lt;/li&gt;
&lt;li&gt;Como migramos de gateway de pagamento sem downtime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se você constrói produtos com pagamento embutido, ou só curte ver decisões reais de arquitetura (com os trade-offs e os erros no caminho), me segue aqui e no GitHub.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>supabase</category>
      <category>stripe</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
