<?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: Kevin Coto🚀💡</title>
    <description>The latest articles on DEV Community by Kevin Coto🚀💡 (@kevincoto).</description>
    <link>https://dev.to/kevincoto</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%2F632883%2F871ba5f7-ba57-4db8-8bcd-c650dc315719.jpg</url>
      <title>DEV Community: Kevin Coto🚀💡</title>
      <link>https://dev.to/kevincoto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevincoto"/>
    <language>en</language>
    <item>
      <title>Building a LINE First Fitness Agent with AI Cost Gates</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 01:04:49 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-a-line-first-fitness-agent-with-ai-cost-gates-8e5</link>
      <guid>https://dev.to/kevincoto/building-a-line-first-fitness-agent-with-ai-cost-gates-8e5</guid>
      <description></description>
      <category>architecture</category>
      <category>django</category>
      <category>line</category>
      <category>ai</category>
    </item>
    <item>
      <title>A Polyglot Feedback Platform: Django, Next.js, and Elixir Working Together</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 01:03:53 +0000</pubDate>
      <link>https://dev.to/kevincoto/a-polyglot-feedback-platform-django-nextjs-and-elixir-working-together-b9c</link>
      <guid>https://dev.to/kevincoto/a-polyglot-feedback-platform-django-nextjs-and-elixir-working-together-b9c</guid>
      <description></description>
      <category>architecture</category>
      <category>django</category>
      <category>elixir</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Building an AI Accountability Coach That Knows Your Habits</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 01:03:50 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-an-ai-accountability-coach-that-knows-your-habits-28fh</link>
      <guid>https://dev.to/kevincoto/building-an-ai-accountability-coach-that-knows-your-habits-28fh</guid>
      <description></description>
      <category>architecture</category>
      <category>python</category>
      <category>telegram</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building a Multi Platform AI Budget Coach</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 01:03:20 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-a-multi-platform-ai-budget-coach-1f72</link>
      <guid>https://dev.to/kevincoto/building-a-multi-platform-ai-budget-coach-1f72</guid>
      <description></description>
      <category>architecture</category>
      <category>fastapi</category>
      <category>telegram</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building a Voice AI Receptionist for Restaurants</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 01:03:18 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-a-voice-ai-receptionist-for-restaurants-4hjg</link>
      <guid>https://dev.to/kevincoto/building-a-voice-ai-receptionist-for-restaurants-4hjg</guid>
      <description></description>
      <category>architecture</category>
      <category>fastapi</category>
      <category>voice</category>
      <category>python</category>
    </item>
    <item>
      <title>Building a Reusable Chat Infrastructure with DynamoDB Single Table Design</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 00:51:11 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-a-reusable-chat-infrastructure-with-dynamodb-single-table-design-2k99</link>
      <guid>https://dev.to/kevincoto/building-a-reusable-chat-infrastructure-with-dynamodb-single-table-design-2k99</guid>
      <description></description>
      <category>aws</category>
      <category>dynamodb</category>
      <category>architecture</category>
      <category>svelte</category>
    </item>
    <item>
      <title>Designing a Three Reviewer Consensus Platform for Digital Harm Reporting</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 00:50:41 +0000</pubDate>
      <link>https://dev.to/kevincoto/designing-a-three-reviewer-consensus-platform-for-digital-harm-reporting-573o</link>
      <guid>https://dev.to/kevincoto/designing-a-three-reviewer-consensus-platform-for-digital-harm-reporting-573o</guid>
      <description></description>
      <category>architecture</category>
      <category>aws</category>
      <category>workflow</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Building a Real Time Sports Scoring Engine with WebSockets and DynamoDB Streams</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 00:49:11 +0000</pubDate>
      <link>https://dev.to/kevincoto/building-a-real-time-sports-scoring-engine-with-websockets-and-dynamodb-streams-5c96</link>
      <guid>https://dev.to/kevincoto/building-a-real-time-sports-scoring-engine-with-websockets-and-dynamodb-streams-5c96</guid>
      <description></description>
      <category>aws</category>
      <category>architecture</category>
      <category>realtime</category>
      <category>websocket</category>
    </item>
    <item>
      <title>Migrating a Production Platform from CDK to SST Without Downtime</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 00:48:21 +0000</pubDate>
      <link>https://dev.to/kevincoto/migrating-a-production-platform-from-cdk-to-sst-without-downtime-37ec</link>
      <guid>https://dev.to/kevincoto/migrating-a-production-platform-from-cdk-to-sst-without-downtime-37ec</guid>
      <description></description>
      <category>aws</category>
      <category>architecture</category>
      <category>sst</category>
      <category>cdk</category>
    </item>
    <item>
      <title>From Dubai to Thailand: How I Landed a Remote Role at a South African Company</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Wed, 15 Jul 2026 00:28:06 +0000</pubDate>
      <link>https://dev.to/kevincoto/from-dubai-to-thailand-how-i-found-remote-work-across-three-continents-5fc3</link>
      <guid>https://dev.to/kevincoto/from-dubai-to-thailand-how-i-found-remote-work-across-three-continents-5fc3</guid>
      <description>&lt;h2&gt;
  
  
  The Next Chapter
