<?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: Param Jaisinghani</title>
    <description>The latest articles on DEV Community by Param Jaisinghani (@param_jaisinghani_b7c9705).</description>
    <link>https://dev.to/param_jaisinghani_b7c9705</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%2F4091227%2F9b4ca728-97b8-43fe-be92-12246f42c4de.png</url>
      <title>DEV Community: Param Jaisinghani</title>
      <link>https://dev.to/param_jaisinghani_b7c9705</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/param_jaisinghani_b7c9705"/>
    <language>en</language>
    <item>
      <title>APEX Versus: An AI That Instantly Settles Any 'Who Would Win' Argument</title>
      <dc:creator>Param Jaisinghani</dc:creator>
      <pubDate>Wed, 16 Sep 2026 05:31:25 +0000</pubDate>
      <link>https://dev.to/param_jaisinghani_b7c9705/apex-versus-an-ai-that-instantly-settles-any-who-would-win-argument-473m</link>
      <guid>https://dev.to/param_jaisinghani_b7c9705/apex-versus-an-ai-that-instantly-settles-any-who-would-win-argument-473m</guid>
      <description>&lt;p&gt;Ever argued with a friend about who'd win — Goku or Superman? Messi or Ronaldo? Your country vs... any other country? I built &lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;APEX Versus&lt;/a&gt; to settle exactly this kind of argument instantly, using AI.&lt;/p&gt;

&lt;p&gt;Type any two things — real people, anime characters, movie heroes, companies, countries, athletes, even animals — and get an instant, detailed verdict. Free, no account needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it actually works
&lt;/h2&gt;

&lt;p&gt;It's not just "whichever name has more search results." An AI model automatically detects what &lt;em&gt;category&lt;/em&gt; your matchup belongs to — there are 16 of them — and scores it on 7 dimensions that actually make sense for that category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Anime characters&lt;/strong&gt; → Power, Speed, Durability, Technique, Battle IQ, Willpower, Potential&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Athletes&lt;/strong&gt; → Skill, Athleticism, Achievements, Consistency, Clutch Factor, Legacy, Versatility&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Countries&lt;/strong&gt; → Economy, Military, Influence, Innovation, Quality of Life, Culture, Growth&lt;/li&gt;
&lt;li&gt;Plus real people, companies, cricketers, movies, food, animals, mythology, video game characters, cars, electronics, and medical products — each with their own 7 dimensions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Naruto vs Goku" and "India vs China" don't get scored on the same axes — the AI picks the right lens and shows a radar chart breakdown, not just a single number.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fun stuff
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⚡ &lt;strong&gt;Power Tiers&lt;/strong&gt; — fictional characters get an 8-tier power-scaling badge, from "C — Peak Human" up to "S++ — Omniversal," the same convention power-scaling communities use&lt;/li&gt;
&lt;li&gt;🎲 &lt;strong&gt;Surprise Me&lt;/strong&gt; — one click picks a genuinely plausible random matchup from the same category&lt;/li&gt;
&lt;li&gt;🏆 &lt;strong&gt;Power Rankings&lt;/strong&gt; — every comparison ever run feeds a live leaderboard of the highest-scoring entities on the whole site&lt;/li&gt;
&lt;li&gt;🗳️ &lt;strong&gt;Community Verdict&lt;/strong&gt; — vote on whether you agree with the AI's call and see the real-time split&lt;/li&gt;
&lt;li&gt;💬 &lt;strong&gt;Forum&lt;/strong&gt; — argue it out with other people, not just the AI&lt;/li&gt;
&lt;li&gt;🎬 &lt;strong&gt;Video export&lt;/strong&gt; — download your result as a shareable video card&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Embeddable widget&lt;/strong&gt; — drop a live result card onto your own blog with two lines of code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why it's not just a toy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free tier&lt;/strong&gt;: 5 comparisons a day, zero signup friction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant&lt;/strong&gt;: a real verdict in a few seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent&lt;/strong&gt;: results are cached, so a popular matchup gives everyone the same real analysis instead of a different random answer every time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Careful where it matters&lt;/strong&gt;: for sensitive categories like medical products, the AI is explicitly instructed to stay informational rather than prescriptive — it's not medical advice, and the app says so clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a small side project, still improving every week. If you've got a "who would win" argument that's been unresolved for years, go settle it: &lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;apexversus.com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My paid AI feature was simultaneously free-for-anyone-to-abuse AND broken for the people actually paying for it</title>
      <dc:creator>Param Jaisinghani</dc:creator>
      <pubDate>Fri, 04 Sep 2026 10:44:56 +0000</pubDate>
      <link>https://dev.to/param_jaisinghani_b7c9705/my-paid-ai-feature-was-simultaneously-free-for-anyone-to-abuse-and-broken-for-the-people-actually-53e2</link>
      <guid>https://dev.to/param_jaisinghani_b7c9705/my-paid-ai-feature-was-simultaneously-free-for-anyone-to-abuse-and-broken-for-the-people-actually-53e2</guid>
      <description>&lt;p&gt;A few weeks ago I shipped "Deep Analysis" and "Advanced Analysis" on &lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;APEX Versus&lt;/a&gt; - an AI "who would win" comparison site. Pay a few credits, get a deeper AI breakdown of any matchup: per-dimension reasoning, a hypothetical scenario, wildcard factors, that kind of thing. Pro plan users are supposed to get it unlimited.&lt;/p&gt;

