<?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"><channel><title><![CDATA[Bahriddin's blog]]></title><description><![CDATA[I’m a senior software engineer focused on Ruby on Rails and React. I love building apps, exploring new tech, and playing table tennis. Outside work, I’m a fathe]]></description><link>https://blog.bahridd.in</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 16:10:07 GMT</lastBuildDate><atom:link href="https://blog.bahridd.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[AI Can Write Code. But Building Systems Is Still Human Work]]></title><description><![CDATA[The first time AI migrated a huge chunk of code between two repositories — perfectly, in one go – I panicked.
Years of experience, thousands of hours writing and debugging… suddenly it felt like a mac]]></description><link>https://blog.bahridd.in/ai-can-write-code-but-building-systems-is-still-human-work</link><guid isPermaLink="true">https://blog.bahridd.in/ai-can-write-code-but-building-systems-is-still-human-work</guid><dc:creator><![CDATA[Bahriddin Abdiev]]></dc:creator><pubDate>Wed, 11 Mar 2026 06:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/5fc087677f8d06480aa0eda7/fed8396e-7519-4715-b795-94f52ab12331.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The first time AI migrated a huge chunk of code between two repositories — perfectly, in one go – I panicked.</p>
<p>Years of experience, thousands of hours writing and debugging… suddenly it felt like a machine could replace me.</p>
<p>For a moment, I thought:<br /><em>“Am I still needed?”</em></p>
<p>I work in a small tech team. Just me on backend and web, our CTO mostly planning product strategy, and two Android engineers handling mobile apps and IoT devices. We don’t even have a dedicated DevOps engineer, yet we maintain <strong>dozens of services</strong>.</p>
<p>When Claude Code rewrote that migration task, I realized: AI can handle a lot of work I used to do – but it <strong>doesn’t replace the human judgment</strong> needed to make it work in a real business.</p>
<p>Here’s what I discovered after experimenting:</p>
<ol>
<li><p><strong>Delegation, not replacement</strong><br />I started giving AI bigger tasks: entire features, repository migrations, even CI/CD failures and dependency upgrades. Fixing a broken pipeline that used to take an hour? AI figured it out in minutes. But I still review, test, and deploy. Responsibility didn’t disappear – it <strong>shifted to higher-level decisions</strong>.</p>
</li>
<li><p><strong>Focus on value, not typing</strong><br />Before AI, I spent most of my time writing code. Now I spend most of my time:</p>
</li>
</ol>
<ul>
<li><p>designing systems</p>
</li>
<li><p>clarifying requirements with stakeholders</p>
</li>
<li><p>reviewing and testing AI-generated code</p>
</li>
<li><p>thinking about the customer experience</p>
</li>
</ul>
<p>AI writes the implementation. I make sure it <strong>actually solves a business problem</strong>.</p>
<ol>
<li><strong>Small teams can operate like big teams</strong><br />Because of AI, our tiny team can now handle more work with fewer people. We can automate repetitive tasks, stabilize internal tools, and maintain dozens of services without hiring a full DevOps team. That’s real business impact: faster delivery, fewer errors, and systems that scale.</li>
</ol>
<p>Here’s the bigger lesson I want to share:</p>
<p>Many business owners and founders see AI and panic. They think: <em>“My developers, my product, my team — will it all be replaced?”</em></p>
<p>Here’s the truth from the trenches:</p>
<ul>
<li><p>AI replaces <strong>tasks</strong>, not responsibility.</p>
</li>
<li><p>AI can write code, but it can’t understand <strong>customers, trade-offs, or real-world consequences</strong>.</p>
</li>
<li><p>The human role shifts to <strong>ensuring that AI-generated work actually creates business value</strong>.</p>
</li>
</ul>
<p>I don’t know if AI will replace software engineers entirely in the long run. Maybe it will. But in the <strong>foreseeable future</strong>, AI isn’t replacing us — it’s <strong>elevating us</strong>. And businesses that leverage it wisely get results that were impossible for small teams before.</p>
<p><strong>Real-world business impact</strong></p>
<ul>
<li><p>Turned manual workflows into automated systems</p>
</li>
<li><p>Stabilized AI-generated code for prototypes that were slowing development</p>
</li>
<li><p>Migrated legacy services efficiently without downtime</p>
</li>
<li><p>Reduced repetitive DevOps tasks, freeing the team to focus on product growth</p>
</li>
</ul>
<p>If your business still relies on manual processes, spreadsheets, or tools that don’t scale, or if your AI/prototype-based project is becoming slow, buggy, or hard to maintain — that’s exactly where experience makes a difference.</p>
<p>I help businesses turn AI and software into <strong>real, reliable systems</strong> that solve actual problems.</p>
<p>AI can write code. But building systems that work for your business? <strong>That’s still human work.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Weekly Wisdom: Insights and Discoveries from My Reading Journey]]></title><description><![CDATA[Occasionally, I'll share insights and learnings from my reading journey. This is the first installment—a digest of valuable discoveries, both recent and past.

1. Sending Prompts to Multiple AI Models Simultaneously
Last week, while commuting home fr...]]></description><link>https://blog.bahridd.in/weekly-wisdom-from-my-reading-journey</link><guid isPermaLink="true">https://blog.bahridd.in/weekly-wisdom-from-my-reading-journey</guid><category><![CDATA[boring technology]]></category><category><![CDATA[AI]]></category><category><![CDATA[Multi tenancy]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Rails]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[chatbot]]></category><category><![CDATA[#AIComparison ]]></category><dc:creator><![CDATA[Bahriddin Abdiev]]></dc:creator><pubDate>Sun, 09 Feb 2025 12:37:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/BVyNlchWqzs/upload/2dfec4db17582a2486a4fe3d5af83f73.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Occasionally, I'll share insights and learnings from my reading journey. This is the first installment—a digest of valuable discoveries, both recent and past.</p>
<hr />
<h2 id="heading-1-sending-prompts-to-multiple-ai-models-simultaneously">1. Sending Prompts to Multiple AI Models Simultaneously</h2>
<p>Last week, while commuting home from work, I had an idea that I quickly noted down:</p>
<blockquote>
<p><strong>One UI to interact with multiple AI models and evaluate the best response.</strong></p>
<h4 id="heading-problem">Problem:</h4>
<p>Currently, users manually copy and paste the same prompt into multiple AI platforms to compare results. What if there were a single UI that could send a prompt to multiple AIs at once? What if, instead of the user going to the AI, the AI came to the user?</p>
</blockquote>
<p>As it turns out, this idea has already been implemented. <a target="_blank" href="https://lmarena.ai/">Chatbot Arena</a>, developed by UC Berkeley researchers and supported by various organizations, allows users to compare AI models based on user votes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739103760032/1ae857ca-f551-476f-a0ed-363eab05ebf3.png" alt class="image--center mx-auto" /></p>
<p>It offers almost all the features I envisioned—and even more:</p>
<ul>
<li><p>Compare chat responses and send follow-up prompts.</p>
</li>
<li><p>Compare image generation, with the option to download images for free.</p>
</li>
<li><p>Compare code generation, with downloadable outputs.</p>
</li>
<li><p>View an AI leaderboard across different categories.</p>
</li>
</ul>
<p>If you try it, don’t forget to vote for the best model as a way of giving back!</p>
<hr />
<h2 id="heading-2-changing-a-self-hosted-app-to-a-multi-tenant-hosted-app-postgres-schemas-in-railshttpsvinioyamacomblogchanging-a-self-hosted-app-to-a-multi-tenant-hosted-app-postgres-schemas-in-ruby-on-rails"><strong>2.</strong> <a target="_blank" href="https://vinioyama.com/blog/changing-a-self-hosted-app-to-a-multi-tenant-hosted-app-postgres-schemas-in-ruby-on-rails/"><strong>Changing a Self-Hosted App to a Multi Tenant Hosted App – Postgres Schemas in Rails</strong></a></h2>
<p><img src="https://vinioyama.com/wp-content/uploads/postgres-schemas-diagram-1024x532.png" alt /></p>
<p>This blog post explores how to implement multi-tenancy in a Rails application using <a target="_blank" href="https://www.postgresql.org/docs/current/ddl-schemas.html">PostgreSQL schemas</a> and the <a target="_blank" href="https://github.com/rails-on-services/apartment">ros/apartment</a> gem. The author presents an unconventional but interesting approach: keeping some tables in the global schema while storing tenant-specific tables in individual schemas.</p>
<p>The gem handles most of the database-related complexities, including:</p>
<ul>
<li><p>Creating a new schema for each tenant and running migrations.</p>
</li>
<li><p>Deleting old tenant schemas when they are no longer needed.</p>
</li>
</ul>
<p>I haven’t had a chance to experiment with this yet, but it’s definitely worth considering when the opportunity arises. Compared to the conventional <code>tenant_id</code> column approach for multi-tenancy, this could be a more elegant solution.</p>
<hr />
<h2 id="heading-3-an-old-but-gold-talk-choose-boring-technology">3. An Old but Gold Talk: <em>Choose Boring Technology</em></h2>
<p>It seems like today’s movies don’t quite match the quality of older classics. Maybe I’m getting old, or maybe, given how many films have been made over time, the best ones are already in the past. The same logic applies to conference talks—many older ones remain relevant and valuable today.</p>
<p>This weekend, I revisited a talk I highly recommend: <strong>Choose Boring Technology</strong> by Dan McKinley (formerly at Stripe).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1739103130656/e8b6673b-f7f6-4da8-9121-569746c67850.png" alt class="image--center mx-auto" /></p>
<p>Dan discusses different approaches to choosing a tech stack when building a product. His core argument: well-established frameworks with broad community support and team familiarity are far superior to new, unproven technologies that haven’t been battle-tested in real-world applications.</p>
<p>The talk is filled with insightful metaphors, real-world examples, and pragmatic advice. I won’t spoil it—go check it out yourself:</p>
<ul>
<li><p><strong>Video (paywall):</strong> <a target="_blank" href="https://learning.oreilly.com/videos/oscon-2015-video/9781491927991/9781491927991-video218406/">O'Reilly Learning</a></p>
</li>
<li><p><strong>Slides and notes:</strong> <a target="_blank" href="https://boringtechnology.club/">Boring Technology Club</a></p>
</li>
<li><p><strong>Summary article:</strong> <a target="_blank" href="https://mcfunley.com/choose-boring-technology">mcfunley.com</a></p>
</li>
</ul>
<hr />
<p>That’s it for this week. Hope you found these insights helpful!</p>
]]></content:encoded></item><item><title><![CDATA[SaaS Marketing Boost: Build a Landing Page with AI Fast]]></title><description><![CDATA[TLDR: In this article, I share my experience of building a SaaS marketing landing page with an email subscription function using various AI tools in just a few hours. You can view the webpage here: https://go.choley.bahridd.in/

Over the past few mon...]]></description><link>https://blog.bahridd.in/build-a-landing-page-with-ai-fast</link><guid isPermaLink="true">https://blog.bahridd.in/build-a-landing-page-with-ai-fast</guid><category><![CDATA[SaaS]]></category><category><![CDATA[AI]]></category><category><![CDATA[marketing]]></category><category><![CDATA[Startups]]></category><category><![CDATA[Design]]></category><dc:creator><![CDATA[Bahriddin Abdiev]]></dc:creator><pubDate>Tue, 04 Feb 2025 12:18:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/fSWQPBxqClg/upload/174fc3eb848d3dd613035ae3ee41a50f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>TLDR: In this article, I share my experience of building a SaaS marketing landing page with an email subscription function using various AI tools in just a few hours. You can view the webpage here: <a target="_blank" href="https://go.choley.bahridd.in/"><strong>https://go.choley.bahridd.in/</strong></a></p>
<hr />
<p>Over the past few months, I've been developing a SaaS app for table tennis clubs (the app itself is beyond the scope of this article). After completing the MVP, I realized I needed a strategy to market my product. An online suggestion was to create a simple marketing website with an email subscription form before the official launch. This approach allows you to:</p>
<ul>
<li><p>Compile a list of potential customers who are interested enough to provide their email addresses.</p>
</li>
<li><p>Connect with some of them to understand their needs and the problems they hope your app will solve.</p>
</li>
</ul>
<p>Given my busy schedule and full-time job, I wanted to build and deploy this quickly and cost-effectively. This was the perfect opportunity to leverage AI tools to the fullest.</p>
<p>The plan was straightforward:</p>
<ol>
<li><p><strong>Create the UI using HTML and CSS.</strong></p>
</li>
<li><p><strong>Develop a minimal backend to capture emails and store them.</strong></p>
</li>
<li><p><strong>Deploy the application.</strong></p>
</li>
</ol>
<p>For the first step, I used <a target="_blank" href="http://Readdy.AI"><strong>Readdy.AI</strong></a>, which generated <a target="_blank" href="https://readdy.ai/">a decent</a> <a target="_blank" href="https://readdy.site/share/651c1371c3efa22ae0dfe344fc0e8a3d"><strong>landing page</strong></a> from the initial prompt<a target="_blank" href="https://readdy.site/share/651c1371c3efa22ae0dfe344fc0e8a3d">:</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738498854485/85a10796-8679-4bae-9e85-a45e541ae847.png" alt class="image--center mx-auto" /></p>
<p>It used React and Shadcn UI components to create the page. A few adjustments I wanted to make included:</p>
<ol>
<li><p>The hero image was unsettling, resembling a horror movie intro 👻. However, this was easily fixable by replacing the image.</p>
</li>
<li><p>I wanted to add a screenshot of the app to give customers a preview.</p>
</li>
</ol>
<p>After few more prompts, Readdy made a <a target="_blank" href="https://readdy.site/share/695d4fd867075adb3a59d40db083c9fc">good progress</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738499422120/f013c71d-b1c4-43f9-b441-353207a967e5.png" alt class="image--center mx-auto" /></p>
<p>I later discovered it wasn't responsive—viewing the link on a mobile device illustrates this issue. I resolved it by hiding the screenshot on mobile screens.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738502879238/a5ee03f6-3784-48d5-bf88-01600e10b1e9.png" alt class="image--center mx-auto" /></p>
<p>I also updated the email form in the footer to collect more information than just the email address, such as feedback and the user's role (player or club admin). I figured that if users reached the end of the page, they were interested enough to provide additional details.</p>
<p>For the backend and deployment, I sought help from ChatGPT, which recommended using Next.js and <a target="_blank" href="https://vercel.com/">Vercel</a>. Despite having no prior experience with these technologies, the process went smoothly. I used Google Spreadsheet for email storage. All other technical details were implemented using ChatGPT and Cursor IDE with its AI features:</p>
<ul>
<li><p>Registering Google Cloud API to write to the spreadsheet</p>
</li>
<li><p>Implementing backend code to write to the spreadsheet</p>
</li>
<li><p>Adding DNS records</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738842532245/2cf2d23a-cd1a-47da-bf05-0f3e7821d550.gif" alt class="image--center mx-auto" /></p>
<p>In summary, I used free tiers of Readdy.ai, ChatGPT, and Pro version of Cursor. All the code is <a target="_blank" href="https://github.com/bahriddin/choley-marketing"><strong>publicly available</strong></a>. You can visit the landing page here: <a target="_blank" href="https://go.choley.bahridd.in/"><strong>https://go.choley.bahridd.in/</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Share external drive using Raspberry Pi]]></title><description><![CDATA[Storing bunch of photos, videos, old files in the cloud is handy but it costs you extra fee each month. Storing them in the external drive is much cheaper option with one drawback: you need to connect it to your machine to access and copy files. What...]]></description><link>https://blog.bahridd.in/share-external-drive-using-raspberry-pi</link><guid isPermaLink="true">https://blog.bahridd.in/share-external-drive-using-raspberry-pi</guid><category><![CDATA[samba]]></category><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[server]]></category><category><![CDATA[homeserver]]></category><dc:creator><![CDATA[Bahriddin Abdiev]]></dc:creator><pubDate>Wed, 14 Feb 2024 11:33:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/-blDs_-gLzE/upload/7c59ee3ebac2116c56c67785f23d241f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Storing bunch of photos, videos, old files in the cloud is handy but it costs you extra fee each month. Storing them in the external drive is much cheaper option with one drawback: you need to connect it to your machine to access and copy files. What if you could share it on your home network? That would be great for a few reasons:</p>
<ul>
<li><p>You will have instant access to the contents from any device in the network</p>
</li>
<li><p>Connect and forget</p>
</li>
<li><p>Free</p>
</li>
</ul>
<p>Good news is you won't need a lot to make it work:</p>
<ul>
<li><p>External drive</p>
</li>
<li><p>Raspberry Pi (4B in my case but any version should work fine)</p>
</li>
<li><p>Home network (WiFi router)</p>
</li>
</ul>
<p>And setup process is also fairly straightforward.</p>
<h3 id="heading-setup-samba-server-on-raspberry-pi">Setup Samba server on Raspberry Pi</h3>
<ol>
<li><p><strong>Connect External Drive:</strong></p>
<ul>
<li>Plug in your external drive to one of the USB ports on your Raspberry Pi.</li>
</ul>
</li>
<li><p><strong>Update and Upgrade:</strong></p>
<ul>
<li><p>Open the terminal and run:</p>
<pre><code class="lang-bash">  $ sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Install Samba:</strong></p>
<ul>
<li><pre><code class="lang-bash">    $ sudo apt install samba
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Configure Samba:</strong></p>
<ul>
<li><p>Open the Samba configuration file:</p>
<pre><code class="lang-bash">  $ sudo nano /etc/samba/smb.conf
</code></pre>
</li>
<li><p>Scroll to the end and add:</p>
<pre><code class="lang-bash">  plaintextCopy code[ExternalDrive]
  path = /path/to/your/external/drive
  writeable = yes
  create mask = 0777
  directory mask = 0777
  public = no