&lt;/h2&gt;

&lt;p&gt;When I left the waiter job and returned to engineering, I knew I wanted something different. Not just a different job, but a different way of working. The kind where your location does not limit the problems you can solve.&lt;/p&gt;

&lt;p&gt;I found that in Thailand, working for a South African company called Exonic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Bangkok
&lt;/h2&gt;

&lt;p&gt;After Dubai, I wanted somewhere with a lower cost of living where I could build runway while working remotely. Bangkok checks that box. The city is a hub for remote engineers. The internet is fast. The infrastructure works. The street food is better than any restaurant I have ever worked in.&lt;/p&gt;

&lt;p&gt;I arrived with a laptop and a clear goal: find a remote role where I could work on meaningful projects without being tied to a physical office.&lt;/p&gt;




&lt;h2&gt;
  
  
  Landing the Role at Exonic
&lt;/h2&gt;

&lt;p&gt;Exonic is a technology consulting company based in South Africa. They serve clients across multiple industries and geographies. When I found the opening, it matched exactly what I was looking for: full time remote, exposure to diverse projects, and the chance to work across the full stack.&lt;/p&gt;

&lt;p&gt;The interview process was practical. System design discussions, technical assessments focused on AWS and modern frontend frameworks, and conversations about how I approach end to end delivery.&lt;/p&gt;

&lt;p&gt;I got the offer and accepted it immediately.&lt;/p&gt;

&lt;p&gt;As a full time remote employee, I was embedded in Exonic's engineering team. My day to day involved building cloud native solutions for their clients, designing architectures on AWS, and shipping production systems across the entire stack. The team was distributed, and the work required communicating clearly across time zones.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Continents Through One Company
&lt;/h2&gt;

&lt;p&gt;Exonic's client base spans the globe. Over my time there, I built production systems touching three different continents.&lt;/p&gt;

&lt;p&gt;One project was &lt;strong&gt;&lt;a href="https://staging-ai-scoring.exonicsolutions.com/" rel="noopener noreferrer"&gt;Scoring AI&lt;/a&gt;&lt;/strong&gt;, a voice enabled match scoring application for sports courts. Players start a match, share a link, and control the scoreboard using voice commands. I worked on the full stack: the real time scoring engine, voice command processing, the shareable match link flow, and the responsive display that works on phones, tablets, and court side screens. The stack was Svelte on the frontend with a Node backend deployed on AWS.&lt;/p&gt;

&lt;p&gt;Another project was &lt;strong&gt;My IBD Pal&lt;/strong&gt; for Ferring Malaysia, a healthcare application for patients with inflammatory bowel disease. This involved building patient facing interfaces and clinical backend systems, processing health data securely, and integrating with healthcare infrastructure in the Malaysian market. The project is protected and not publicly accessible.&lt;/p&gt;

