<?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: Melroy D Souza</title>
    <description>The latest articles on DEV Community by Melroy D Souza (@russel_melroydsouza_afb).</description>
    <link>https://dev.to/russel_melroydsouza_afb</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%2F3617790%2F0b75cc41-600f-4f12-9164-4edb93729dff.png</url>
      <title>DEV Community: Melroy D Souza</title>
      <link>https://dev.to/russel_melroydsouza_afb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/russel_melroydsouza_afb"/>
    <language>en</language>
    <item>
      <title>I Onboarded 14 Indie Devs to TestFlight This Month. Here's What Actually Confused Them</title>
      <dc:creator>Melroy D Souza</dc:creator>
      <pubDate>Wed, 29 Jul 2026 04:47:34 +0000</pubDate>
      <link>https://dev.to/russel_melroydsouza_afb/i-onboarded-14-indie-devs-to-testflight-this-month-heres-what-actually-confused-them-2j9j</link>
      <guid>https://dev.to/russel_melroydsouza_afb/i-onboarded-14-indie-devs-to-testflight-this-month-heres-what-actually-confused-them-2j9j</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Every first-timer asks the same four questions in the same order, and the gap between "my build succeeded" and "why can't my friend install it" is where most quit for 2 to 3 days.&lt;/li&gt;
&lt;li&gt;The real map has &lt;strong&gt;eight steps across three separate Apple properties&lt;/strong&gt; (Developer Portal, App Store Connect, the TestFlight app) and two async waits.&lt;/li&gt;
&lt;li&gt;After &lt;code&gt;eas submit&lt;/code&gt;, watch the App Store Connect &lt;strong&gt;Activity&lt;/strong&gt; tab, not the TestFlight tab. Activity shows "Processing" immediately; TestFlight only shows the build once processing finishes.&lt;/li&gt;
&lt;li&gt;A pre-flight checklist, an ITMS error decoder, and a live walkthrough with the first tester cut time-to-first-tester from 3 days to 90 minutes.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Running a small Discord for React Native indies, I did unstructured office hours with 14 devs shipping their first TestFlight build this month. Every single one hit the same four walls in roughly the same order.&lt;/p&gt;

&lt;p&gt;None of them were technical walls. They were &lt;strong&gt;mental-model&lt;/strong&gt; walls, and every EAS tutorial online is written by people who forgot they exist.&lt;/p&gt;

&lt;p&gt;Here's what I saw, in the order they saw it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four questions every first-timer asks (in order)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;"Do I need a Mac?" (Answer: not for EAS. Yes, eventually, for &lt;code&gt;xcrun&lt;/code&gt; when things go wrong.)&lt;/li&gt;
&lt;li&gt;"Wait, what's the difference between App Store Connect and my Apple Developer account?"&lt;/li&gt;
&lt;li&gt;"I ran &lt;code&gt;eas build&lt;/code&gt; and it succeeded. Where's the app?"&lt;/li&gt;
&lt;li&gt;"Why can't my friend just... install it?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every single time, in that order. And the gap between question 3 and question 4 is where most people quit for 48 to 72 hours, because they don't know what they don't know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the mental model breaks
&lt;/h2&gt;

&lt;p&gt;Here's the actual conceptual map: how devs think it works, versus how it works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How they think it works:&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;[my code] --&amp;gt; [EAS] --&amp;gt; [TestFlight] --&amp;gt; [friend's phone]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it actually works:&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;[my code]
   --&amp;gt; [EAS builds .ipa, signed with a cert tied to my Apple Dev account]
   --&amp;gt; [eas submit uploads .ipa to App Store Connect]
   --&amp;gt; [ASC processes the build ~5-30 min, may email you an ITMS error]
   --&amp;gt; [ASC exposes the processed build in the TestFlight tab]
   --&amp;gt; [I add internal testers by Apple ID email, they get an email]
   --&amp;gt; [tester installs the TestFlight app first, then accepts the invite, then installs my app]
   --&amp;gt; [external testers need Beta App Review, another 24-48 hr]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eight steps. Three separate Apple properties (Developer Portal, App Store Connect, the TestFlight app on the phone). Two async waits (processing, review). One place where things silently break: ITMS emails go to your Apple ID, not your dev email, if those differ.&lt;/p&gt;

