<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Fahad Allibdi on Medium]]></title>
        <description><![CDATA[Stories by Fahad Allibdi on Medium]]></description>
        <link>https://medium.com/@f13hd?source=rss-fb638fe8163c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*KOwN3h7Hl8qxoJ-Uhi-e5A.jpeg</url>
            <title>Stories by Fahad Allibdi on Medium</title>
            <link>https://medium.com/@f13hd?source=rss-fb638fe8163c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 01:19:46 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@f13hd/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[SEO Is Not Enough Anymore: What the LLM Era Demands from Your Web Frontend]]></title>
            <link>https://medium.com/@f13hd/seo-is-not-enough-anymore-what-the-llm-era-demands-from-your-web-frontend-c073c43c1063?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c073c43c1063</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[seo]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Thu, 14 May 2026 21:40:58 GMT</pubDate>
            <atom:updated>2026-05-14T21:40:58.601Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5bvrHYnBeWXR8btStzZszg.jpeg" /><figcaption><a href="https://www.goldcoastlogin.com.au/ai-crawlers-vs-search-crawlers">https://www.goldcoastlogin.com.au/ai-crawlers-vs-search-crawlers</a></figcaption></figure><h3>SEO Is Not Enough Anymore: What the LLM Era Demands from Your Frontend</h3><p>A few months ago, we started noticing something frustrating.</p><p>Our frontend looked good. The product was solid. Pages were indexed. Metadata existed. But organic visibility was inconsistent, and crawler behavior was unreliable.</p><p>The platform was originally built with ReactJS as a client-side app.</p><p>For users, everything worked.</p><p>For crawlers, not really.</p><p>Some pages loaded as nearly empty HTML shells before hydration. Important content only appeared after JavaScript executed. Structured data was inconsistent. Arabic and English pages sometimes confused crawlers.</p><p>Google could eventually figure some of it out.</p><p>LLM crawlers struggled much more.</p><p>That was the turning point.</p><p>We stopped thinking only about SEO and started thinking about machine readability.</p><p>So we migrated the frontend to Next.js 16 using the App Router and rebuilt the platform around server rendering.</p><p>At first, the goal was simple:</p><ul><li>better indexing</li><li>faster rendering</li><li>cleaner metadata</li><li>proper multilingual support</li></ul><p>But during the migration, we realized the real challenge wasn’t Google anymore.</p><p>It was AI crawlers.</p><h3>The Old SEO Checklist Wasn’t Enough</h3><p>Initially, we felt confident about the migration.</p><p>We had:</p><ul><li>generateMetadata on routes</li><li>canonical URLs</li><li>OpenGraph tags</li><li>Twitter cards</li><li>XML sitemaps</li><li>hreflang support for Arabic and English</li><li>server-rendered page shells</li></ul><p>A few years ago, that would’ve been considered a strong SEO setup.</p><p>But when we started auditing the platform for LLM crawler readiness, an entirely different checklist appeared.</p><p>And honestly, most React frontends are not prepared for it.</p><h3>The First Big Problem: Crawlers Don’t Behave Like Browsers</h3><p>One of the biggest lessons from the migration was simple:</p><p>Just because users can see content doesn’t mean crawlers can.</p><p>In React SPA architectures, it’s very easy to accidentally ship empty HTML.</p><p>We found patterns like this during the audit:</p><pre>const Page = dynamic(() =&gt; import(&#39;./Page&#39;), {<br>  ssr: false,<br>})</pre><p>For the browser, that’s fine.</p><p>For AI crawlers, it’s dangerous.</p><p>Many crawlers don’t fully execute JavaScript.</p><p>So instead of seeing:</p><ul><li>products</li><li>articles</li><li>supplier data</li><li>page structure</li></ul><p>They only see a hydration container.</p><p>That completely changes how you architect a frontend.</p><p>After migrating to Next.js, we kept all important page content server-rendered and isolated client-side rendering only to interactive sections.</p><p>Something closer to this:</p><pre>export default async function ProductPage() {<br>  const product = await getProduct()<br>  <br>  return (<br>      &lt;&gt;<br>        &lt;ProductSchema data={product} /&gt;<br>        &lt;ProductContent data={product} /&gt;<br>        &lt;InteractiveGallery data={product} /&gt;<br>      &lt;/&gt;<br>    )<br>}</pre><p>That one shift made crawler-visible HTML dramatically better.</p><h3>Then Came the LLM-Specific Layer</h3><p>This is where the migration started feeling less like SEO work and more like infrastructure work.</p><p>Traditional SEO mainly optimizes for ranking.</p><p>LLM systems optimize for understanding.</p><p>They’re trying to answer questions like:</p><ul><li>What company is this?</li><li>Is this source trustworthy?</li><li>What type of content is this?</li><li>Which language version should be referenced?</li><li>Can this content be summarized confidently?</li></ul><p>That requires more explicit structure from the frontend.</p><p>During the audit, we grouped the work into three layers.</p><h3>1. Discoverability</h3><p>The first layer was making the platform discoverable to AI crawlers.</p><p>We added an llms.txt file describing:</p><ul><li>what the platform does</li><li>supported languages</li><li>important sections</li><li>canonical domain references</li><li>sitemap references</li></ul><p>We also updated robots.txt with explicit rules for AI crawlers instead of relying only on:</p><pre>User-agent: *</pre><p>The final setup included named user-agents like:</p><ul><li>GPTBot</li><li>ChatGPT-User</li><li>ClaudeBot</li><li>PerplexityBot</li><li>Google-Extended</li><li>CCBot</li><li>cohere-ai</li><li>Bytespider</li></ul><p>This matters because AI systems increasingly have different crawling and retrieval behavior than traditional search engines.</p><h3>2. Identity and Structured Understanding</h3><p>The second layer was structured identity.</p><p>Not just metadata for search engines, but machine-readable context for language models.</p><p>We implemented server-rendered JSON-LD across the platform using schema types such as:</p><ul><li>Organization</li><li>WebSite</li><li>Product</li><li>ItemList</li><li>Article</li><li>FAQPage</li><li>CollectionPage</li></ul><p>The Organization schema became especially important.</p><p>We included:</p><ul><li>knowsAbout</li><li>areaServed</li><li>sameAs</li><li>contactPoint</li></ul><p>This gives AI systems a clearer understanding of:</p><ul><li>what the company does</li><li>which industry it belongs to</li><li>which region it serves</li><li>whether the source is authoritative</li></ul><p>We also implemented SearchAction under the WebSite schema.</p><p>This helps crawlers and AI systems understand how site-level search works and how content can be queried internally.</p><p>Example:</p><pre>{<br>  &quot;@type&quot;: &quot;SearchAction&quot;,<br>  &quot;target&quot;: &quot;https://example.com/search?q={search_term_string}&quot;<br>}</pre><p>The important part is that these schemas were rendered server-side and embedded directly in the HTML.</p><p>Not injected after hydration.</p><h3>3. Language and Regional Clarity</h3><p>The platform was Arabic-first, which added another layer of complexity.</p><p>We had to make multilingual intent explicit across the frontend.</p><p>That included:</p><ul><li>hreflang support</li><li>lang=&quot;ar&quot;</li><li>dir=&quot;rtl&quot;</li><li>inLanguage in JSON-LD</li><li>aligned canonical URLs between language variants</li></ul><p>Example:</p><pre>&lt;html lang=&quot;ar&quot; dir=&quot;rtl&quot;&gt;</pre><p>And:</p><pre>{<br>  &quot;@type&quot;: &quot;Article&quot;,<br>  &quot;inLanguage&quot;: &quot;ar-SA&quot;<br>}</pre><p>Without this level of clarity, AI systems can:</p><ul><li>reference the wrong language version</li><li>summarize English content for Arabic prompts</li><li>confuse regional variants</li><li>misclassify translated pages</li></ul><p>This becomes especially important for Arabic-first products because many global AI systems still default toward English assumptions.</p><h3>The Small Details That Matter More Now</h3><p>One surprising thing during the audit was how many silent problems existed.</p><p>For example, our SearchAction schema pointed to /search.</p><p>The route didn’t exist.</p><p>Humans would never notice.</p><p>But for crawlers, that’s a trust issue.</p><p>We also found:</p><ul><li>inconsistent domains between sitemap and metadata</li><li>pages missing schema types</li><li>metadata rendered client-side</li><li>routes with weak server-rendered content</li></ul><p>Traditional SEO tools don’t always catch these problems clearly.</p><p>LLM systems expose them fast.</p><h3>The Unexpected Result</h3><p>After the migration and cleanup work, we started monitoring traffic patterns closely.</p><blockquote><strong>What surprised us most wasn’t Google.</strong></blockquote><blockquote><strong>It was referral traffic from AI systems.</strong></blockquote><p>Based on GA tracking, some of the fastest-growing discovery sources became:</p><ul><li>ChatGPT</li><li>Gemini</li><li>Perplexity</li></ul><p>Not because we gamed anything.</p><p>Simply because the frontend became easier for machines to understand.</p><p>That’s the part many teams still miss.</p><p>The frontend is no longer just a UI layer.</p><p>It’s becoming a machine-readable interface.</p><p>And in practice, that means:</p><ul><li>server-rendered content matters again</li><li>structured data matters more</li><li>multilingual clarity matters more</li><li>crawler accessibility matters more</li><li>semantic consistency matters more</li></ul><p>SEO is still important.</p><p>But ranking is no longer the only outcome that matters.</p><p>Now the question is:</p><p><strong>Can machines understand your platform well enough to trust, summarize, and recommend it?</strong></p><p>Because increasingly, that’s where discovery starts.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c073c43c1063" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Smarter Types with Less Code: A Better Way to Use Prisma in TypeScript]]></title>
            <link>https://medium.com/@f13hd/smarter-types-with-less-code-a-better-way-to-use-prisma-in-typescript-303ed9faea7b?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/303ed9faea7b</guid>
            <category><![CDATA[prisma]]></category>
            <category><![CDATA[datatypes-in-javascript]]></category>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Sun, 20 Jul 2025 15:31:49 GMT</pubDate>
            <atom:updated>2025-07-20T15:31:49.078Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7FF6UJc4XY8koM24ScBbAg.png" /></figure><p>You write TypeScript with Prisma, but your code is full of as unknown casts and custom types like UserDTO, MaybeUser, etc. You maintain duplicate type definitions that don’t match your DB. Type errors pop up randomly. Your team is confused. Sound familiar?</p><p>You’re not alone. Let’s fix this.</p><h3>Why Custom Types Fail</h3><p>Many teams create custom types that mirror Prisma models to feel in control — until it backfires:</p><ul><li><strong>Drift</strong>: Your types no longer match the database.</li><li><strong>Casts everywhere</strong>: as unknown Hides real bugs.</li><li><strong>Extra work</strong>: Every schema change breaks your custom types.</li><li><strong>IntelliSense fails</strong>: You lose all TypeScript benefits.</li></ul><p><strong>Example mess:</strong></p><pre>type PublicUser = {<br>  id: number;<br>  email: string;<br>  posts: PostSummary[];<br>};<br><br>return user as unknown as PublicUser;</pre><p>You’re forcing types, not matching them.</p><h3>The Better Way: Prisma‑First Types</h3><h3>1. Use Prisma.XxxGetPayload&lt;&gt;</h3><p>Let Prisma tell TypeScript exactly what shape your data has:</p><pre>type UserWithPosts = Prisma.UserGetPayload&lt;{<br>  include: { posts: true }<br>}&gt;;</pre><h3>2. Omit or pick, don’t recreate</h3><p>Want a public version?</p><pre>type PublicUser = Omit&lt;UserWithPosts, &#39;password&#39;&gt;;</pre><h3>3. Centralized selects</h3><p>Define reusable selects:</p><pre>export const publicUserSelect = {<br>  id: true,<br>  email: true,<br>  posts: { select: { id: true, title: true } }<br>} satisfies Prisma.UserSelect;<br><br>type PublicUser = Prisma.UserGetPayload&lt;{ <br>   select: typeof publicUserSelect <br>}&gt;;</pre><p>Use this everywhere — handlers, services, validation schemas.</p><h3>Easy Refactor Steps</h3><ol><li><strong>Find</strong> your custom types that mirror Prisma models.</li><li><strong>Identify</strong> common query patterns and relations.</li><li><strong>Extract</strong> shared select/include objects.</li><li><strong>Switch</strong> to GetPayload&lt;&gt; types.</li><li><strong>Replace</strong> as unknown as with real typed queries.</li><li><strong>Align</strong> your validation schemas (e.g. Zod) with new types.</li></ol><h3>Before vs After</h3><p><strong>Before:</strong></p><pre>user as unknown as PublicUser;</pre><p><strong>After:</strong></p><pre>const publicUserSelect = { … };<br><br>type PublicUser = Prisma.UserGetPayload&lt;{ <br>select: typeof publicUserSelect }<br>&gt;;<br><br>const user = await prisma.user.findUnique({<br>  where: { id },<br>  select: publicUserSelect<br>});<br>return user;</pre><p>✅ No casting. ✅ Real type safety.</p><h3>Benefits You’ll See</h3><ul><li>50–70% fewer type definitions</li><li>No more as unknown hacks</li><li>Types auto-sync when schema changes</li><li>Better IntelliSense and error checking</li><li>Easier onboarding — types guide devs naturally</li></ul><h3>In Summary</h3><p>Prisma’s auto-generated types are your friend. Don’t fight them — build on top of them. Your code becomes cleaner, safer, and easier to maintain. TypeScript finally becomes helpful again.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=303ed9faea7b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Promise.allSettled Makes Your Admin Dashboard Faster and More Resilient]]></title>
            <link>https://medium.com/@f13hd/how-promise-allsettled-makes-your-admin-dashboard-faster-and-more-resilient-88a7bf696a5c?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/88a7bf696a5c</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[promises-in-javascript]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Sun, 29 Jun 2025 22:54:41 GMT</pubDate>
            <atom:updated>2025-06-29T22:54:41.754Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2H-W6BxRNbV-d53LREWlMg.png" /></figure><p>If you’re building an admin dashboard with real-time data from multiple APIs, there’s a good chance you’re juggling several asynchronous calls at once. That’s where Promise.allSettled comes in. It’s a powerful tool that lets you run multiple operations in parallel—<em>without breaking if one fails</em>.</p><p>Let’s break down how it works, using a real example from your dashboard code.</p><h3>What Is Promise.allSettled?</h3><p>Promise.allSettled is a JavaScript method that takes an array of promises and waits for <strong>all of them to finish, </strong>no matter if they succeed or fail.</p><p>Unlike Promise.all, which throws an error if <em>any</em> promise fails, Promise.allSettled Let you inspect the outcome of <em>each</em> operation individually.</p><h3>Here’s How You’re Using It</h3><pre>const [productsResponse, categoriesResponse] = await Promise.allSettled([<br>  AdminProductService.getProducts({ page: 1, page_size: 1 }),<br>  AdminCategoryService.getCategories(),<br>]);</pre><p>This line fires off two API calls in parallel:</p><ul><li>One to fetch products</li><li>One to fetch categories</li></ul><p>No waiting around. No try/catch blocks. No crashing if one fails.</p><h3>⚙️ Why This Is Smart</h3><h3>1. Parallel Execution</h3><p>You’re loading data faster by running both APIs at the same time.</p><pre>// Sequential — slower<br>const products = await AdminProductService.getProducts();<br>const categories = await AdminCategoryService.getCategories();</pre><pre>// Parallel — faster<br>const [productsResponse, categoriesResponse] = await Promise.allSettled([<br>  AdminProductService.getProducts(),<br>  AdminCategoryService.getCategories(),<br>]);</pre><p>If each call takes 200ms, parallel execution saves you 200ms of waiting time. In a dashboard, that’s noticeable.</p><h3>2. Never Rejects</h3><p>Even if one of the promises fails, your code doesn’t crash. Promise.allSettled returns an array where each item tells you whether it <strong>fulfilled</strong> or <strong>rejected</strong>.</p><pre>{<br>  status: &#39;fulfilled&#39;,<br>  value: { /* API response */ }<br>}</pre><pre>{<br>  status: &#39;rejected&#39;,<br>  reason: Error(&#39;Something went wrong&#39;)<br>}</pre><p>You can now write logic to handle each result, fallback gracefully, and keep the UI running smoothly.</p><h3>3. Safe Result Handling</h3><p>In your code, you’re handling potential failures like this:</p><pre>setStats({<br>  totalProducts:<br>    productsResponse.status === &#39;fulfilled&#39;<br>      ? productsResponse.value.total_count || 0<br>      : 0,<br>  totalCategories:<br>    categoriesResponse.status === &#39;fulfilled&#39;<br>      ? categoriesResponse.value.total_count || 0<br>      : 0,<br>});</pre><p>This ensures your dashboard never breaks — even if one of the APIs fails. You just show a fallback value (0), and the rest of the data still loads.</p><h3>🆚 Promise.all vs Promise.allSettled</h3><p>Here’s what happens if you use Promise.all instead:</p><pre>try {<br>  const [products, categories] = await Promise.all([<br>    AdminProductService.getProducts(), // ✅<br>    AdminCategoryService.getCategories(), // ❌<br>  ]);<br>} catch (error) {<br>  // Whole operation fails — even the successful data is lost<br>}</pre><p>With Promise.allSettled, it looks like this:</p><pre>const [productsResponse, categoriesResponse] = await Promise.allSettled([<br>  AdminProductService.getProducts(), // ✅<br>  AdminCategoryService.getCategories(), // ❌<br>]);</pre><pre>const productCount = productsResponse.status === &#39;fulfilled&#39; <br>  ? productsResponse.value.total_count <br>  : 0;</pre><p>You still get the good data and skip the broken stuff.</p><h3>✅ Why This Matters in Real Dashboards</h3><p>Imagine this scenario:</p><ul><li>Products API: ✅ Returns 50 products</li><li>Categories API: ❌ Times out</li></ul><p>With Promise.allSettled, your dashboard still shows:</p><blockquote><strong><em>“50 Products, 0 Categories”</em></strong></blockquote><p>That’s way better than an error message — or worse, a blank screen.</p><h3>💡 Takeaways</h3><p>Using Promise.allSettled in your admin dashboard helps you:</p><ol><li><strong>Avoid full crashes</strong> when one API fails</li><li><strong>Load data faster</strong> by running calls in parallel</li><li><strong>Handle partial failures</strong> without confusing your users</li><li><strong>Build resilient, user-friendly UIs</strong></li></ol><p>It’s a small change in your async strategy, but it makes a big difference in user experience.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=88a7bf696a5c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Your Code Works on macOS but Breaks on Linux: Case Sensitivity in File Imports]]></title>
            <link>https://medium.com/@f13hd/why-your-code-works-on-macos-but-breaks-on-linux-case-sensitivity-in-file-imports-cbbf8d1b7978?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/cbbf8d1b7978</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[linux]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Thu, 26 Jun 2025 22:21:51 GMT</pubDate>
            <atom:updated>2025-06-26T22:21:51.567Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mAuuVd8-h2Bm9MxM-sgXVw.png" /></figure><p>If you’re a software engineer who codes on macOS and deploys to Linux, you’ve probably hit this bug at least once:<br> Your app works perfectly on your machine, but the moment it hits the server, it crashes with a MODULE_NOT_FOUND or similar error.</p><p>Most of the time, the culprit is simple but sneaky: <strong>case-sensitive file imports.</strong></p><h3>⚠️ The Hidden Difference: File System Case Sensitivity</h3><p>The root of this issue comes from a key difference in how macOS and Linux handle file names:</p><p>OS File System Case Sensitivity <strong>macOS</strong> Case-insensitive (by default) <strong>Linux</strong> Case-sensitive</p><p>In plain terms, this means:</p><ul><li>On <strong>macOS</strong>, Navbar.js, navbar.js, and NAVBAR.js are all treated as the same file.</li><li>On <strong>Linux</strong>, those are <strong>three completely different files</strong>.</li></ul><h3>🧨 Real Example: It Works on Mac, Fails on Linux</h3><p>Let’s say you have a component saved as:</p><pre>src/components/NavBar.js</pre><p>But somewhere in your code, you import it like this:</p><pre>import Navbar from &#39;./components/navbar.js&#39;;</pre><p><strong>macOS lets this slide.</strong> It finds the file despite the wrong casing.</p><p><strong>Linux does not.</strong> It throws a file not found error and crashes your build or server.</p><h3>😵 Why This Happens So Often</h3><p>Because most engineers use macOS for local development, the OS silently corrects casing mistakes. Everything seems fine… until you deploy to a Linux server or run CI in a Linux container.</p><p>This disconnect can be frustrating — especially when bugs only surface in production.</p><h3>🛡️ How to Avoid Case-Related Import Bugs</h3><p>Here’s how to protect yourself and your team from falling into this trap:</p><h3>✅ 1. Use a Linter That Flags Case Mismatches</h3><p><strong>ESLint</strong> with eslint-plugin-import can catch incorrect import casing during development.</p><p><strong>Setup:</strong></p><p>Install the plugin:</p><pre>npm install eslint-plugin-import --save-dev</pre><p>Update your .eslintrc.js:</p><pre>module.exports = {<br>  plugins: [&#39;import&#39;],<br>  rules: {<br>    &#39;import/no-unresolved&#39;: &#39;error&#39;,<br>  },<br>  settings: {<br>    &#39;import/resolver&#39;: {<br>      node: {<br>        extensions: [&#39;.js&#39;, &#39;.jsx&#39;, &#39;.ts&#39;, &#39;.tsx&#39;],<br>      },<br>    },<br>  },<br>};</pre><p>This will throw an error if an import path doesn’t match the actual file name — including case mismatches.</p><h3>✅ 2. Use Webpack’s Case Sensitive Paths Plugin</h3><p>If you’re using Webpack, add this plugin to enforce case accuracy at build time.</p><p><strong>Setup:</strong></p><p>Install the plugin:</p><pre>npm install case-sensitive-paths-webpack-plugin --save-dev</pre><p>Update your webpack.config.js:</p><pre>const CaseSensitivePathsPlugin = require(&#39;case-sensitive-paths-webpack-plugin&#39;);</pre><pre>module.exports = {<br>  // other config...<br>  plugins: [new CaseSensitivePathsPlugin()],<br>};</pre><p>Now, any mis-cased import will fail the build with a clear, actionable error.</p><h3>✅ 3. Develop on a Case-Sensitive Volume on macOS</h3><p>To simulate Linux’s case-sensitive behavior locally, create a case-sensitive disk image on macOS:</p><pre>hdiutil create -size 10g -fs &quot;Case-sensitive APFS&quot; -volname DevVolume ~/Desktop/CaseSensitiveDev.dmg</pre><p>Mount the image, move your project into it, and develop as if you were on Linux. This forces macOS to respect casing and catch mistakes early.</p><h3>✅ 4. Make Your CI Linux-Based</h3><p>Always run your continuous integration (CI) pipeline in a Linux environment. This ensures any case mismatch or filesystem-sensitive bug surfaces before hitting production.</p><p>Popular CI services like GitHub Actions, CircleCI, and GitLab CI all support Linux runners by default.</p><h3>💡 Pro Tips</h3><ul><li>Stick to a consistent naming convention (e.g., camelCase, PascalCase, or kebab-case) and enforce it across your codebase.</li><li>Add file naming rules to your linter or commit hooks using tools like <a href="https://typicode.github.io/husky">Husky</a> and <a href="https://github.com/okonet/lint-staged">lint-staged</a>.</li><li>If you’re using TypeScript, enable forceConsistentCasingInFileNames in your tsconfig.json.</li></ul><pre>{<br>  &quot;compilerOptions&quot;: {<br>    &quot;forceConsistentCasingInFileNames&quot;: true<br>  }<br>}</pre><h3>Final Word</h3><p>“Works on my machine” isn’t good enough when your machine hides bugs.<br> <strong>Case-sensitive file imports</strong> are an easy mistake, and one of the most common causes of failed Linux deployments from macOS.</p><p>Don’t leave it to chance. Lint it. Build it. Test it like it’s already in production.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cbbf8d1b7978" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting up SSH authentication for GitHub]]></title>
            <link>https://medium.com/@f13hd/setting-up-ssh-authentication-for-github-41119d537342?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/41119d537342</guid>
            <category><![CDATA[ssh]]></category>
            <category><![CDATA[github]]></category>
            <category><![CDATA[ssh-keys]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Mon, 19 Feb 2024 21:04:53 GMT</pubDate>
            <atom:updated>2024-02-19T21:05:50.351Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Generated By DALL·E" src="https://cdn-images-1.medium.com/max/1024/1*8tDjtsr-maGzHl5XPY7s6g.jpeg" /></figure><p>in this article, we are setting up an SSH connection instead of a direct GitHub repo URL.<br>So, here’s the steps below to resolve the issue:<br>open your terminal and run:</p><pre>ssh-keygen -R github.com</pre><blockquote>This command is for updating known_hosts that saved in .ssh folder.</blockquote><p><a href="https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/">read more about github.com hosts</a></p><p>after updating hosts, we are ready to create our SSH key for GitHub authentication,</p><p>run the following command to generate public/private keys</p><pre>ssh-keygen -o -t rsa -C “&lt;your-email-in-github-account&gt;”</pre><p>after running the command, you will notice passphrase prompts in the terminal.</p><p>you can either click enter as the default value will be chosen which means no password or write your password.</p><p>the terminal will display public/private file locations.</p><p>Good job, remain two steps,</p><p>1- copy the public key by running this command</p><pre>cat &lt;your-public-key-location&gt;</pre><p>** public key with extension .pub</p><p>** public key location: `/Users/&lt;username&gt;/.ssh/id_rsa.pub`</p><p>2- copy the printed text and open your GitHub account to create a new SSH key, you can click here to <a href="https://github.com/settings/keys">github settings</a> directly</p><p>add whatever name and paste the copied string.</p><p>now go back to the terminal with the project path and run the install dependencies command, will go with a flutter command</p><pre>flutter pub get</pre><p>Now, the private repos deps should start installing smoothly.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=41119d537342" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why I Chose JavaScript: My Path to Coding]]></title>
            <link>https://medium.com/@f13hd/why-i-chose-javascript-my-path-to-coding-1a4718c48d4a?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a4718c48d4a</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[nodejs]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Sun, 11 Feb 2024 16:32:58 GMT</pubDate>
            <atom:updated>2024-02-11T16:32:58.539Z</atom:updated>
            <content:encoded><![CDATA[<p>Starting a journey into coding is super exciting, but also a bit scary, right? It’s like stepping into a whole new world where you can create cool stuff, solve puzzles, and maybe even get a bit frustrated when things don’t work out the first time. But hey, that’s all part of the fun.</p><p>I picked JavaScript and Node.js to start with because they’re everywhere on the web. JavaScript lets you make websites interactive, and Node.js helps with server stuff, making sure everything runs smoothly on the back end.</p><p>Learning to code has its ups and downs. At first, it’s like learning a new language, trying to make sense of all these new words and rules. But the more you practice, the better you get. And building your own projects? That’s the best part. It’s where you get to put everything you’ve learned into action, make cool things, and see your ideas come to life.</p><p>One thing I didn’t expect was how awesome the coding community is. There are so many people out there ready to help, share their knowledge, and cheer you on. It makes the journey a lot less lonely and a lot more fun.</p><p>Looking ahead, I know there’s always going to be something new to learn, and that’s exciting. It means there’s always a way to get better, to create more amazing things, and to keep having fun with coding.</p><p>If you’re thinking about starting this journey, or if you’re already on your way, just keep going. Yes, it might be tough sometimes, but the feeling of solving a problem or finishing a project is unbeatable. Plus, you’re not alone. There’s a whole community here to support you.</p><p>So, let’s keep learning and coding together. Who knows what awesome things we’ll create?</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a4718c48d4a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Challenges of Starting as an Engineering Manager]]></title>
            <link>https://medium.com/@f13hd/the-challenges-of-starting-as-an-engineering-manager-c90c0fb308d9?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c90c0fb308d9</guid>
            <category><![CDATA[leadership]]></category>
            <category><![CDATA[engineering-manager]]></category>
            <category><![CDATA[technical-lead]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Tue, 10 Oct 2023 22:02:54 GMT</pubDate>
            <atom:updated>2023-10-10T22:02:54.435Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rvfoOxT3m8C-MzUk39EohQ.jpeg" /></figure><p>Transitioning into the role of an engineering manager can be a thrilling experience, filled with the promise of new responsibilities, leadership opportunities, and the chance to shape a dynamic team. However, this transition is not without its share of challenges. In this article, we’ll explore the journey of starting as an engineering manager and discuss the human aspect of these challenges, offering insight into how to navigate them with grace and wisdom.</p><p>1. The Transition Period:</p><p>One of the initial challenges an engineering manager faces is the transition from a technical expert to a leader. It’s like learning to play a completely new instrument while still being expected to perform a solo. This transformation requires a shift in mindset, from solving technical problems yourself to enabling your team to tackle them.</p><p>Embrace the learning curve, as it’s perfectly normal to feel overwhelmed initially. Don’t be too hard on yourself, and take time to grow into your role. Lean on your mentor or senior colleagues for guidance as you navigate this change.</p><p>2. Balancing Technical and Managerial Duties:</p><p>As an engineering manager, you’ll walk a fine line between your technical responsibilities and your managerial duties. You must remain engaged with the technical aspects of your projects while also managing your team, setting goals, and ensuring efficient project delivery.</p><p>A key to success is finding the right balance. Stay hands-on with technical work to some extent, but also trust your team members to take the lead on certain technical aspects. Delegation is your ally here, and it’s a skill worth honing.</p><p>3. People Management Challenges:</p><p>Engineering management is not just about managing projects; it’s primarily about managing people. This can be one of the most rewarding yet daunting aspects of the role.</p><p>Your team will comprise individuals with unique personalities, strengths, and weaknesses. You’ll encounter conflicts, differing opinions, and the occasional challenge in keeping everyone motivated. The key here is communication. Create an environment where open and honest dialogue is encouraged, and address issues as they arise.</p><p>4. Time Management:</p><p>An engineering manager’s schedule can be hectic, with meetings, project planning, and mentoring sessions competing for your time. Effective time management is crucial to avoid burnout.</p><p>Prioritize tasks, delegate when possible, and set boundaries. Remember that you can’t do everything yourself, and sometimes saying ‘no’ or ‘not now’ is the best decision for your well-being and your team’s success.</p><p>5. Staying Connected:</p><p>As you transition into a managerial role, don’t lose touch with the human side of your team. Stay connected with your team members on a personal level. Engage in one-on-one discussions, show empathy, and provide support when they need it. A little kindness can go a long way in fostering a strong and loyal team.</p><p>Conclusion:</p><p>Becoming an engineering manager is a rewarding journey, but it’s not without its challenges. Embrace the transition, strike a balance between technical and managerial duties, and remember that people management is the heart of your role. Effective time management and maintaining a personal connection with your team are equally important.</p><p>In your quest to overcome these challenges, keep in mind that you are not alone. Seek guidance from experienced mentors, learn from your experiences, and continue to grow as a compassionate and effective engineering manager. Embrace these challenges, and with time, you’ll find yourself leading a thriving and dynamic team with grace and wisdom.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c90c0fb308d9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ماذا عن Trigger في قاعدة البيانات؟]]></title>
            <link>https://medium.com/@f13hd/%D9%85%D8%A7%D8%B0%D8%A7-%D8%B9%D9%86-trigger-%D9%81%D9%8A-%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-8aeb38c2e08d?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8aeb38c2e08d</guid>
            <category><![CDATA[trigger]]></category>
            <category><![CDATA[bds]]></category>
            <category><![CDATA[قاعدة-بيانات]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Fri, 09 Sep 2016 17:48:56 GMT</pubDate>
            <atom:updated>2016-09-09T17:53:17.748Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/291/1*q1x27wcSM7gQTFM90U7oWg.jpeg" /></figure><p>قواعد البيانات كثيرة وباختلاف محركاتها وانواعها ودائما هي الركن الأساسي في الكثير من المشاريع التقنية وقوتها تعطي قوة للمشروع واستقراره.</p><p>ومع تطور قواعد البيانات لم تقتصر على عمليات (اضافة ، قراءة ، تحديث، حذف ).</p><p>يوجد الكثير من العمليات والوظائف functions التي تزودنا بها محركات قواعد البيانات وبالتالي تعطي اضافة مميزة للمطور ليستخدمها ويستفيد منها في مشروعه .</p><p>في هذه المقالة السريعة سوف نستعرض ابرز النقاط عن Trigger</p><p>من ابرز خصائصها انها تبدء بالتنفيذ عند حدوث Event محدد .</p><ul><li>before &amp; After insert data</li><li>before &amp; After delete data</li><li>before &amp; After update data</li></ul><p>عند عمل تريقر عند اي حدث من الاحداث السابقة . سوف ينفذ تلقائيا التريقر عند وقوع الحدث .</p><h4>بدون اي تدخل منك او استدعاء خارجي.</h4><p>الكثير من الفوائد للتريقر ومساهمتها في رفع سرعة اداء قاعدة البيانات خاصة بعد فترة من العمل ع المشروع وتخزين مئات الحقول .</p><p>هنا بعض الافكار لاستخدامها</p><ul><li>عمل function وجدولته أسبوعيا يقوم بنقل سجلات المتابعة وتفاصيلها الى جدول الارشيف لعدم احتياجه بعد مضي اسبوع .</li></ul><p>إضافة بيانات الى جدول التنبيهات (After insert ) بعد اضافة تعليق في جدول التعليقات على مقالة محددة .</p><blockquote>ملاحظة</blockquote><p>في بعض الحالات لا ينصح باستخدام التيرقر ويجب قراءة documentation الخاص بقاعدة بياناتك المستخدمة مثل :</p><p>عدم استخدام التريقر مع المفاتيح ذات صلة بجدول آخر Foreign keys لانها تمنع التعديل والحذف في بعض الحالات .</p><p>وبالتالي لا يستطيع التريقر من اداء مهمته على اكمل وجه.</p><p>حبيت ابرز بعض النقاط عن ما تقدمه قواعد البيانات غير الأمور التقليدية .</p><p>من حذف وإضافة وتعديل .</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8aeb38c2e08d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[نسبية صفات الانسان]]></title>
            <link>https://medium.com/@f13hd/%D8%BA%D8%A7%D9%84%D8%A8%D8%A7-%D9%85%D8%A7-%D9%86%D8%B3%D9%85%D8%B9-%D8%B9%D9%86-%D8%B4%D8%AE%D8%B5-%D9%85%D8%A7-%D9%8A%D8%AA%D8%AD%D8%AF%D8%AB-%D8%B9%D9%86-%D8%A7%D9%84%D8%B1%D8%A3%D9%8A-%D9%88%D8%A7%D9%84%D8%B1%D8%A3%D9%8A-%D8%A7%D9%84%D8%A2%D8%AE%D8%B1-%D9%88%D9%83%D9%8A%D9%81%D9%8A%D8%A9-%D8%AA%D9%82%D8%A8%D9%84%D9%87-%D8%A7%D9%8A%D8%B6%D8%A7-%D9%86%D8%B4%D8%A7%D9%87%D8%AF-%D8%A7%D9%84%D9%83%D8%AB%D9%8A%D8%B1-%D9%85%D9%86-%D8%A7%D9%84%D8%A7%D8%B4%D8%AE%D8%A7%D8%B5-%D9%84-7122f44cc7a0?source=rss-fb638fe8163c------2</link>
            <guid isPermaLink="false">https://medium.com/p/7122f44cc7a0</guid>
            <category><![CDATA[people]]></category>
            <category><![CDATA[human-rights]]></category>
            <dc:creator><![CDATA[Fahad Allibdi]]></dc:creator>
            <pubDate>Wed, 24 Aug 2016 11:52:36 GMT</pubDate>
            <atom:updated>2016-08-24T16:59:49.375Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/373/1*HBmAxxS_nDwU3EMGvS5lRA.jpeg" /></figure><p>نسبية صفات الانسان</p><p>غالبا ما نسمع عن شخص ما يتحدث عن الرأي والرأي الآخر وكيفية تقبله , ايضا نشاهد الكثير من الاشخاص لديهم صفات مشتركة وصفات خاصة وهذا ما يتميزون به عن غيرهم . عندما نحس بتعابير وكلام الشخص الذي نشاهده , فأكثر ما نردده من مقولات الا وهي ( هذا الانسان فيه من صفات فلان ) .. وغيرها من التعابير .</p><p>فلو لاحظنا بأن كل شخص يحتوي على صفات كثيرة جدا منها ما ذكره القرآن الكريم وهي 8 صفات وهي مشمولة بكل انسان (مجادل، ضعيف، شحيح، هلوع، عجول، كادح، جحود، طغيان) .</p><p>فمن وجهة نظري اعتقد ان الانسان يحتوي على كل الصفات البشرية من خير وشر ولكن بنسب متفاوتة من شخص لأخر .</p><p>فمثلا شخص تغلب صفاته الخيرة صفاته السيئة ولكن لا نعتقد انه لا توجد فيه صفات سيئة (0%) .</p><p>ولكنه غلبها بصفات خيرة وكذلك عند الاشخاص الآخرين . فلو أخذنا مفهوم نسب الصفات عند كل شخص</p><p>فان هذا يسهل علينا فهم طبيعة الانسان وطبيعة تصرفاته سواء انت او الآخرين . فلا نستغرب صفة سيئة بشخص مشهود له بالخير والعكس عند الشخص السيء لمن يسوي شيء فيه خير .</p><p>لانها في ذلك الموقف ارتفعت النسبة وغلبت الاخريات .</p><h4><strong>فيا ابن آدم اعمل على رفع نسبة الصفة التي ترغب ان تتصف بها والتي تقودك الى ما تطمح اليه .</strong></h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7122f44cc7a0" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>