&lt;p&gt;I also worked on &lt;strong&gt;Real411&lt;/strong&gt;, a digital complaints platform for Media Monitoring Africa in South Africa. The platform allows citizens to report digital offenses, track complaint status, and supports media regulation workflows. Full stack development, from the submission forms to the admin dashboard and trend analytics. This project is also under restricted access.&lt;/p&gt;

&lt;p&gt;I also worked on &lt;strong&gt;Real411&lt;/strong&gt;, a digital complaints platform for Media Monitoring Africa in South Africa. The platform allows citizens to report digital offenses, track complaint status, and supports media regulation workflows. Full stack development, from the submission forms to the admin dashboard and trend analytics.&lt;/p&gt;

&lt;p&gt;Each project had different business contexts, different regulatory requirements, and different user bases. The engineering principles remained the same: understand the domain, design the solution, ship it, document it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AWS Solutions Architect Certification
&lt;/h2&gt;

&lt;p&gt;Working across multiple AWS projects for different clients made one thing clear: I needed a formal credential that backed up the experience. The AWS Solutions Architect certification is the industry standard for cloud architecture knowledge.&lt;/p&gt;

&lt;p&gt;I studied for six weeks. Not because the material is difficult, but because the scope is wide. Compute, storage, networking, databases, security, cost optimization. Each domain has multiple services and multiple trade offs.&lt;/p&gt;

&lt;p&gt;The exam is scenario based. You are given a business requirement and you choose the architecture that meets it. Not just which service, but why. The certification forces you to think in trade offs: cost versus performance, latency versus durability, managed versus self hosted.&lt;/p&gt;

&lt;p&gt;Passing it validated the patterns I had been applying in production for Exonic's clients. The theory matched the practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  End to End Ownership
&lt;/h2&gt;

&lt;p&gt;One of the best parts of the role was the scope. Exonic trusted me with full projects, not just isolated tickets.&lt;/p&gt;

&lt;p&gt;An end to end project looked like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discovery. Understand the business domain. What problem are we solving? Who are the users? What are the constraints?&lt;/li&gt;
&lt;li&gt;Architecture. Choose the stack and design the system. Document the rationale.&lt;/li&gt;
&lt;li&gt;Implementation. Build it. Write tests. Set up CI/CD.&lt;/li&gt;
&lt;li&gt;Deployment. Put it in production. Configure monitoring and alerts.&lt;/li&gt;
&lt;li&gt;Handoff. Document everything. Train the team. Transfer ownership.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AWS certification helped with step two. The experience working across different client contexts helped with step one. The discipline of shipping consistently helped with steps three through five.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed
&lt;/h2&gt;

&lt;p&gt;When I was in Cuba, I was a good engineer with limited options. When I was in Dubai working as a waiter, I was someone starting from zero in a new country. When I landed in Bangkok and joined Exonic, I was someone who had learned that the ceiling is not set by your location.&lt;/p&gt;

&lt;p&gt;It is set by your ability to deliver.&lt;/p&gt;

&lt;p&gt;Employers do not care where you log in from. They care whether the code compiles, the deployments succeed, and the systems stay up. If you can do that consistently, you can work from anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Full time remote is different from freelancing.&lt;/strong&gt; Freelancing gives you flexibility. A full time remote role gives you stability, team structure, and exposure to larger projects. Both are valid, but they require different mindsets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A South African company hiring someone in Thailand to build for clients in Malaysia, South Africa, and beyond is not unusual anymore.&lt;/strong&gt; Geography is no longer a constraint. The companies that understand this win access to global talent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Specific projects teach more than generic ones.&lt;/strong&gt; Scoring AI taught me about real time voice processing on the web. My IBD Pal taught me about healthcare data compliance. Real411 taught me about building for media regulation workflows. Each project expanded my context, not just my tech stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certifications validate what you already know.&lt;/strong&gt; They are not a replacement for experience. But they make it easier to get past the first screening call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full ownership changes how you build.&lt;/strong&gt; When you own the entire lifecycle, you design differently. You think about deployability from day one. You write documentation as you go. You build systems that do not require you to be on call forever.&lt;/p&gt;

