<?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: Chris</title>
    <description>The latest articles on DEV Community by Chris (@criscmd).</description>
    <link>https://dev.to/criscmd</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F844017%2F83fd4977-3a5d-4125-bf9e-c82f66c00690.jpg</url>
      <title>DEV Community: Chris</title>
      <link>https://dev.to/criscmd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/criscmd"/>
    <language>en</language>
    <item>
      <title>Azura: local-first personal assistant (feedback wanted)</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Fri, 14 Nov 2025 12:04:16 +0000</pubDate>
      <link>https://dev.to/criscmd/azura-local-first-personal-assistant-feedback-wanted-56dp</link>
      <guid>https://dev.to/criscmd/azura-local-first-personal-assistant-feedback-wanted-56dp</guid>
      <description>&lt;p&gt;Hey devs 👋&lt;/p&gt;

&lt;p&gt;I'm working solo on a project called &lt;strong&gt;Azura&lt;/strong&gt; and I’d love blunt technical + product feedback before I go too deep.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local-first personal AI assistant&lt;/strong&gt; (Windows / macOS / Linux)&lt;/li&gt;
&lt;li&gt;Runs &lt;strong&gt;7B-class models locally&lt;/strong&gt; on your own machine&lt;/li&gt;
&lt;li&gt;Optional &lt;strong&gt;cloud inference&lt;/strong&gt; with &lt;strong&gt;70B+ models&lt;/strong&gt; (potentially up to ~120B if I can get a GPU cluster cheap enough)&lt;/li&gt;
&lt;li&gt;Cloud only sees &lt;strong&gt;temporary context&lt;/strong&gt; for a given query, then it’s gone&lt;/li&gt;
&lt;li&gt;Goal: let AI work with &lt;strong&gt;highly personalized data&lt;/strong&gt; while keeping your data &lt;strong&gt;on-device&lt;/strong&gt; and making AI compute more &lt;strong&gt;sustainable&lt;/strong&gt; by offloading work to the user’s hardware&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as &lt;strong&gt;Signal, but for AI&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;private by default
&lt;/li&gt;
&lt;li&gt;transparent about what leaves your device
&lt;/li&gt;
&lt;li&gt;and actually usable as a daily “second brain”.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Problem I’m trying to solve
&lt;/h2&gt;

&lt;p&gt;Most AI tools today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ship all your prompts and files to a remote server
&lt;/li&gt;
&lt;li&gt;keep embeddings / logs indefinitely
&lt;/li&gt;
&lt;li&gt;centralize all compute in big datacenters
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s bad if you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use AI on &lt;strong&gt;sensitive&lt;/strong&gt; data (legal docs, internal company info, personal notes)
&lt;/li&gt;
&lt;li&gt;build a &lt;strong&gt;long-term memory&lt;/strong&gt; of your life and work
&lt;/li&gt;
&lt;li&gt;not rely 100% on someone else’s infrastructure for every tiny inference
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of that, current AI usage is very &lt;strong&gt;cloud-heavy&lt;/strong&gt;. Every small task hits a GPU in a datacenter, even when a smaller local model would be good enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Azura’s goal:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let AI work deeply with your personal data while keeping that data on your device by default, and offload as much work as possible to the user’s hardware to make AI more sustainable.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Core concept
&lt;/h2&gt;

&lt;p&gt;Azura has two main execution paths:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Local path (default)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desktop app (Win / macOS / Linux)&lt;/li&gt;
&lt;li&gt;Local backend (Rust / llama.cpp / vector DB)&lt;/li&gt;
&lt;li&gt;Uses a &lt;strong&gt;7B model&lt;/strong&gt; running on your machine&lt;/li&gt;
&lt;li&gt;Good for:

&lt;ul&gt;
&lt;li&gt;day-to-day chat&lt;/li&gt;
&lt;li&gt;note-taking / journaling&lt;/li&gt;
&lt;li&gt;searching your own docs/files&lt;/li&gt;
&lt;li&gt;“second brain” queries that don’t need super high IQ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cloud inference path (optional)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a query is too complex / heavy for the local 7B:

&lt;ul&gt;
&lt;li&gt;Azura builds a &lt;strong&gt;minimal context&lt;/strong&gt; (chunks of docs, metadata, etc.)&lt;/li&gt;
&lt;li&gt;Sends that context + query to a &lt;strong&gt;70B+ model&lt;/strong&gt; in the cloud (ideally up to ~120B later)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data handling:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Files / context are used &lt;strong&gt;only temporarily&lt;/strong&gt; for that request&lt;/li&gt;
&lt;li&gt;Held in memory or short-lived storage just long enough to run the inference&lt;/li&gt;
&lt;li&gt;Then discarded – no long-term cloud memory of your life&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Context engine (high-level idea)
&lt;/h2&gt;

&lt;p&gt;On top of “just call an LLM”, I’m experimenting with a structured &lt;strong&gt;context engine&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ingests:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;files, PDFs, notes, images&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Stores:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;embeddings + metadata (timestamps, tags, entities, locations)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Builds:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;a lightweight relationship graph (people, projects, events, topics)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Answers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;“What did I do for project A in March?”&lt;/li&gt;
&lt;li&gt;“Show me everything related to ‘Company A’ and ‘pricing’.”&lt;/li&gt;
&lt;li&gt;“What did I wear at the gala in Tokyo?” (from images ingested)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Standard RAG is part of this, but the goal is an &lt;strong&gt;ongoing personal knowledge base&lt;/strong&gt; that the LLM can query, not just a vector search API.&lt;/p&gt;

&lt;p&gt;All of this long-term data lives &lt;strong&gt;on-device&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sustainability angle (important to me)
&lt;/h2&gt;

&lt;p&gt;Part of the vision is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t hit a giant GPU cluster for every small query.
&lt;/li&gt;
&lt;li&gt;Let the &lt;strong&gt;user’s device&lt;/strong&gt; handle as much as possible (7B locally).
&lt;/li&gt;
&lt;li&gt;Use big cloud models &lt;strong&gt;only when they actually add value&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, I’d like Azura to feel like a &lt;strong&gt;hybrid compute layer&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local where possible,
&lt;/li&gt;
&lt;li&gt;Cloud only for heavy stuff,
&lt;/li&gt;
&lt;li&gt;Always explicit and transparent.
&lt;/li&gt;
&lt;li&gt;And most of all, &lt;strong&gt;PRIVATE&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I’d love feedback on
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Architecture sanity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the “local-first + direct cloud inference” setup look sane?&lt;/li&gt;
&lt;li&gt;Any better patterns you’ve used for mixing on-device models with cloud models?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security + privacy model&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For ephemeral cloud context: what would &lt;em&gt;you&lt;/em&gt; need to see (docs / guarantees / telemetry) to trust this?&lt;/li&gt;
&lt;li&gt;Anything obvious I’m missing around temporary file handling?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sustainability / cost&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As engineers: do you care about offloading compute to end-user devices vs fully cloud?&lt;/li&gt;
&lt;li&gt;Any horror stories optimizing 7B vs 70B usage that I should know about?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Would you actually use this?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re into self-hosting / local LLMs:

&lt;ul&gt;
&lt;li&gt;What’s missing for this to replace “Ollama + notebook + random SaaS” for you?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;Right now I’m:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing 7B models on typical consumer hardware&lt;/li&gt;
&lt;li&gt;Designing the first version of the context engine and schema&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this resonates, I’d really appreciate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture critiques&lt;/li&gt;
&lt;li&gt;“This will break because X” comments&lt;/li&gt;
&lt;li&gt;Ideas for must-have features for a real, daily-use personal AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 🙏&lt;br&gt;&lt;br&gt;
Happy to dive into any part in more detail if you’re curious.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>community</category>
      <category>programming</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>You Only Really Need to Learn 2 Languages to Succeed</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Fri, 27 Jun 2025 16:12:59 +0000</pubDate>
      <link>https://dev.to/criscmd/you-only-really-need-to-learn-2-languages-to-succeed-4a7n</link>
      <guid>https://dev.to/criscmd/you-only-really-need-to-learn-2-languages-to-succeed-4a7n</guid>
      <description>&lt;p&gt;Most developers are told they need to learn dozens of languages to stay competitive. One for scripting, one for frontend, one for backend, one for systems, and another five because "they’re trending."&lt;/p&gt;

&lt;p&gt;But in reality?&lt;/p&gt;

&lt;p&gt;You only need two.&lt;br&gt;
Not any two, but one from each of these two fundamental categories:&lt;/p&gt;




&lt;h3&gt;
  
  
  🔹 1. A &lt;strong&gt;High Level Language&lt;/strong&gt; (With Garbage Collection)
&lt;/h3&gt;

&lt;p&gt;These are your productive, developer-friendly languages. They manage memory for you, offer rich ecosystems, and help you ship fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;C#&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use these when building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web apps&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Scripts&lt;/li&gt;
&lt;li&gt;Automation&lt;/li&gt;
&lt;li&gt;Data pipelines&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔸 2. A &lt;strong&gt;Low Level Language&lt;/strong&gt; (Without Garbage Collection)
&lt;/h3&gt;

&lt;p&gt;These languages give you precise control over memory and performance. They are used when predictability, speed, or system-level access matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;C++&lt;/li&gt;
&lt;li&gt;C&lt;/li&gt;
&lt;li&gt;Zig&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use these for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game engines&lt;/li&gt;
&lt;li&gt;OS development&lt;/li&gt;
&lt;li&gt;Embedded systems&lt;/li&gt;
&lt;li&gt;Performance-critical code&lt;/li&gt;
&lt;li&gt;Security and cryptography work&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Why Just These Two?
&lt;/h2&gt;

&lt;p&gt;Because most real-world software problems fall into one of these buckets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High level orchestration like building logic, connecting services, and managing flows&lt;/li&gt;
&lt;li&gt;Low level performance like speed, memory management, and hardware interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can write both, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a full stack system on your own&lt;/li&gt;
&lt;li&gt;Write efficient backend services and embedded agents&lt;/li&gt;
&lt;li&gt;Move between startup MVPs and military-grade firmware&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Smart Pairings
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GC Language&lt;/th&gt;
&lt;th&gt;Non-GC Language&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You do not need to master all of them. Just pick one solid language from each group and go deep.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Depth Over Breadth
&lt;/h2&gt;

&lt;p&gt;Mastering a garbage-collected language makes you productive&lt;br&gt;
Mastering a non-GC language makes you powerful&lt;/p&gt;

&lt;p&gt;You do not need to chase trends. You need to understand tradeoffs, how systems work, how memory is managed, and how to scale clean code.&lt;/p&gt;

&lt;p&gt;Everything else is just syntax.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ TLDR
&lt;/h2&gt;

&lt;p&gt;You only really need to learn two languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One that frees you to move fast&lt;/li&gt;
&lt;li&gt;One that forces you to think clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn them deeply&lt;br&gt;
Build boldly&lt;br&gt;
Forget the noise&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Stop Overengineering in the Name of Clean Architecture</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 11 May 2025 03:15:29 +0000</pubDate>
      <link>https://dev.to/criscmd/stop-overengineering-in-the-name-of-clean-architecture-b8h</link>
      <guid>https://dev.to/criscmd/stop-overengineering-in-the-name-of-clean-architecture-b8h</guid>
      <description>&lt;p&gt;Clean Architecture is a great concept. It’s meant to help you write maintainable, modular, and scalable software.&lt;/p&gt;

&lt;p&gt;But too many developers treat it like a religion. They follow it blindly, stuffing projects with unnecessary layers, abstractions, and patterns. All in the name of “clean code.”&lt;/p&gt;

&lt;p&gt;Let’s be honest, Clean Architecture is often &lt;strong&gt;overused&lt;/strong&gt;, not because the ideas are bad, but because people &lt;strong&gt;overengineer&lt;/strong&gt; the implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Joke (That Some Devs Write Unironically)
&lt;/h2&gt;

&lt;p&gt;Here’s an example of multiplying two numbers implemented with an absurd number of patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// overengineered-multiplier.ts&lt;/span&gt;

&lt;span class="c1"&gt;// Interface&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Singleton&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultiplierService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;MultiplierService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Adapter&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMultiplierInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InputAdapter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;adapt&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;IMultiplierInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Decorator&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoggingMultiplierDecorator&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Logging: Multiplying &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; * &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Logging: Result is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Proxy&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultiplierProxy&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid input types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Abstract Factory&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IMultiplierFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RealMultiplierFactory&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IMultiplierFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;IMultiplier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;singleton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MultiplierService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLogging&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LoggingMultiplierDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withProxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MultiplierProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;withLogging&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;withProxy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adapted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InputAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rawInput&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;adapt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RealMultiplierFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;adapted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;adapted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Final Result: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of this just to calculate &lt;code&gt;6 * 9&lt;/code&gt;. This is what happens when design patterns become cosplay.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem: Over-Abstraction
&lt;/h2&gt;

&lt;p&gt;Clean Architecture promotes decoupling. That’s good. But too many devs interpret that as "abstract everything."&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IUserRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryImpl&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IUserRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&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="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you add a use case on top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetUserByIdUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUserRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;All of this for one database call. This isn’t clean it’s waste.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Overengineering Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Interfaces and Implementations for Everything
&lt;/h3&gt;

&lt;p&gt;Blindly creating an interface and a class for every service adds friction without real value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use it when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You actually have multiple implementations&lt;/li&gt;
&lt;li&gt;You’re building a plugin system or SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Don’t use it when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You only have one implementation&lt;/li&gt;
&lt;li&gt;You’re doing it "just in case"&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Use Case Classes for Simple Logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreatePostUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CreatePostDTO&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostDTO&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;postRepo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;This is a one-line call. Wrapping it in a class adds nothing. Use a service or method directly unless business logic really requires separation.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. DTO Explosion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreatePostDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PostResponseDTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the structure is the same across layers, reuse the object. You don’t need a new DTO for every transition unless there’s a reason.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Domain Models with No Behavior
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;If your "domain entity" is just a data wrapper, it’s not a domain model. Add behavior or don’t abstract.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Dependency Injection Overkill
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserServiceImpl&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUserRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserRepositoryImpl&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;DI containers are great. But if you’re not benefiting from polymorphism or dynamic injection, just instantiate the class.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You Should Do Instead
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start simple.&lt;/strong&gt; Build complexity only when needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abstract with intent.&lt;/strong&gt; Not everything needs to be swappable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactor later.&lt;/strong&gt; Let the structure grow organically as the app gets more complex.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize for clarity.&lt;/strong&gt; Not for pleasing architecture diagrams.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Clean Code Is Not More Code
&lt;/h2&gt;