&lt;p&gt;Ran a full debug pass on the codebase this week. Found out the feature had two bugs at once, and they canceled each other out in the worst possible way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 1: the paywall didn't exist server-side.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The frontend checked credits before calling the API. Normal enough - except the API itself never checked anything. &lt;code&gt;POST /api/compare&lt;/code&gt; with &lt;code&gt;mode: 'advanced'&lt;/code&gt; and no auth header at all would happily burn a real Gemini call and return real content. No login required, no credit check, no daily cap. The free-tier quota I did have only applied to the basic comparison endpoint - I'd built rate limiting for the wrong door.&lt;/p&gt;

&lt;p&gt;I confirmed it with a plain curl request. It worked. Zero auth, zero payment, full output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 2: the feature was invisible to the people who'd actually paid for it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Separately, the UI had this line:&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="nx"&gt;deepCard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isPaid&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that again. The card that lets you use Deep Analysis was hidden whenever the user was on a paid plan. My "Advanced Analysis" button - the one Pro users are paying for - had literally no onclick anywhere in the HTML. The function existed. Nothing called it. Ever. It had been dead code since the day I wrote it.&lt;/p&gt;

&lt;p&gt;So: free users who found the right request shape got it for nothing, forever. Paying users couldn't find the button to use the feature they were paying for. Directly opposite of what a paywall is supposed to do, both directions, at once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The root cause was the same bug wearing two different hats.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd tightened Firestore security rules a while back so credit balances can only be written server-side (admin SDK), not by the client - good instinct, closes a real self-serve-credits exploit. But I never went back and updated the code that used to write credits from the browser. It was still there, still running, just silently failing every time:&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deductPaidCredit&lt;/span&gt; &lt;span class="o"&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;updateDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userCredits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;credits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&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="c1"&gt;// this write has been rejected by security rules for weeks.&lt;/span&gt;
    &lt;span class="c1"&gt;// the empty catch below means nobody ever found out.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;An empty catch block is a great way to make a permission error indistinguishable from success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix was straightforward once the actual shape of the bug was clear:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moved the credit check and deduction fully server-side, inside a Firestore transaction, before the Gemini call happens - not after.&lt;/li&gt;
&lt;li&gt;Deleted the dead client-side deduction function entirely.&lt;/li&gt;
&lt;li&gt;Fixed the inverted visibility check so paid users can actually see the feature.&lt;/li&gt;
&lt;li&gt;Added the missing button for the half of the feature that never had one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I tested it for real instead of trusting the diff: ran Deep Analysis on a live paid account and watched the credit balance drop by exactly 2, atomically, server-confirmed. First time in this feature's existence that a credit deduction has actually happened.&lt;/p&gt;