&lt;p&gt;I started my career in Cuba. I worked as a waiter in Dubai. I moved to Thailand and joined a South African company building for clients across three continents. The path was not linear, but it was worth it.&lt;/p&gt;

</description>
      <category>career</category>
      <category>life</category>
      <category>aws</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Integrating Cloudflare Turnstile with SvelteKit Forms</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Sun, 30 Mar 2025 15:29:59 +0000</pubDate>
      <link>https://dev.to/kevincoto/using-cloudflare-turnstile-with-sveltekit-a-simple-guide-398k</link>
      <guid>https://dev.to/kevincoto/using-cloudflare-turnstile-with-sveltekit-a-simple-guide-398k</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Bot protection is essential for any public facing form. Cloudflare Turnstile offers a privacy friendly alternative to traditional CAPTCHAs: no image grids, no traffic analysis, just a lightweight challenge that runs in the background.&lt;/p&gt;

&lt;p&gt;When you pair it with SvelteKit's &lt;code&gt;use:enhance&lt;/code&gt; for progressive form enhancement, you hit a subtle issue. Turnstile tokens are single use. After a successful submission, the old token is consumed. The next submission attempt fails because the widget still holds the spent token. The page does not reload (that is the whole point of &lt;code&gt;use:enhance&lt;/code&gt;), so the widget never gets a chance to issue a fresh one.&lt;/p&gt;

&lt;p&gt;This guide walks through a complete SvelteKit integration with server side validation, client side token refresh, and multiple submission support.&lt;/p&gt;




&lt;h2&gt;
  
  
  Server Side Validation
&lt;/h2&gt;