&lt;p&gt;When I draw this on a whiteboard for someone, the reaction is always the same exhale: "oh, &lt;em&gt;that's&lt;/em&gt; why the tutorials didn't make sense."&lt;/p&gt;

&lt;h2&gt;
  
  
  The eas submit moment: relief or panic
&lt;/h2&gt;

&lt;p&gt;The single highest-emotional-swing moment in the whole flow is the first &lt;code&gt;eas submit -p ios --latest&lt;/code&gt;. It succeeds and prints something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✔ Submitted your app to Apple App Store!
App Store Connect: https://appstoreconnect.apple.com/apps/1234567890/testflight/ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They click the link. They see an empty TestFlight tab. Panic sets in. "Did it fail? Did I do it wrong?"&lt;/p&gt;

&lt;p&gt;No. Apple's processing takes 5 to 30 minutes. Nobody tells first-timers this. Half of them re-run &lt;code&gt;eas submit&lt;/code&gt; thinking they missed a step, which creates a duplicate build in ASC. Now they have two builds processing, and one will probably fail with &lt;code&gt;ITMS-90478: Invalid Version&lt;/code&gt;, because the second submission carries the same build number.&lt;/p&gt;

&lt;p&gt;The fix is small but it works: tell people to keep the ASC &lt;strong&gt;Activity&lt;/strong&gt; tab open in a browser, not the TestFlight tab. Activity shows the "Processing" state immediately. TestFlight only shows the build after processing completes. Different tab, different truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three onboarding fixes that cut time-to-first-tester from 3 days to 90 minutes
&lt;/h2&gt;

&lt;p&gt;After watching people stall in the same spots, here's what actually helped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 1: a pre-flight checklist that runs before their first &lt;code&gt;eas build&lt;/code&gt;.&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;[ ] Apple Developer account paid ($99/yr, not the free tier)
[ ] Apple ID for App Store Connect access confirmed (may differ from dev email)
[ ] App identifier registered in Certificates, Identifiers &amp;amp; Profiles
[ ] App created in App Store Connect (Name + Bundle ID + SKU)
[ ] TestFlight testers' Apple IDs collected (not phone numbers, not work emails: Apple IDs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last one alone saves a day. Testers don't know what their Apple ID is. Half of them think it's their Gmail. It's actually their iCloud address from 2011. Get this list before you submit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 2: the ITMS decoder ring.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every first-timer hits at least one of these. Print it, tape it to the monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ITMS-90163: Invalid Code Signing&lt;/code&gt; → provisioning profile expired or doesn't match your bundle ID. Regenerate via &lt;code&gt;eas credentials&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ITMS-90478: Invalid Version&lt;/code&gt; → build number collision. Bump &lt;code&gt;ios.buildNumber&lt;/code&gt; in &lt;code&gt;app.json&lt;/code&gt;, or set &lt;code&gt;"appVersionSource": "remote"&lt;/code&gt; and let EAS manage it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ITMS-91053: Missing API declaration&lt;/code&gt; → the Privacy Manifest requirement (iOS 17+). Add the relevant &lt;code&gt;NSPrivacyAccessedAPICategory&lt;/code&gt; keys to a &lt;code&gt;PrivacyInfo.xcprivacy&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ITMS-90062: Bundle version must be a higher number&lt;/code&gt; → same as 90478, more polite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you'd rather not memorize any of these, &lt;a href="https://letsdeploy.it/?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testflight-onboarding" rel="noopener noreferrer"&gt;letsdeploy.it&lt;/a&gt; exists specifically to catch them before you hit submit. But you'll still hit one once, and the decoder ring turns "3 days stuck" into "20 minutes annoyed."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 3: a live TestFlight walkthrough with the tester on a call.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sounds like overkill. It isn't. Testers themselves get stuck: they don't have the TestFlight app installed, they click the invite link on desktop instead of phone, or they "already have an account" and get lost in the redemption-code flow. The first tester gets a 15-minute call with you. Every tester after that gets a Loom of that call. Time saved: enormous.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the community keeps getting wrong in tutorials
&lt;/h2&gt;