&lt;p&gt;Good code is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to read&lt;/li&gt;
&lt;li&gt;Easy to test&lt;/li&gt;
&lt;li&gt;Easy to change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not defined by how many layers, decorators, or design patterns it uses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Clean Architecture should serve your code, not the other way around.&lt;/p&gt;

&lt;p&gt;It’s a tool, not a rulebook. Use it to solve complexity not to create it.&lt;/p&gt;




&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Avoid This&lt;/th&gt;
&lt;th&gt;Do This Instead&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Interface and Impl for everything&lt;/td&gt;
&lt;td&gt;Use one class until you actually need two&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use cases for CRUD logic&lt;/td&gt;
&lt;td&gt;Use simple services or methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Separate DTOs for same shapes&lt;/td&gt;
&lt;td&gt;Reuse types where possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DI for everything&lt;/td&gt;
&lt;td&gt;Instantiate directly when practical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Layers for layers’ sake&lt;/td&gt;
&lt;td&gt;Let structure grow with real needs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Build software, not monuments.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of course, if your goal is job security, then by all means abstract everything. Write five layers per feature, name nothing clearly, and inject interfaces into factories into services into use cases. Once the codebase hits 100,000 lines, no one will know what’s going on but you. Congratulations, you’re now unfireable LOL.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>programming</category>
      <category>discuss</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>TypeScript + Rust: All You Need in 2025</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 11 May 2025 02:59:58 +0000</pubDate>
      <link>https://dev.to/criscmd/typescript-rust-all-you-need-in-2025-3dic</link>
      <guid>https://dev.to/criscmd/typescript-rust-all-you-need-in-2025-3dic</guid>
      <description>&lt;p&gt;Let’s be real. The software landscape is bloated. Between AI hyped frameworks and the constant cycle of JS libraries trying to reinvent the wheel, it’s easy to get lost chasing tech for the sake of it.&lt;/p&gt;

&lt;p&gt;But if you're trying to actually build something valuable in 2025, not just keep up with Hacker News, you really only need two languages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;Rust&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Why TypeScript?
&lt;/h3&gt;

&lt;p&gt;Because 90 percent of products today touch the web. And when it comes to frontend, API clients, or even backend services, nothing is more practical than TypeScript.&lt;/p&gt;

&lt;p&gt;You get type safety without the Java boilerplate&lt;br&gt;
You get first class tooling with VSCode, ESLint, Bun, tsup&lt;br&gt;
You can build full stack apps across Next.js, Node, Cloudflare Workers, Firebase&lt;br&gt;
You move fast without breaking everything&lt;/p&gt;

&lt;p&gt;It’s the language of the web. Period&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Rust?
&lt;/h3&gt;

&lt;p&gt;Because when performance, memory safety, and scale matter, Rust is unmatched&lt;/p&gt;

&lt;p&gt;C level performance with zero segfaults&lt;br&gt;
Compiles to WebAssembly or runs as a blazing fast backend&lt;br&gt;
Handles AI pipelines, edge compute, custom databases, file systems&lt;br&gt;
Gives you memory control and fearless concurrency for real workloads&lt;/p&gt;

&lt;p&gt;You are not wasting CPU cycles on garbage collection or runtime bugs&lt;/p&gt;




&lt;h3&gt;
  
  
  What About the Others?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;br&gt;
Nice syntax until the codebase grows. The type system is glued on, not designed in. Static analysis is a mess and errors sneak in constantly&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go&lt;/strong&gt;&lt;br&gt;
Go is great for building simple tools quickly, but it can become a liability at scale. Discord famously dropped Go from their caching system after the garbage collector became a bottleneck. While that specific issue was later addressed, GC performance can still be unpredictable under heavy load. If you need fine-grained control or predictable latency, Go might not cut it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;br&gt;
Enterprise hell. Verbose classes, XML config files, Spring Boot complexity. Java is built for a different era. If you are building modern software today, why are you still using it&lt;/p&gt;




&lt;h3&gt;
  
  
  Real World Example
&lt;/h3&gt;

&lt;p&gt;In my current projects&lt;/p&gt;

&lt;p&gt;Frontend and admin dashboards: TypeScript with React, Chakra, Next.js&lt;br&gt;
Backend logic, APIs, authentication, realtime: TypeScript with NestJS, Firebase, Cloud Run&lt;br&gt;
Data processing, local AI, indexing: Rust with REST API, image parsing, zip and file system crawling&lt;br&gt;
Vector search and storage orchestration: Rust with Qdrant and PostgreSQL&lt;/p&gt;

&lt;p&gt;One stack&lt;br&gt;
End to end control&lt;br&gt;
No bloat&lt;br&gt;
No regrets&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;If you master TypeScript and Rust, you are not a JS dev&lt;br&gt;
You are not a systems dev&lt;br&gt;
You are a &lt;strong&gt;full spectrum engineer&lt;/strong&gt; who can build anything from the interface to the infrastructure&lt;/p&gt;

&lt;p&gt;In a world filled with AI noise, cloud saturation, and latency pressure&lt;/p&gt;

&lt;p&gt;That’s all you need&lt;/p&gt;




&lt;p&gt;What are you building with in 2025&lt;br&gt;
Let’s talk in the comments&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>rust</category>
      <category>typescript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Don’t Use SQL If Your Client Doesn’t Know What They Want</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 11 May 2025 02:46:56 +0000</pubDate>
      <link>https://dev.to/criscmd/dont-use-sql-if-your-client-doesnt-know-what-they-want-2hhm</link>
      <guid>https://dev.to/criscmd/dont-use-sql-if-your-client-doesnt-know-what-they-want-2hhm</guid>
      <description>&lt;h2&gt;
  
  
  Firestore saved me from schema hell
&lt;/h2&gt;

&lt;p&gt;If you’re building for a client who keeps shifting the goalpost, here’s some honest advice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid SQL until the spec is stable.&lt;/strong&gt;&lt;br&gt;
You’ll save yourself from endless migrations, broken data, and wasted hours.&lt;/p&gt;




&lt;h2&gt;
  
  
  💥 Why SQL is a bad idea in chaotic projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Every schema change = manual migration&lt;/li&gt;