</code></pre>
</li>
</ul>
</li>
</ol>
<p>    Replace <code>/path/to/your/external/drive</code> with the actual path to your external drive.</p>
<ol>
<li><p><strong>Create Samba User:</strong></p>
<ul>
<li><p>Set a password for the default pi user (or create a new user):</p>
<pre><code class="lang-bash">  $ sudo smbpasswd -a pi
</code></pre>
</li>
</ul>
</li>
<li><p><strong>Restart Samba:</strong></p>
<ul>
<li><pre><code class="lang-bash">    $ sudo service smbd restart
</code></pre>
</li>
</ul>
</li>
</ol>
<p>Now, you should be able to access your external drive through Samba. Connect to it using your computer's file explorer with <code>smb://&lt;Raspberry_Pi_IP_Address&gt;/ExternalDrive</code>.</p>
<h3 id="heading-connect-to-the-server">Connect to the Server</h3>
<p>In my case I accessed using my Macbook but for other devices process should be similar:</p>
<ol>
<li><p>Open Finder.</p>
</li>
<li><p>In the menu bar, select <strong>Go</strong> and then <strong>Connect to Server...</strong> (or simply use <code>Cmd + K</code> shortcut).</p>
</li>
<li><p>Type the following in the "Server Address" field:</p>
<ul>
<li><pre><code class="lang-bash">    $ smb://&lt;Raspberry_Pi_IP_Address&gt;/ExternalDrive
</code></pre>
</li>
<li><p>Replace <code>&lt;Raspberry_Pi_IP_Address&gt;</code> with the actual IP address of your Raspberry Pi.</p>
</li>
</ul>
</li>
<li><p><strong>Authentication:</strong></p>
<ul>
<li><p>Click the <strong>Connect</strong> button.</p>
</li>
<li><p>Enter the username (likely 'pi') and the password you set with <code>sudo smbpasswd -a pi</code>.</p>
</li>
</ul>
</li>
<li><p><strong>Access Files:</strong></p>
<ul>
<li>Once connected, you should see the contents of your external drive. You can now copy, paste, or manage files as needed.</li>
</ul>
</li>
</ol>
<p>That's it! You're now connected to your Samba server from your MacBook. Let me know if you encounter any issues.</p>
]]></content:encoded></item></channel></rss>