&lt;p&gt;After 14 rounds of this, three tutorial-flavored misconceptions worth killing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. "You need Xcode installed to use TestFlight." You don't.&lt;/strong&gt; You need Xcode when signing goes wrong and you want to inspect a &lt;code&gt;.mobileprovision&lt;/code&gt; file by hand. For the happy path, &lt;code&gt;eas build &amp;amp;&amp;amp; eas submit&lt;/code&gt; is enough. Half the people I onboarded were on Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Internal testing is instant, external needs review." Half true.&lt;/strong&gt; Internal testing (up to 100 people, added as users in ASC) is fast: the build appears within an hour of processing. External testing (up to 10,000 people, invited by email) needs Beta App Review, which averages 24 hours but has spiked to 5 days when a new iOS version drops. Don't promise external testers same-day access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. "You can hot-swap builds and testers stay in sync." No.&lt;/strong&gt; When you push build 42, testers on build 41 don't auto-update. They get a badge in TestFlight and have to open the app there. If you want them on the new build, tell them explicitly, in whatever channel they actually read (spoiler: not email).&lt;/p&gt;




&lt;p&gt;The deeper thing I keep noticing: EAS itself is fine. The docs are fine. The gap is the roughly eight concepts between "I wrote code" and "my friend can install it," and none of them are in the EAS docs, because they aren't EAS's problem. They're Apple's ecosystem.&lt;/p&gt;

&lt;p&gt;If you're building anything in this space, the empathy exercise is simple: watch one first-timer, silently, for 90 minutes. You'll ship better onboarding by Tuesday.&lt;/p&gt;

&lt;p&gt;What was your first TestFlight wall? Mine was waiting 25 minutes on an empty TestFlight tab, convinced I'd broken something.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>expo</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How to Vibe-Check an AI-Generated React Native Codebase Before You Ship</title>
      <dc:creator>Melroy D Souza</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:46:14 +0000</pubDate>
      <link>https://dev.to/russel_melroydsouza_afb/how-to-vibe-check-an-ai-generated-react-native-codebase-before-you-ship-1j53</link>
      <guid>https://dev.to/russel_melroydsouza_afb/how-to-vibe-check-an-ai-generated-react-native-codebase-before-you-ship-1j53</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Three AI failure modes no test catches: &lt;strong&gt;duplication instead of reuse&lt;/strong&gt;, &lt;strong&gt;style drift&lt;/strong&gt;, and &lt;strong&gt;tests that mock the hard part&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A 20-minute review pass: find what should have been reused (3 min), read the tests and ignore the impl (7 min), run it on a device (5 min), ask the "six months from now" question (5 min).&lt;/li&gt;
&lt;li&gt;The bar for AI-generated code should be &lt;strong&gt;higher&lt;/strong&gt; than for human code — a human is committing their reputation to what they wrote. The AI isn't.&lt;/li&gt;
&lt;li&gt;Rewrite when the pattern would set a precedent. Accept when the failure is small and isolated.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Claude Code will produce a working React Native feature in 20 minutes that would have taken you four hours. Tests pass. Typecheck passes. You ship it.&lt;/p&gt;

&lt;p&gt;Six weeks later you're wondering why the codebase feels harder to work in than it should.&lt;/p&gt;

&lt;p&gt;What happened: the AI made choices that were &lt;strong&gt;locally correct and globally corrosive&lt;/strong&gt;, and no automated check caught them.&lt;/p&gt;

&lt;p&gt;Here's how to catch them yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three failure modes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Duplication instead of reuse.&lt;/strong&gt; The AI didn't know &lt;code&gt;useUser()&lt;/code&gt; existed, so it wrote its own version. Or it wrote three functions that all normalise a phone number, none of them quite the same.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Style drift.&lt;/strong&gt; Your codebase uses styled-components. The AI generated a screen with inline &lt;code&gt;StyleSheet.create&lt;/code&gt; because that's more common in its training data. Both work. Now your codebase has two styling systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Test-driven wishful thinking.&lt;/strong&gt; The AI wrote a test that mocks the tricky part. Test passes. The tricky part still doesn't work in production.&lt;/p&gt;