&lt;li&gt;Every migration = rollback risk&lt;/li&gt;
&lt;li&gt;Every miscommunication = broken relations or corrupted data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s like building a skyscraper with a blueprint drawn in crayon.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Why Firestore (NoSQL) saved me
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No migrations&lt;/strong&gt;&lt;br&gt;
Just start writing data. Add new fields whenever. No tables to alter. No DB admin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nested data, no problem&lt;/strong&gt;&lt;br&gt;
Need a user profile with 5 settings and a subcollection of comments? Firestore handles that like it’s native.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed over structure&lt;/strong&gt;&lt;br&gt;
Perfect for MVPs. When the client changes their mind (again), you don’t have to rewrite half your DB logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Schema-less = stress-less&lt;/strong&gt;&lt;br&gt;
You don’t get yelled at for not “planning ahead.” You just ship.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚖️ But if you &lt;em&gt;have&lt;/em&gt; to use SQL…
&lt;/h2&gt;

&lt;p&gt;Some teams/projects require relational DBs. Here are tools that make the pain tolerable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prisma&lt;/strong&gt; Type-safe, declarative schema, powerful migration engine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knex.js + Objection.js&lt;/strong&gt; Mature and battle-tested in Node environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atlas by Ariga&lt;/strong&gt; Clean migration workflows, good for CI/CD&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Supabase&lt;/strong&gt; 🔥 Firebase-like developer experience &lt;strong&gt;on top of PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant APIs&lt;/li&gt;
&lt;li&gt;Auth + storage included&lt;/li&gt;
&lt;li&gt;Web UI for managing schema/migrations&lt;/li&gt;
&lt;li&gt;Great for teams that &lt;em&gt;need&lt;/em&gt; SQL but want NoSQL-level velocity&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Supabase is different
&lt;/h3&gt;

&lt;p&gt;Even though it’s SQL under the hood, &lt;strong&gt;Supabase makes schema changes easier to manage&lt;/strong&gt;. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View and edit tables in the dashboard&lt;/li&gt;
&lt;li&gt;Auto-generate APIs&lt;/li&gt;
&lt;li&gt;Roll back or push migrations with Git workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a great compromise if your project is too relational for Firestore but still in flux.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If the client says “we’re still figuring it out,” avoid SQL unless you enjoy stress.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Use &lt;strong&gt;Firestore&lt;/strong&gt; when things are unstable or MVP&lt;/li&gt;
&lt;li&gt;✅ Use &lt;strong&gt;Supabase&lt;/strong&gt; if you &lt;em&gt;need&lt;/em&gt; SQL but want NoSQL flexibility&lt;/li&gt;
&lt;li&gt;✅ Use proper migration tools (Prisma, Knex, Atlas) if you're stuck with raw SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose tools that match the &lt;em&gt;reality&lt;/em&gt; of the project, not what sounds good on paper.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>database</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>I Started My Own Company at 20 and Landed a $70K Contract. Here's What I'm Building Next</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 11 May 2025 02:41:10 +0000</pubDate>
      <link>https://dev.to/criscmd/i-started-my-own-company-at-20-and-landed-a-70k-contract-heres-what-im-building-next-1h0c</link>
      <guid>https://dev.to/criscmd/i-started-my-own-company-at-20-and-landed-a-70k-contract-heres-what-im-building-next-1h0c</guid>
      <description>&lt;p&gt;At 20 years old, I took the leap and officially founded my first company. I’ve been a software engineer since I was 15, leading teams, shipping products, and consulting. But this is different. This is mine.&lt;/p&gt;

&lt;p&gt;Just days after incorporation, I closed a $70,000 contract. No funding. No connections. No fancy pitch decks. Just proof of work, relentless execution, and solving real problems fast.&lt;/p&gt;

&lt;p&gt;Now I’m channeling that momentum into building something much bigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing &lt;em&gt;NousCore&lt;/em&gt; My Legacy Project
&lt;/h2&gt;

&lt;p&gt;I won’t spill everything. There are too many eyes and too many people trying to ride waves they didn’t earn.&lt;/p&gt;

&lt;p&gt;But here’s what I can share:&lt;/p&gt;

&lt;p&gt;• It’s an AI-native platform that runs on the edge, not in the cloud&lt;br&gt;
• It’s built for performance, privacy, and permanence&lt;br&gt;
• It combines my love for systems programming, local-first data, and real-world utility&lt;br&gt;
• It’s memory-efficient, resilient, and doesn’t need a datacenter to function&lt;/p&gt;

&lt;p&gt;Think of it as a personal AI system that works for you and not for advertisers, not for surveillance, and not for data farms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I’m Doing This
&lt;/h2&gt;

&lt;p&gt;I’m tired of bloated software and overengineered cloud stacks that leak data and burn budgets. I want to create something powerful, self-contained, and private. Something that lasts.&lt;/p&gt;

&lt;p&gt;This isn’t just a product. It’s a statement.&lt;/p&gt;

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

&lt;p&gt;I’ll be documenting parts of my journey (without giving away the sauce). From technical breakdowns to startup realities.&lt;/p&gt;

&lt;p&gt;If you're into AI, systems design, or just want to build things that matter, follow along.&lt;/p&gt;

&lt;p&gt;Let’s make tech that respects people again.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>career</category>
      <category>startup</category>
    </item>
    <item>
      <title>Stop Letting AI Do Your Thinking For You</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Thu, 24 Apr 2025 03:36:12 +0000</pubDate>
      <link>https://dev.to/criscmd/stop-letting-ai-do-your-thinking-for-you-1ne9</link>
      <guid>https://dev.to/criscmd/stop-letting-ai-do-your-thinking-for-you-1ne9</guid>
      <description>&lt;p&gt;Lately it feels like roles are reversing.&lt;br&gt;&lt;br&gt;
Instead of developers using AI as a tool, they are becoming tools for AI.&lt;/p&gt;

&lt;p&gt;People plug their entire codebase into Copilot or Cursor, click accept like it is gospel, and think they are building software. You are not. You are just pasting code with no idea where it came from or how it fits into the system you are supposed to understand.&lt;/p&gt;

&lt;p&gt;Let me be clear:&lt;br&gt;&lt;br&gt;
I use AI. I use ChatGPT. But I use it like a &lt;strong&gt;scalpel&lt;/strong&gt;, not a &lt;strong&gt;crutch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I do not touch Copilot. I do not rely on Cursor. Why?&lt;br&gt;&lt;br&gt;
Because the second you offload thinking, you lose track of context.&lt;br&gt;&lt;br&gt;
And context is the &lt;strong&gt;only real superpower&lt;/strong&gt; a software engineer has.&lt;/p&gt;

&lt;p&gt;No AI today not ChatGPT, not Claude, not anything can keep track of your mental model. They do not know the trade-offs you made last sprint. They do not remember that one brittle API you agreed to avoid touching until Q3. They do not understand why you chose composition over inheritance in a specific module that is now quietly holding your whole app together.&lt;/p&gt;

&lt;p&gt;But you do.&lt;br&gt;&lt;br&gt;
Your brain does.&lt;br&gt;&lt;br&gt;
And when you give up your role as the system’s architect to let some autocomplete guess what you need, you become the assistant, not the engineer.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI is a hammer. You are still the one swinging it.
&lt;/h2&gt;

&lt;p&gt;Use AI to accelerate your thinking. Ask it to break down a regex, write a first draft of a boring config, or summarize documentation. Fine. Great. But never let it own the architecture. Do not let it become your crutch for avoiding complexity.&lt;/p&gt;