&lt;p&gt;Turnstile verification must happen on the backend. A client side check alone can be bypassed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend (&lt;code&gt;+page.server.ts&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SECRET_TURNSTILE_KEY&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$env/static/private&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://challenges.cloudflare.com/turnstile/v0/siteverify&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SECRET_TURNSTILE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&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="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="o"&gt;=&amp;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;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formData&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;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cf-turnstile-response&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;validateToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&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;success&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Verification failed. Please try again.&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&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="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Form submitted successfully.&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth noting here.&lt;/p&gt;

&lt;p&gt;Turnstile returns the token as &lt;code&gt;cf-turnstile-response&lt;/code&gt; by default. That field name is configurable if you need to avoid collisions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;siteverify&lt;/code&gt; endpoint expects URL encoded form data, not JSON. This is a common gotcha when using &lt;code&gt;fetch&lt;/code&gt; with the default JSON content type.&lt;/p&gt;

&lt;p&gt;Store the secret key in a &lt;code&gt;.env&lt;/code&gt; file as &lt;code&gt;SECRET_TURNSTILE_KEY&lt;/code&gt; and reference it through SvelteKit's &lt;code&gt;$env/static/private&lt;/code&gt; module. Never expose it to the client.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frontend Integration
&lt;/h2&gt;

&lt;p&gt;The client side uses the &lt;code&gt;svelte-turnstile&lt;/code&gt; package which wraps the Turnstile widget as a Svelte component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;svelte-turnstile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend (&lt;code&gt;+page.svelte&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight svelte"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Turnstile&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte-turnstile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;enhance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$app/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;captchaKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;$effect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;captchaKey&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt; &lt;span class="na"&gt;use:enhance&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;#key&lt;/span&gt; &lt;span class="nx"&gt;captchaKey&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Turnstile&lt;/span&gt; &lt;span class="na"&gt;siteKey=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&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="nx"&gt;VITE_TURNSTILE_SITEKEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;/key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why the Key Block Works
&lt;/h3&gt;

&lt;p&gt;SvelteKit's &lt;code&gt;use:enhance&lt;/code&gt; intercepts the form submission and updates the page without a full navigation. The Turnstile widget holds a token that has now been spent.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;{#key captchaKey}&lt;/code&gt; block tells Svelte to destroy and recreate its children whenever &lt;code&gt;captchaKey&lt;/code&gt; changes. Incrementing the counter inside the &lt;code&gt;$effect&lt;/code&gt; forces a fresh Turnstile widget to mount with a new token.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;setTimeout&lt;/code&gt;, no mount/unmount races, just a counter increment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment Variables
&lt;/h2&gt;

&lt;p&gt;You need two keys from the Cloudflare Turnstile dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;VITE_TURNSTILE_SITEKEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0x4AAAAAA...    # public, exposed to browser&lt;/span&gt;
&lt;span class="py"&gt;SECRET_TURNSTILE_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0x4AAAAAA...       # private, server only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;VITE_&lt;/code&gt; prefix makes the variable available to client side Vite bundles. The un-prefixed version is loaded through &lt;code&gt;$env/static/private&lt;/code&gt; and never leaves the server.&lt;/p&gt;




&lt;h2&gt;
  
  
  Production Considerations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Token expiry.&lt;/strong&gt; Turnstile tokens expire after 300 seconds. If a user fills out a long form, the token may become invalid by the time they hit submit. Consider implementing a periodic refresh mechanism for forms with long completion times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limiting.&lt;/strong&gt; The &lt;code&gt;/siteverify&lt;/code&gt; endpoint does not have built in rate limiting. Implement your own per IP or per session limits to prevent abuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessibility.&lt;/strong&gt; Turnstile runs a non interactive challenge by default. If the challenge fails, it falls back to a visible widget. Test this flow with keyboard only navigation and screen readers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple forms on one page.&lt;/strong&gt; Each Turnstile instance needs a unique widget ID. The &lt;code&gt;svelte-turnstile&lt;/code&gt; component handles this internally, but verify that your page layout does not share instances between forms.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Turnstile tokens are single use and require a fresh widget after each submission.&lt;/li&gt;
&lt;li&gt;Server side validation is mandatory. Never trust the client alone.&lt;/li&gt;
&lt;li&gt;The mount/unmount pattern in &lt;code&gt;$effect&lt;/code&gt; solves the token refresh problem cleanly.&lt;/li&gt;
&lt;li&gt;Environment variables keep your keys separated by environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup gives you a secure, bot protected form that works with SvelteKit's progressive enhancement.&lt;/p&gt;

</description>
      <category>svelte</category>
      <category>captcha</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>LeetCode 35: Search Insert Position. Binary Search vs Linear Scan</title>
      <dc:creator>Kevin Coto🚀💡</dc:creator>
      <pubDate>Fri, 14 Mar 2025 19:50:34 +0000</pubDate>
      <link>https://dev.to/kevincoto/yeah-leetcode-without-google-or-llm-part-1-35-search-insert-position-4gpl</link>
      <guid>https://dev.to/kevincoto/yeah-leetcode-without-google-or-llm-part-1-35-search-insert-position-4gpl</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Given a sorted array of distinct integers and a target value, return the index where the target would be inserted to maintain order. If the target already exists, return its index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input: nums = [1, 3, 5, 6], target = 5
Output: 2

Input: nums = [1, 3, 5, 6], target = 2
Output: 1

Input: nums = [1, 3, 5, 6], target = 7
Output: 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem is straightforward on the surface, but the constraints reveal its intent. The array is sorted, and the operation needs to complete efficiently.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Linear Solution
&lt;/h2&gt;

&lt;p&gt;A linear scan checks each element until we find the insertion point.&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;searchInsert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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;This works but runs in O(n) time. For an array of 10,000 elements, the worst case iterates through all of them. The problem expects a solution that exploits the fact that the input is sorted.&lt;/p&gt;




&lt;h2&gt;
  
  
  Binary Search
&lt;/h2&gt;

&lt;p&gt;Binary search divides the search space in half at each step. It runs in O(log n) time, which means finding an element in a million entries takes at most 20 comparisons instead of a million.&lt;/p&gt;

&lt;p&gt;The algorithm maintains three pointers: &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;, and &lt;code&gt;mid&lt;/code&gt;. At each step we check the middle element. If it matches the target, we are done. If the target is smaller, we discard the right half. If larger, we discard the left half.&lt;/p&gt;

&lt;p&gt;When the loop ends without finding the target, &lt;code&gt;left&lt;/code&gt; points to where the target should be inserted.&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;searchInsert&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;right&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;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&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="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;target&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="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;left&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;h2&gt;
  
  
  Why the Insertion Point Works
&lt;/h2&gt;

&lt;p&gt;When the loop exits, &lt;code&gt;left&lt;/code&gt; has crossed &lt;code&gt;right&lt;/code&gt;. The element at &lt;code&gt;left&lt;/code&gt; is the first element greater than the target (or &lt;code&gt;left&lt;/code&gt; equals the array length if the target belongs at the end). This is exactly the insertion position.&lt;/p&gt;

&lt;p&gt;The invariant &lt;code&gt;nums[right] &amp;lt; target &amp;lt; nums[left]&lt;/code&gt; holds at the point of exit. Visualizing this helps. Try tracing through &lt;code&gt;[1, 3, 5, 6]&lt;/code&gt; with &lt;code&gt;target = 2&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;Step 1: left=0, right=3, mid=1, nums[1]=3 &amp;gt; 2, go left
Step 2: left=0, right=0, mid=0, nums[0]=1 &amp;lt; 2, go right
Step 3: left=1, right=0, exit loop, return left=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The index 1 is where 2 fits between 1 and 3.&lt;/p&gt;




&lt;h2&gt;
  
  
  Edge Cases
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Target smaller than all elements.&lt;/strong&gt; The algorithm returns 0, which is correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nums = [10, 20], target = 5
left=0, right=1, mid=0, nums[0]=10 &amp;gt; 5, right=-1, exit, return 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Target larger than all elements.&lt;/strong&gt; The loop shifts &lt;code&gt;left&lt;/code&gt; past the last index and returns &lt;code&gt;nums.length&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;nums = [10, 20], target = 30
left=0, right=1, mid=0, nums[0]=10 &amp;lt; 30, left=1
left=1, right=1, mid=1, nums[1]=20 &amp;lt; 30, left=2
exit, return 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Single element arrays.&lt;/strong&gt; The algorithm handles these with no special cases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nums = [5], target = 3
left=0, right=0, mid=0, nums[0]=5 &amp;gt; 3, right=-1, exit, return 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Complexity
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Space&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linear scan&lt;/td&gt;
&lt;td&gt;O(n)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary search&lt;/td&gt;
&lt;td&gt;O(log n)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Binary search matches the problem's constraints and is the expected solution. The space complexity is constant because we only store three integers regardless of input size.&lt;/p&gt;




&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;Binary search is one of those patterns that seems trivial on paper but requires careful pointer management in practice. The off by one errors are common. The key is tracking the invariant: the condition for moving &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; must be consistent, and the exit condition must guarantee that &lt;code&gt;left&lt;/code&gt; is the answer.&lt;/p&gt;

&lt;p&gt;Practice this pattern on a few variations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard binary search (find exact match)&lt;/li&gt;
&lt;li&gt;Lower bound (first position where element could be inserted)&lt;/li&gt;
&lt;li&gt;Upper bound (last position where element could be inserted)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each variant adjusts the pointer movement rules slightly. Understanding one makes the others click.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>javascript</category>
      <category>leetcode</category>
    </item>
  </channel>
</rss>