&lt;p&gt;None of these are caught by tests, typecheck, or linting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 20-minute review pass
&lt;/h2&gt;

&lt;p&gt;For every AI-generated PR:&lt;/p&gt;

&lt;h3&gt;
  
  
  Minutes 1–3: Find the smallest new thing that should have been reused
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Search the codebase for the function name. If two exist, decide which one stays.&lt;/li&gt;
&lt;li&gt;Check the imports. Did the AI pull in a new library when an existing one would work?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minutes 4–10: Read the tests, ignore the implementation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What are the assertions actually checking — the important behaviour, or the easy behaviour?&lt;/li&gt;
&lt;li&gt;Are the mocks hiding the hard part?&lt;/li&gt;
&lt;li&gt;Would this test still pass if the implementation was &lt;code&gt;return true&lt;/code&gt; for the happy path?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minutes 11–15: Run the feature end-to-end on a device
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Don't trust "tests pass." Open the app and do the flow.&lt;/li&gt;
&lt;li&gt;Empty state? Error state? Slow network?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minutes 16–20: The "six months from now" question
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If someone joined the team in six months, would they know why this exists?&lt;/li&gt;
&lt;li&gt;Will the naming still make sense when the product has changed?&lt;/li&gt;
&lt;li&gt;Would you be embarrassed if this was on your GitHub?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reject the PR if any of the above smells. The AI can rewrite it in five minutes; you save yourself weeks of drag.&lt;/p&gt;

&lt;h2&gt;
  
  
  What good AI-generated code looks like
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reuses existing helpers instead of inventing new ones.&lt;/li&gt;
&lt;li&gt;Follows existing patterns — styling, error handling, state management — without being told to.&lt;/li&gt;
&lt;li&gt;Tests assert on user-visible behaviour, not implementation details.&lt;/li&gt;
&lt;li&gt;Function and variable names match the codebase's conventions.&lt;/li&gt;
&lt;li&gt;Comments explain &lt;strong&gt;why&lt;/strong&gt;, not &lt;strong&gt;what&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your &lt;code&gt;CLAUDE.md&lt;/code&gt; is doing its job, most of these are automatic. If it isn't, you'll see the failure modes above in every PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to accept vs. rewrite
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Accept when:&lt;/strong&gt; the failure is small (one duplicate helper), the risk is low (isolated feature), and the fix cost is high (refactoring would take longer than the value it returns).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rewrite when:&lt;/strong&gt; the pattern would set a precedent (the next five features would follow it), the risk is high (it touches shared code), or the code just feels &lt;em&gt;foreign&lt;/em&gt; in the codebase.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The bar for AI-generated code should be higher than for human-generated code, not lower. A human is committing their reputation to what they wrote. The AI isn't.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setting up guardrails past one dev
&lt;/h2&gt;

&lt;p&gt;If you're on a team using AI heavily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Require a &lt;code&gt;CLAUDE.md&lt;/code&gt; in every repo.&lt;/strong&gt; Update it every time you catch the AI going in a wrong direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shift the code review focus.&lt;/strong&gt; Human reviewers should focus on the failure modes above, not on "does this work" — the AI will make it work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a weekly AI code-quality review.&lt;/strong&gt; Grep for patterns the AI introduced, refactor duplicates, and update &lt;code&gt;CLAUDE.md&lt;/code&gt; so the next PRs don't repeat them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;AI code that you don't review will make your codebase worse over time. AI code that you review carefully will make you 3× faster without the tax.&lt;/p&gt;

&lt;p&gt;The difference is entirely in your review discipline.&lt;/p&gt;




&lt;p&gt;One thing that reduces the failure modes at the source: pointing the agent at a codebase that already has conventions rather than an empty folder. &lt;a href="https://www.applighter.com/?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=vibe-check-ai-code" rel="noopener noreferrer"&gt;Applighter&lt;/a&gt; ships Expo + Supabase templates with the patterns and agent docs already in place, so there's less for the AI to invent.&lt;/p&gt;

&lt;p&gt;What's the worst thing an AI has quietly done to your codebase? Mine wrote a third phone-number formatter.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>ai</category>
      <category>codequality</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