&lt;p&gt;Because if you do, one day you will open your codebase and realize you do not even recognize the thing you built.&lt;br&gt;&lt;br&gt;
And worse, you will not know how to fix it.&lt;/p&gt;




&lt;p&gt;If this resonates, drop your thoughts. I am all for AI, but we need to stop worshipping it like it is the engineer. It is not. You are.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How I Made My SaaS "Students Only" Without School IDs Using WHOIS and GPT</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Thu, 24 Apr 2025 00:49:18 +0000</pubDate>
      <link>https://dev.to/criscmd/how-i-made-my-saas-students-only-without-school-ids-using-whois-and-gpt-1p82</link>
      <guid>https://dev.to/criscmd/how-i-made-my-saas-students-only-without-school-ids-using-whois-and-gpt-1p82</guid>
      <description>&lt;p&gt;In building my resume review SaaS tailored for students and 転職活動 (career change) seekers in Japan, I faced a simple question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How do I restrict access to just students without relying on official university logins or SheerID?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lot of companies solve this using school issued IDs, OAuth through G Suite for Education, or even SheerID verification. But all of those come with integration complexity, potential friction, and worst of all kill the speed and ease of my UX.&lt;/p&gt;

&lt;p&gt;So I built something better.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ The Goal: Students Only Access With Just an Email
&lt;/h3&gt;