&lt;p&gt;The lesson that's stuck with me: a client-side check and a server-side check are not the same feature just because they look at the same variable. One is a suggestion. The other is the only one that counts. I had the suggestion and skipped the count for a feature that directly touches revenue, and it took a dedicated audit - not normal usage, not testing, not code review - to surface it, because both failure modes were silent by design (empty catches, hidden UI) rather than loud.&lt;/p&gt;

&lt;p&gt;If you're running anything with a credits/paywall system: grep your codebase for every place a balance gets checked, and ask whether that check would survive someone skipping your UI entirely and hitting the API directly. If the answer requires the word "should," it's not actually enforced.&lt;/p&gt;




&lt;p&gt;APEX Versus is live at &lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;apexversus.com&lt;/a&gt; if you want to see the (now-actually-working) Deep Analysis in action - first few comparisons are free, no signup needed.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Built an AI That Settles "Who Would Win" Arguments — Here's How</title>
      <dc:creator>Param Jaisinghani</dc:creator>
      <pubDate>Sun, 23 Aug 2026 20:12:19 +0000</pubDate>
      <link>https://dev.to/param_jaisinghani_b7c9705/i-built-an-ai-that-settles-who-would-win-arguments-heres-how-1en8</link>
      <guid>https://dev.to/param_jaisinghani_b7c9705/i-built-an-ai-that-settles-who-would-win-arguments-heres-how-1en8</guid>
      <description>&lt;p&gt;Every group chat has that debate that never resolves: Messi or Ronaldo, Naruto or Goku, India or China. Someone always says "there's no real answer" and the thread dies. I got annoyed enough by this that I built a site that actually gives an answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;APEX Versus&lt;/a&gt; lets you type any two people, characters, companies, or countries and get an AI verdict across 7 power dimensions — power, influence, wealth, intelligence, legacy, popularity, and potential. It picks a winner, gives an Apex Score for each side, and explains the reasoning instead of just flipping a coin.&lt;/p&gt;

&lt;p&gt;Try it right now, no signup needed for your first few: &lt;strong&gt;&lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;https://apexversus.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this was harder than it sounds
&lt;/h2&gt;

&lt;p&gt;The obvious approach — "just ask an LLM who'd win" — falls apart fast. Ask the same matchup twice and you get wildly different reasoning, sometimes a different winner entirely. I ended up structuring every prompt around the same fixed rubric (the 7 dimensions), forcing the model to score each one explicitly before it's allowed to declare a winner. That single change took the results from "random vibes" to something that felt consistent and defensible.&lt;/p&gt;

&lt;p&gt;Caching was the other half of the battle. Every unique matchup gets computed once via Gemini and cached in Firestore — reads stay public so anonymous visitors get instant results, but writes are locked down server-side (more on why below).&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: plain HTML/JS, no framework — kept it simple since this was a solo build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Vercel serverless functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI&lt;/strong&gt;: Gemini API for generating verdicts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DB/Auth&lt;/strong&gt;: Firebase (Firestore + Auth)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payments&lt;/strong&gt;: Razorpay for the paid tier&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A real security lesson
&lt;/h2&gt;

&lt;p&gt;Early on, the Firestore rules for the cache collection were wide open — anyone could PATCH a battle's cached verdict directly via the public REST API, no auth required. On a site whose whole product is declaring "winners" about real people and companies, that's a content-injection hole waiting to be exploited. Locked it down so writes only happen through the Admin SDK server-side, reads stay public. Same story for daily-battle content and user credit balances, which I found could be self-granted client-side before the fix. Worth a reminder that "nobody's going to bother" is not a security model, even for a small solo project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Referral system, push notifications for daily battles, and expanding the SEO-friendly comparison pages. Built and run solo, so feedback — what's broken, what's missing, what matchup you tried that gave a bad answer — is genuinely useful and I read all of it.&lt;/p&gt;

&lt;p&gt;Try it: &lt;strong&gt;&lt;a href="https://apexversus.com" rel="noopener noreferrer"&gt;https://apexversus.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ai</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