&lt;p&gt;My signup form asks for a university email. That’s it. If your domain is a real school, you’re in. If it’s not, you’re blocked. No ID upload. No OAuth. No API dependency.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ The Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Node.js (NestJS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Firestore (for whitelist and blacklist)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External Tools&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;WHOIS lookup&lt;/li&gt;
&lt;li&gt;OpenAI GPT API&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;No SheerID. No OAuth. No .edu requirement&lt;/strong&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  💡 The Logic
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;User submits an email like &lt;code&gt;someone@s.chibakoudai.jp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;I extract the domain: &lt;code&gt;s.chibakoudai.jp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check my Firestore whitelist and blacklist&lt;/li&gt;
&lt;li&gt;If unknown, use WHOIS and GPT to verify&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  🔍 WHOIS and GPT Magic
&lt;/h3&gt;

&lt;p&gt;If the domain isn’t already in my whitelist, I check WHOIS to get metadata like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organization name&lt;/li&gt;
&lt;li&gt;Registrant info&lt;/li&gt;
&lt;li&gt;Domain category (often &lt;code&gt;.ac.jp&lt;/code&gt;, &lt;code&gt;.edu&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I feed that WHOIS data into ChatGPT with a prompt like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this domain associated with an educational institution? Just return Yes or No."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If GPT says yes → ✅ add to whitelist&lt;br&gt;&lt;br&gt;
If GPT says no → ❌ add to blacklist and block the user&lt;/p&gt;




&lt;h3&gt;
  
  
  ✨ Example Code Snippet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;whoisData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;lookupWhois&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Is this domain from a university or educational institution?\n\nWHOIS:\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;whoisData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gptResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSchool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gptResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Yes&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;h3&gt;
  
  
  🧠 Why It Works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast UX&lt;/strong&gt; — Users don’t need to upload IDs or register school portals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self expanding list&lt;/strong&gt; — My whitelist grows automatically as GPT verifies new domains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low Cost&lt;/strong&gt; — GPT and WHOIS is cheaper and faster than commercial APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔐 What About Abuse
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Domains like &lt;code&gt;gmail.com&lt;/code&gt; or &lt;code&gt;yahoo.co.jp&lt;/code&gt; get instantly rejected&lt;/li&gt;
&lt;li&gt;Once flagged, a domain is blacklisted and denied forever&lt;/li&gt;
&lt;li&gt;This isn’t a hardcore identity proof — it’s smart friction&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚀 Outcome
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Zero authentication integrations&lt;/li&gt;
&lt;li&gt;Super smooth UX&lt;/li&gt;
&lt;li&gt;Only real students can register&lt;/li&gt;
&lt;li&gt;No need to deal with Japanese school bureaucracy (trust me, that’s worth it)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🤖 TLDR
&lt;/h3&gt;

&lt;p&gt;I used WHOIS and GPT to check if an email domain belonged to a school and whitelist it automatically. No OAuth. No ID. Just a clever prompt and database check. Lightweight, fast, and clean.&lt;/p&gt;




&lt;p&gt;If you want to implement this or have questions, feel free to drop a comment. Happy to share the logic in more detail&lt;br&gt;&lt;br&gt;
And if you’re working on an AI SaaS and want to avoid auth complexity this might be the easiest "student only" gate you'll ever build.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>How I Landed a $150K Contract at 20 While Everyone Else Was Virtue Signaling</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Tue, 22 Apr 2025 10:24:31 +0000</pubDate>
      <link>https://dev.to/criscmd/how-i-landed-a-150k-contract-at-20-while-everyone-else-was-virtue-signaling-2hdo</link>
      <guid>https://dev.to/criscmd/how-i-landed-a-150k-contract-at-20-while-everyone-else-was-virtue-signaling-2hdo</guid>
      <description>&lt;p&gt;Let’s be real&lt;br&gt;&lt;br&gt;
Most of what you see online from “young founders” is noise&lt;/p&gt;

&lt;p&gt;Pitch decks, buzzwords, hackathon demos, endless posts about “building in public”&lt;br&gt;&lt;br&gt;
No users, no product, no revenue&lt;br&gt;&lt;br&gt;
Just vibes&lt;/p&gt;

&lt;p&gt;Meanwhile, I’m 20&lt;br&gt;&lt;br&gt;
No college&lt;br&gt;&lt;br&gt;
No investor&lt;br&gt;&lt;br&gt;
No clout&lt;br&gt;&lt;br&gt;
Just skill and execution&lt;/p&gt;

&lt;p&gt;And with that alone, I closed a $150,000 contract to build a full-scale SNS platform from the ground up&lt;/p&gt;

&lt;p&gt;This post isn’t about bragging&lt;br&gt;&lt;br&gt;
It’s about showing you that you don’t need credentials when you can provide undeniable value&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Did (That Most Don’t)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. I shut up and learned to build
&lt;/h3&gt;

&lt;p&gt;I didn’t waste my time posting “day 34 of building my startup” or preaching on LinkedIn&lt;br&gt;&lt;br&gt;
I spent my time mastering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full stack engineering (React, NestJS, PostgreSQL, etc.)&lt;/li&gt;
&lt;li&gt;Real world infrastructure (GCP, Docker, Firebase, Cloud Run)&lt;/li&gt;
&lt;li&gt;Clean architecture, auth systems, deployment pipelines&lt;/li&gt;
&lt;li&gt;Systems that actually scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While others were building MVPs with no understanding of backend security or performance, I built real, working apps&lt;/p&gt;

&lt;h3&gt;
  
  
  2. I made my skills public through work
&lt;/h3&gt;

&lt;p&gt;No resumes. Just output&lt;br&gt;&lt;br&gt;
I didn’t tell people I could build, I showed them&lt;/p&gt;

&lt;p&gt;I took smaller gigs early, overdelivered, built trust, and made sure everything I touched was undeniably professional&lt;br&gt;&lt;br&gt;
Design. Docs. Architecture. Deployment&lt;br&gt;&lt;br&gt;
All clean. All tight&lt;/p&gt;

&lt;p&gt;When the $150K opportunity came, there was no question of "can you handle this"&lt;br&gt;&lt;br&gt;
They already knew I could&lt;/p&gt;

&lt;h3&gt;
  
  
  3. I didn’t act like a founder, I acted like an engineer
&lt;/h3&gt;

&lt;p&gt;I didn’t wear a fake CEO badge or pretend I was changing the world&lt;br&gt;&lt;br&gt;
I scoped the problem, broke it down, communicated clearly, and delivered a real execution plan&lt;/p&gt;

&lt;p&gt;That alone made me stand out more than any mission statement ever could&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Worked
&lt;/h2&gt;

&lt;p&gt;Because companies don’t care about your startup story&lt;br&gt;&lt;br&gt;
They care about whether you can deliver something that works, that scales, and that solves a problem&lt;/p&gt;

&lt;p&gt;I didn’t pretend to be a visionary&lt;br&gt;&lt;br&gt;
I just did the work, and that work turned into value which turned into a $150K payout&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Words
&lt;/h2&gt;

&lt;p&gt;If you’re young and trying to get in&lt;br&gt;&lt;br&gt;
Stop trying to look impressive. Be useful&lt;br&gt;&lt;br&gt;
Stop preaching about disruption. Start delivering output&lt;br&gt;&lt;br&gt;
Let your craft speak for itself&lt;/p&gt;

&lt;p&gt;Because in the end&lt;br&gt;&lt;br&gt;
Value over virtue signaling&lt;br&gt;&lt;br&gt;
Results over resumes&lt;br&gt;&lt;br&gt;
Execution over excuses&lt;/p&gt;

&lt;p&gt;I’m 20, I didn’t go to college, and I’m already profiting with skill alone&lt;br&gt;&lt;br&gt;
You can too if you stop playing the game everyone else is playing&lt;/p&gt;

</description>
      <category>programming</category>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Why I Never Use Optimistic Updates (And Why You Might Regret It Too)</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sat, 19 Apr 2025 14:16:57 +0000</pubDate>
      <link>https://dev.to/criscmd/why-i-never-use-optimistic-updates-and-why-you-might-regret-it-too-4jem</link>
      <guid>https://dev.to/criscmd/why-i-never-use-optimistic-updates-and-why-you-might-regret-it-too-4jem</guid>
      <description>&lt;p&gt;If you’ve built anything with React, Vue, or any modern frontend framework, you’ve probably come across the idea of &lt;strong&gt;optimistic UI updates&lt;/strong&gt;. It sounds fancy. It sounds fast. It even feels good. Until it doesn’t.&lt;/p&gt;

&lt;p&gt;Let me tell you why I almost &lt;em&gt;never&lt;/em&gt; update state optimistically anymore, and why you might want to think twice before doing it too.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ What Is an Optimistic Update?
&lt;/h2&gt;

&lt;p&gt;Optimistic updates mean changing the UI &lt;em&gt;before&lt;/em&gt; you know if the backend operation actually succeeded. For example, you click "like" on a post, and the heart icon turns red &lt;em&gt;immediately&lt;/em&gt;, before the API call finishes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setLiked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// optimistic update&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;likePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something fails, you roll it back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setLiked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// rollback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seems harmless, right?&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ Why I Stopped Using Optimistic Updates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Edge Cases Multiply Fast&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every time you write an optimistic update, you're creating an alternate reality. Now you have to write logic to reconcile the optimistic state with the real state if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The request fails&lt;/li&gt;
&lt;li&gt;The data changes from another tab or user&lt;/li&gt;
&lt;li&gt;The user undoes the action before the request finishes&lt;/li&gt;
&lt;li&gt;The server responds with something unexpected like validation or sanitization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s four edge cases for &lt;em&gt;one&lt;/em&gt; button. Multiply that across a large app and your UI becomes a ticking time bomb.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;strong&gt;Rollbacks Are a UX Nightmare&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Users hate seeing the UI revert. Imagine typing a message, seeing it appear instantly, and then it disappears because the server threw a 500.&lt;/p&gt;

&lt;p&gt;Yes, you can show toasts like “Action failed,” but most people don’t read those. It just &lt;em&gt;feels&lt;/em&gt; like your app is broken or buggy.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;strong&gt;It Breaks Consistency&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your UI state and your backend state go out of sync &lt;em&gt;on purpose&lt;/em&gt; when you use optimistic updates. That’s dangerous.&lt;/p&gt;

&lt;p&gt;Consistency between client and server is everything in multi-user apps. If you break that contract, you introduce bugs that are extremely hard to debug, especially when multiple users are involved.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;strong&gt;You’re Not Facebook&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Optimistic updates are mostly popularized by companies that can afford &lt;em&gt;massive&lt;/em&gt; infra and logic to handle them properly.&lt;/p&gt;

&lt;p&gt;You probably have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A few devs, maybe just you&lt;/li&gt;
&lt;li&gt;No conflict resolution backend&lt;/li&gt;
&lt;li&gt;No retry queue&lt;/li&gt;
&lt;li&gt;No live event stream syncing the UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without all of that, optimism is a luxury you can’t afford.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What I Do Instead: Pessimistic + Immediate Feedback
&lt;/h2&gt;

&lt;p&gt;I do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;likePost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setLiked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And optionally show a spinner or skeleton. Sure, it's 100 to 300 ms slower, but I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t need to roll anything back&lt;/li&gt;
&lt;li&gt;Don’t need to guess what the server will return&lt;/li&gt;
&lt;li&gt;Keep the UI and backend state &lt;strong&gt;always in sync&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Avoid writing extra logic for "what if it fails"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clean code. Predictable behavior. No surprise bugs at 3 am.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 When I &lt;em&gt;Do&lt;/em&gt; Use Optimistic Updates
&lt;/h2&gt;

&lt;p&gt;Okay, I lied a little. I’ll use optimistic updates &lt;strong&gt;if and only if&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The failure state doesn't matter, like liking a post that no one else sees&lt;/li&gt;
&lt;li&gt;The action is &lt;em&gt;idempotent&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;I have background sync or retry logic&lt;/li&gt;
&lt;li&gt;I’m willing to tolerate inconsistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most CRUD apps, not worth it.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Optimistic updates are like gambling. Sometimes you win. But when you lose, the debugging cost is &lt;em&gt;massive&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Instead of betting that your API won't fail, just build for the world we live in. A world where servers crash, networks flake, and users click faster than requests resolve.&lt;/p&gt;

&lt;p&gt;You don’t need optimism. You need &lt;strong&gt;resilience&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;✍️ What do you think? Do you use optimistic updates in your app? Have they bitten you before? Let’s talk in the comments.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>backend</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 How I Boosted Slack RAG Accuracy by 5–6% with Smarter Chunking</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 06 Apr 2025 04:53:56 +0000</pubDate>
      <link>https://dev.to/criscmd/how-i-boosted-slack-rag-accuracy-by-5-6-with-smarter-chunking-1kf9</link>
      <guid>https://dev.to/criscmd/how-i-boosted-slack-rag-accuracy-by-5-6-with-smarter-chunking-1kf9</guid>
      <description>&lt;p&gt;I recently worked on improving chunking strategies for a Slack text RAG (Retrieval-Augmented Generation) system, and I wanted to share my approach — especially for those dealing with chaotic, real-world conversational data.&lt;/p&gt;

&lt;p&gt;When you’re trying to retrieve relevant context from Slack conversations, naive chunking can lead to fragmented or unhelpful responses. So I combined &lt;strong&gt;three different chunking strategies&lt;/strong&gt; to make the data &lt;em&gt;much&lt;/em&gt; richer and improve retrieval quality.&lt;/p&gt;

&lt;p&gt;By doing this, I saw about a &lt;strong&gt;5–6% increase in accuracy&lt;/strong&gt;, and interestingly, the system gets &lt;em&gt;even more accurate&lt;/em&gt; as more data is added. 📈&lt;/p&gt;

&lt;p&gt;Let’s dive in! 🧩&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 The Problem: Slack Conversations Are Messy
&lt;/h2&gt;

&lt;p&gt;Slack messages are fast-paced and fragmented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conversations happen across multiple channels.&lt;/li&gt;
&lt;li&gt;Threads are scattered.&lt;/li&gt;
&lt;li&gt;Messages are often short and informal.&lt;/li&gt;
&lt;li&gt;Context gets lost easily if you chunk blindly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My goal was to feed high-quality chunks into the vector store for better context retrieval, especially for RAG systems. So I experimented with multiple chunking techniques to capture as much context as possible in each chunk.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Strategy 1: Token-Based Chunking (Contextual Enrichment)
&lt;/h2&gt;

&lt;p&gt;The first thing I implemented was &lt;strong&gt;token-based chunking&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of chunking by a fixed number of messages, I chunked by token count (e.g., ~500 tokens per chunk). This ensured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each chunk was dense with meaningful information.&lt;/li&gt;
&lt;li&gt;I avoided splitting messages awkwardly.&lt;/li&gt;
&lt;li&gt;I could control the input size for my LLM efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bonus: Token-based chunking allowed me to enrich each chunk with metadata (timestamps, user IDs, thread info) while staying within token limits.&lt;/p&gt;

&lt;p&gt;📝 &lt;strong&gt;Why it matters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Token limits are very real when you’re dealing with LLMs. Efficient token-based chunking helps maximize signal while respecting those limits.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⏱️ Strategy 2: Timestamp-Based Chunking (5-Minute Windows)
&lt;/h2&gt;

&lt;p&gt;Slack conversations often happen in bursts.&lt;br&gt;&lt;br&gt;
To capture that natural rhythm, I implemented &lt;strong&gt;timestamp-based chunking&lt;/strong&gt;, grouping all messages within a 5-minute window.&lt;/p&gt;

&lt;p&gt;This helped me capture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natural conversation flow.&lt;/li&gt;
&lt;li&gt;Real-time back-and-forth.&lt;/li&gt;
&lt;li&gt;Standalone short discussions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📝 &lt;strong&gt;Why it matters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
By keeping chunks within natural conversational timeframes, retrieval felt &lt;em&gt;more human&lt;/em&gt;. When the model retrieved context, it got the full flow of that moment in time.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧵 Strategy 3: Thread-Based Chunking
&lt;/h2&gt;

&lt;p&gt;Slack threads are goldmines of context.&lt;br&gt;&lt;br&gt;
To avoid fragmenting them, I chunked &lt;strong&gt;entire threads as a single chunk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every reply and reaction in a thread stayed together.&lt;/li&gt;
&lt;li&gt;I avoided splitting up follow-up questions and answers.&lt;/li&gt;
&lt;li&gt;Models could "read" the whole conversation without gaps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📝 &lt;strong&gt;Why it matters:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Thread-based chunking keeps related ideas intact, which is critical for meaningful retrieval in Q&amp;amp;A scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 The Impact: 5–6% Accuracy Boost (And It Scales!)
&lt;/h2&gt;

&lt;p&gt;By combining these three strategies, my Slack RAG system became noticeably smarter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ More relevant context retrieved.&lt;/li&gt;
&lt;li&gt;✅ Better grounding for generation tasks.&lt;/li&gt;
&lt;li&gt;✅ Less noise in retrieval results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I measured about a &lt;strong&gt;5–6% increase in retrieval accuracy&lt;/strong&gt;, and I noticed something exciting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The accuracy improves even further as the dataset grows.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes sense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The richer the chunks, the better your embeddings.&lt;/li&gt;
&lt;li&gt;As you add more data, there’s a higher chance of finding meaningful matches.&lt;/li&gt;
&lt;li&gt;Chunking effectively compounds its benefits over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re scaling your data ingestion, this is an optimization that keeps giving back!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Takeaways for Your RAG System
&lt;/h2&gt;

&lt;p&gt;If you’re building any RAG system, especially with noisy chat data, I &lt;em&gt;highly&lt;/em&gt; recommend combining chunking strategies.&lt;/p&gt;

&lt;p&gt;Here’s your actionable playbook:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Token-based chunking&lt;/strong&gt; to manage LLM input limits efficiently.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Timestamp chunking&lt;/strong&gt; to preserve natural conversation flow.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Thread chunking&lt;/strong&gt; to keep full discussions intact.&lt;/li&gt;
&lt;li&gt;✅ And remember: the bigger your dataset, the more these strategies shine! 📈&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Experiment and find the right balance for your use case.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Pro Tip
&lt;/h2&gt;

&lt;p&gt;Consider layering these strategies together:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;First, chunk by thread.&lt;br&gt;&lt;br&gt;
Then, within threads, chunk by token count if they’re too big.&lt;br&gt;&lt;br&gt;
For non-threaded conversations, use timestamp-based chunking to group messages naturally.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a multi-step process, but the quality of your retrieval will thank you.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 What’s Next?
&lt;/h2&gt;

&lt;p&gt;I’m thinking about pushing this even further by exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hybrid chunking (e.g., timestamp + thread + token cap).&lt;/li&gt;
&lt;li&gt;Sentiment-aware chunking (grouping emotional bursts together).&lt;/li&gt;
&lt;li&gt;Speaker role-based chunking (grouping moderator/admin messages separately).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would love to hear your thoughts — how are you handling chunking in your RAG systems? Drop a comment below! 🚀&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>discuss</category>
    </item>
    <item>
      <title>🧪 Types of Software Testing and What They Actually Accomplish</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Fri, 28 Mar 2025 14:54:43 +0000</pubDate>
      <link>https://dev.to/criscmd/types-of-software-testing-and-what-they-actually-accomplish-4b7</link>
      <guid>https://dev.to/criscmd/types-of-software-testing-and-what-they-actually-accomplish-4b7</guid>
      <description>&lt;p&gt;Whether you're launching a new feature, shipping a hotfix, or building a system from the ground up, &lt;strong&gt;testing&lt;/strong&gt; is what keeps your code safe, sane, and solid. But with all the buzzwords flying around—unit tests, integration tests, E2E—it's easy to get lost.&lt;/p&gt;

&lt;p&gt;So let’s break down the main types of software testing, what they &lt;strong&gt;actually&lt;/strong&gt; accomplish, and when you should use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 1. Unit Testing: Test the Smallest Pieces
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tests &lt;strong&gt;individual functions or methods&lt;/strong&gt; in isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To verify that each "unit" of your code (like a function or class) works as expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript: Jest, Mocha
&lt;/li&gt;
&lt;li&gt;Python: unittest, pytest
&lt;/li&gt;
&lt;li&gt;Java: JUnit
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&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="c1"&gt;// JavaScript example&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds 2 + 3 to equal 5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&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;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catches bugs early
&lt;/li&gt;
&lt;li&gt;Makes refactoring easier
&lt;/li&gt;
&lt;li&gt;Improves code reliability
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 2. Integration Testing: Test How Pieces Work Together
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tests &lt;strong&gt;multiple components or modules working together&lt;/strong&gt; (e.g., database + backend).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To ensure integrations between services, modules, or layers (like API ↔️ DB) are functioning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Postman
&lt;/li&gt;
&lt;li&gt;Supertest
&lt;/li&gt;
&lt;li&gt;Pytest (Python)
&lt;/li&gt;
&lt;li&gt;Spring Test (Java)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test that a REST API endpoint creates a new user in the database correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catches issues with data flow
&lt;/li&gt;
&lt;li&gt;Verifies contracts between components
&lt;/li&gt;
&lt;li&gt;Prevents regression when APIs change
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌐 3. End-to-End (E2E) Testing: Test the Whole App Like a User
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tests the &lt;strong&gt;entire application from the user’s perspective&lt;/strong&gt;, from frontend to backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To simulate real user scenarios and verify the app works as expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cypress
&lt;/li&gt;
&lt;li&gt;Playwright
&lt;/li&gt;
&lt;li&gt;Selenium
&lt;/li&gt;
&lt;li&gt;Puppeteer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in → Navigate to dashboard → Create a post → Verify it appears&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirms the system works as a whole
&lt;/li&gt;
&lt;li&gt;Detects real-world failures
&lt;/li&gt;
&lt;li&gt;Increases confidence before release
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔄 4. Regression Testing: Test Old Features After New Changes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Re-running old test cases to ensure &lt;strong&gt;existing functionality still works&lt;/strong&gt; after updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To prevent bugs from creeping back into previously working code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usually done using:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated test suites (unit + integration + E2E)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures stability with each release
&lt;/li&gt;
&lt;li&gt;Helps maintain trust in legacy systems
&lt;/li&gt;
&lt;li&gt;Reduces risk during updates/refactors
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  👀 5. Manual Testing: Human-Powered Validation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Testing done &lt;strong&gt;manually by a tester or developer&lt;/strong&gt;, clicking around and verifying behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To catch UI/UX issues, edge cases, or things automation can’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Great for:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploratory testing
&lt;/li&gt;
&lt;li&gt;Usability testing
&lt;/li&gt;
&lt;li&gt;Complex interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detects subtle bugs or weird behavior
&lt;/li&gt;
&lt;li&gt;Validates user experience
&lt;/li&gt;
&lt;li&gt;Complements automated tests
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 6. Acceptance Testing: Meet the Requirements
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tests whether the &lt;strong&gt;product meets business requirements&lt;/strong&gt; and is ready for delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To verify that the software does what the stakeholder or customer expects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cucumber (BDD)
&lt;/li&gt;
&lt;li&gt;FitNesse
&lt;/li&gt;
&lt;li&gt;Manual acceptance checklists&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures business logic is correct
&lt;/li&gt;
&lt;li&gt;Helps align devs and stakeholders
&lt;/li&gt;
&lt;li&gt;Validates "done" criteria before shipping
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔐 7. Security Testing: Stay Safe Out There
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Testing focused on &lt;strong&gt;vulnerabilities, data protection, and access control&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To find security holes like XSS, SQL Injection, broken auth, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OWASP ZAP
&lt;/li&gt;
&lt;li&gt;Burp Suite
&lt;/li&gt;
&lt;li&gt;Static code analysis tools (Snyk, SonarQube)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protects against exploits
&lt;/li&gt;
&lt;li&gt;Builds user trust
&lt;/li&gt;
&lt;li&gt;Ensures compliance (HIPAA, GDPR, etc.)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ 8. Performance &amp;amp; Load Testing: Can It Handle the Heat?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Tests how your app performs under &lt;strong&gt;load, stress, and varying conditions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
To find bottlenecks, memory leaks, or scalability issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apache JMeter
&lt;/li&gt;
&lt;li&gt;k6
&lt;/li&gt;
&lt;li&gt;Gatling
&lt;/li&gt;
&lt;li&gt;Locust (Python)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it accomplishes:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures smooth experience under traffic
&lt;/li&gt;
&lt;li&gt;Prepares systems for scaling
&lt;/li&gt;
&lt;li&gt;Avoids crashes on launch day 🚀
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔁 Bonus: Smoke &amp;amp; Sanity Testing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smoke Testing:&lt;/strong&gt; A quick check to see if the &lt;strong&gt;core functions work&lt;/strong&gt; before diving deeper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanity Testing:&lt;/strong&gt; Verifying a &lt;strong&gt;small change or fix&lt;/strong&gt; didn’t break related features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of them as your morning coffee checks ☕—quick sanity savers.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Software testing isn't just a checkbox—it's a mindset.&lt;br&gt;&lt;br&gt;
Each type of test plays a unique role in protecting your codebase and giving you the confidence to ship faster, safer, and smarter.&lt;/p&gt;

&lt;p&gt;Here’s the cheat sheet:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Type&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;When to Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;Test individual functions&lt;/td&gt;
&lt;td&gt;During development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integration&lt;/td&gt;
&lt;td&gt;Test connections between parts&lt;/td&gt;
&lt;td&gt;After modules are complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End-to-End&lt;/td&gt;
&lt;td&gt;Simulate real user behavior&lt;/td&gt;
&lt;td&gt;Before major releases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regression&lt;/td&gt;
&lt;td&gt;Ensure nothing broke after changes&lt;/td&gt;
&lt;td&gt;Every sprint/release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Catch UI/UX bugs humans notice&lt;/td&gt;
&lt;td&gt;For exploratory sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acceptance&lt;/td&gt;
&lt;td&gt;Meet stakeholder expectations&lt;/td&gt;
&lt;td&gt;Before sign-off/delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Protect against vulnerabilities&lt;/td&gt;
&lt;td&gt;Regular security audits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Check scalability and speed&lt;/td&gt;
&lt;td&gt;Before high-traffic launches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;💬 Got a favorite testing setup or war story from production? Let’s talk in the comments!&lt;br&gt;
🛠️ Follow me for more dev deep-dives, architecture tips, and real-world engineering breakdowns.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
