<?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: Favor Charles Owuor</title>
    <description>The latest articles on DEV Community by Favor Charles Owuor (@fcharles).</description>
    <link>https://dev.to/fcharles</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%2F3718960%2F45a605d6-431f-4c09-a25b-97266a22a9c7.jpg</url>
      <title>DEV Community: Favor Charles Owuor</title>
      <link>https://dev.to/fcharles</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fcharles"/>
    <language>en</language>
    <item>
      <title>Why you should Deploy early and often</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Fri, 29 May 2026 14:15:19 +0000</pubDate>
      <link>https://dev.to/fcharles/why-you-should-deploy-early-and-often-27ie</link>
      <guid>https://dev.to/fcharles/why-you-should-deploy-early-and-often-27ie</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FCGDTJS8%2F7090038.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FCGDTJS8%2F7090038.jpg" alt="7090038" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.magnific.com/free-vector/hand-drawn-flat-design-api-illustration_25632103.htm" rel="noopener noreferrer"&gt;Image by freepik&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create a project and ensure it has all the features first then and only then can I deploy it. That's something most of us have done, right? Though you may have not thought or said the same thing word for word, but it's something that just happens sub-consciencely. Basically like habit and it does not seem to have any issues. So why would you change your current normal balance to now start deploying work that's incomplete? Let's explore this question together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy early and often
&lt;/h2&gt;

&lt;p&gt;This is a software development philosophy that prioritizes frequent, smaller releases over long, feature-heavy development cycles. This approach creates a rapid, tight feedback loop with users while eliminating the risk of building software no one actually wants. It's also known as RERO: Release Early, Release Often&lt;/p&gt;

&lt;p&gt;The thing is, your project might work fast and efficiently in your local host environment. Where there is one user, the hardware would be dedicated to that task alone at the time of testing, and no major issues. But when you deploy there's differences in latency, infrastructure and the users. &lt;/p&gt;

&lt;p&gt;I heard from another developer that he once deployed a website and minutes later the site crashed. Reason being, one of the users had sent many requests in a short period of time. Another one's account creation failed because they added an emoji to their user name. &lt;/p&gt;

&lt;p&gt;These are all variables that would not be considered in a local environment. Putting your work out there as you develop it allows you to identify weak points and problems you normally wouldn't experience alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Deploy Early and Often?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;  &lt;strong&gt;Faster Feedback Loops:&lt;/strong&gt; 
Getting a Minimum Viable Product (MVP) to users early ensures customer preferences guide the product, saving hundreds of hours of guesswork. They can also show errors and issues that the product may have that you may not have seen in the planning or creation process&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Easier Debugging:&lt;/strong&gt;
Deploying smaller batches of code makes tracking down and fixing bugs easier, as there are fewer variables and lines of code changed at any given time.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reduced Release Stress:&lt;/strong&gt; 
Long periods between releases generate pressure, making deployments risky and complicated. Making deployments a normal, frequent occurrence turns them into a routine, and low risk.
When you have many features at hand and want to release them all at once the likely hood of one of them failing silently is high. 
I once deployed a project and there were many silent errors in different parts, but when looking at the code, there were no error indicators anywhere. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Higher Quality:&lt;/strong&gt; 
It shifts the mindset from chasing "full-featured perfection" to continuous improvement and user-defined validation. 
It's better to work step by step and "perfect" features as you go. Since you will be sure of the working features, your attitude towards the project rises as stress reduces since you have the time and effort dedicated to making the next thing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Implement It Effectively
&lt;/h2&gt;

&lt;p&gt;Deploying isn't just one and done. You need to implement and use the proper tools and practices to ensure a smooth development journey. If done right It will allow you to focus on creation and innovation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automation:&lt;/strong&gt; &lt;br&gt;
Use a CI/CD (Continuous Integration/Continuous Deployment) pipeline that automatically builds, tests, and deploys code changes. This makes it so that you always deploy projects that are stable and work according to spec&lt;br&gt;
   &lt;strong&gt;Feature Flags:&lt;/strong&gt;&lt;br&gt;
 Utilize feature flags (toggles) to merge features into the main branch but hide them from users until they are officially ready. This allows continuous deployment without exposing incomplete features. You may have select users as testers. They will ascertain if the features that you have pushed work as intended.&lt;br&gt;
  &lt;strong&gt;Solid Rollback Plans:&lt;/strong&gt; &lt;br&gt;
 When automating deployments, ensure your infrastructure allows you to quickly roll back to the previous stable version if something breaks. This is more frequent than one might realize. You might push a feature to production, then it breaks everything. It's important to note that having versions that are close in terms of times they were developed makes it easier to restore. That's why having updates that are few and far between can really hurt when the rollback happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A product that “works but", fails at the critical moment is  of eploy early and often help you frustrating, and most developers have experienced it. That’s why the ideaa bitter experience I'm sure most of us have experienced. But having the concept of "Deploy early and often” matters. It" though long can helps you catch issues sooner, improve reliability, and keep your system ready for real use at any timebuild better and working systems always ready for action. If you haven’t started doing this yet, now is a good time as any. It'll save you a lot of stress and worries in the long run.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
      <category>productivity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Beginner steps into CI/CD</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Tue, 26 May 2026 09:28:22 +0000</pubDate>
      <link>https://dev.to/fcharles/beginner-steps-into-cicd-55df</link>
      <guid>https://dev.to/fcharles/beginner-steps-into-cicd-55df</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FGwHv0tx%2Fherro.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FGwHv0tx%2Fherro.jpg" alt="herro" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.magnific.com/free-vector/flat-design-technology-devops-illustration_24746653.htm" rel="noopener noreferrer"&gt;Image by freepik&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most people me included, just use Github as kind of like an online store for code. But this application has more to it than meets the eye. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is CI/CD
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FHfQJzj2F%2Fci-cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FHfQJzj2F%2Fci-cd.png" alt="ci cd" width="800" height="606"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Continuous Integration (CI):&lt;/strong&gt; Is the of automation of the process of merging code changes. It's typically trigged on every &lt;code&gt;push&lt;/code&gt; or &lt;code&gt;pull request&lt;/code&gt;, running automated tests and builds to detect bugs early.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Continuous Deployment/Delivery (CD):&lt;/strong&gt; Automatically prepares or pushes tested code to a production environment once the CI checks pass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These series of events can help cut down on the time and effort spent on the manual tasks. They can be summarized in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FqFjgjR70%2Fproper-ci-cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FqFjgjR70%2Fproper-ci-cd.png" alt="proper ci cd" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How you can do it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Create your workflows
&lt;/h3&gt;

&lt;p&gt;In CI, there's four key concepts one should know i.e. trigger, workflow, job and step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A trigger is what will cause the CI process to start&lt;/li&gt;
&lt;li&gt;Workflow is the automation file(.yml)&lt;/li&gt;
&lt;li&gt;Job is a group of steps on one machine&lt;/li&gt;
&lt;li&gt;Step is a single command or action&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To begin we first create a .github directory. Inside we create a workflows folder. Inside we create out ci.yml file. The structure should look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FwZZS52BQ%2FScreenshot-2026-05-26-083904.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FwZZS52BQ%2FScreenshot-2026-05-26-083904.png" alt="Screenshot 2026 05 26 083904" width="286" height="196"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Define triggers
&lt;/h3&gt;

&lt;p&gt;For this instance we want the process to start when someone performs a pr but you can set it to push as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI Pipeline&lt;/span&gt;

&lt;span class="c1"&gt;# TRIGGERS&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Define Jobs
&lt;/h3&gt;

&lt;p&gt;Jobs work in Isolated Environments. Every job runs inside its own fresh virtual machine (called a runner), such as Ubuntu, Windows, or macOS.&lt;br&gt;
If your workflow has multiple jobs, GitHub runs them at the same time to save time.&lt;br&gt;
 A job groups together a series of sequential tasks (steps) that handle the actual work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# JOBS&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt; &lt;span class="c1"&gt;# The machine to use&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Define Steps
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt; are the individual, sequential tasks that execute inside a single job. They run one after another, in the exact order they are listed in the YAML file.&lt;br&gt;
All steps in a single job run on the same virtual machine instance. If Step 1 creates a file or installs a package, Step 2 can use it.&lt;br&gt;
In case any step fails (returns an error code), the job stops immediately, and the remaining steps are skipped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Step 1: Get the code&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Github code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="c1"&gt;# Step 2: Set up Node.js&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;20'&lt;/span&gt;
        &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That there was a simple CI pipeline now of to the CD.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Deployment cycle
&lt;/h3&gt;

&lt;p&gt;Similar to the CI structure, the CD is also made in the same structure but the steps differ. &lt;br&gt;
They go from tests, if they pass then to the build. Upon successful build the project is then staged and finally pushed to production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Prevent multiple deployments at once&lt;/span&gt;
&lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deployment&lt;/span&gt;
  &lt;span class="na"&gt;cancel-in-progress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# First: Run tests&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Tests&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;

  &lt;span class="c1"&gt;# Second: Build the project&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;

  &lt;span class="c1"&gt;# Third: Deploy to staging&lt;/span&gt;
  &lt;span class="na"&gt;deploy-staging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Staging&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;staging&lt;/span&gt;        &lt;span class="c1"&gt;# Requires environment approval (optional)&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;

  &lt;span class="c1"&gt;# Fourth: Deploy to production (manual approval)&lt;/span&gt;
  &lt;span class="na"&gt;deploy-production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy-staging&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;     &lt;span class="c1"&gt;# Can require manual approval in GitHub settings&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is just an example, to better understand see the video &lt;a href="https://www.youtube.com/watch?v=0PbxpIao_EU" rel="noopener noreferrer"&gt;here&lt;/a&gt; or see this &lt;a href="https://github.com/shazforiot/github-actions-demo" rel="noopener noreferrer"&gt;github repo&lt;/a&gt;. It will provide a wider view and context&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do this
&lt;/h2&gt;

&lt;p&gt;Short answer: Speed. Organizations that have mastered the CI/CD, build and deploy products faster than others. Since products are always being rated and feedback being provided. Developers commit smaller changes more often, hence keeping up with customer demands.&lt;br&gt;
With ongoing feedback, developers are constantly making small changes. &lt;br&gt;
Automated continuous testing ensures that the codebases remain stable and ready for deployment at all times. Since the manual tasks are taken care of with this automation, developers can focus on creation, innovation, and other important tasks&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I'm also still learning about this concept and implementing it into my own workflow. It's a core skill that I believe every developer should enforce in their workflows especially junior developers. It's a major time saver and also ensures you always have working code ready for production.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
    </item>
    <item>
      <title>Logs in code</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Mon, 25 May 2026 11:44:00 +0000</pubDate>
      <link>https://dev.to/fcharles/logs-in-code-58hi</link>
      <guid>https://dev.to/fcharles/logs-in-code-58hi</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2obhcta0ppfl6raefxo9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2obhcta0ppfl6raefxo9.jpg" alt="alt text" width="800" height="422"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;&lt;small&gt;Image from thumbs.dreamstime.com&lt;/small&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When writing code, many developers especially junior level, don't understand the importance of having logs in their code. I was also a victim of this. This article will delve a bit into the importance of logs in your development cycle and how you can implement them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance
&lt;/h2&gt;

&lt;p&gt;So recently I've been developing a personal finance tool. When trying to do add a transaction performed it brings errors but they don't state where the issue is.&lt;/p&gt;

&lt;p&gt;This is what is be displayed on the website:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FskmPh6f%2Fwebsite-error.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FskmPh6f%2Fwebsite-error.png" alt="website error" width="637" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shows there's an issue in the way the time is being parsed. The bigger issue is that the error message is being displayed to the user which is a mistake on my part. Still, this would be better shown in the logs. As for the logs, this is what is displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FrKc2TYwb%2Frender-normal-log.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FrKc2TYwb%2Frender-normal-log.png" alt="render normal log" width="792" height="47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The image just shows that there was a bad request and nothing else, no context. So I didn't even know where to begin with in terms of fixing my code.&lt;/p&gt;

&lt;p&gt;Back to the matter at hand, the importance of adding logs to your code. So what exactly is logging?&lt;/p&gt;

&lt;p&gt;Logging can be defined as writing text describing what’s been happening in your program to a file or other storage system. Logging is essential for debugging and troubleshooting. When there's a bug, you need to find out which specific part of the program is broken, because it’s often not the part that’s visibly acting weird. This is often the first step in addressing a new bug after  &lt;a href="https://www.thecodedmessage.com/posts/reproducibility/" rel="noopener noreferrer"&gt;reproducing it&lt;/a&gt;, or even part of figuring out how to reproduce it.&lt;/p&gt;

&lt;p&gt;In fact, logs can be helpful at every stage of the debugging process. You have to confirm your assumptions on what parts are known to work. After all, the whole program is supposed to work, and often times, the thing that’s broken is something that you would’ve assumed definitely worked.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to implement it
&lt;/h2&gt;

&lt;p&gt;So I got to work and added a few lines of code to see the actual reason why the transactions were not being created.:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FVcFBB0PR%2Fadded-logging.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FVcFBB0PR%2Fadded-logging.png" alt="added logging" width="612" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code initially just returned the err, but the slog.Error code allows for a more detailed error to be shown in the logs. Like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FN6tR8RsP%2Fupdated-lines.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FN6tR8RsP%2Fupdated-lines.png" alt="updated lines" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The line in red is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;{&lt;br&gt;
"time":"2026-05-25T10:47:02.872094934Z",&lt;br&gt;
"level":"ERROR",&lt;br&gt;
"msg":"CreateTransactions failed",&lt;br&gt;
"user_id":"a7e2fa58-712c-4fed-9783-35272ea7e2a1",&lt;br&gt;
"account_id":"1ad6e60e-b104-4dc4-91d7-b22de26ee972",&lt;br&gt;
"amount":2300,&lt;br&gt;
"type":"expense",&lt;br&gt;
&lt;strong&gt;"error":"Type can only be income or exepense"&lt;/strong&gt;&lt;br&gt;
}&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see in the logs, the error is more detailed and I can see that the error is a typo in my own code base, since it is an error 500(internal). So Upon closer inspection of my code I realized, that I wrote something entirely different. &lt;/p&gt;

&lt;p&gt;Instead of expense I wrote:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FsTsrS1L%2Ferror-expense.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.ibb.co%2FsTsrS1L%2Ferror-expense.png" alt="error expense" width="403" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's an error on my part(coding while tired). but I wouldn't have known to go back to my code and  check, if I didn't have that error message.&lt;/p&gt;

&lt;p&gt;So for you the reader you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Choose a Standard Library or Framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avoid using &lt;code&gt;print()&lt;/code&gt; for permanent logging, as it lacks control over levels and destinations. Use established tools for your language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Python:&lt;/strong&gt; The built-in &lt;a href="https://docs.python.org/3/library/logging.html" rel="noopener noreferrer"&gt;logging module&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Java:&lt;/strong&gt; &lt;a href="https://logging.apache.org/log4j/2.3.x/javadoc.html" rel="noopener noreferrer"&gt;Log4j2&lt;/a&gt; or Logback via SLF4J.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Node.js:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/winston" rel="noopener noreferrer"&gt;Winston&lt;/a&gt; or Bunyan.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Go&lt;/strong&gt;: &lt;a href="https://pkg.go.dev/log" rel="noopener noreferrer"&gt;Log&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Rust:&lt;/strong&gt; &lt;a href="https://crates.io/crates/log" rel="noopener noreferrer"&gt;The log crate facade&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Define Severity Levels&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Categorizing messages will allow you to filter logs in different environments (e.g., show only errors in production but everything in development).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;DEBUG:&lt;/strong&gt; Detailed information for diagnosing problems during development.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;INFO:&lt;/strong&gt; Confirmation that things are working as expected (e.g., service started).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;WARNING:&lt;/strong&gt; Indication that something unexpected happened, but the software is still working.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;ERROR:&lt;/strong&gt; Serious problems where a specific function failed to execute.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;CRITICAL:&lt;/strong&gt; Fatal errors indicating the program itself may be unable to continue. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Configure Loggers, Handlers, and Formatters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A strong setup has three main components: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Loggers:&lt;/strong&gt; The entry point where your code sends messages (e.g., &lt;code&gt;logger.info("Starting process")&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Handlers (Appenders):&lt;/strong&gt; Determine where the logs go—such as the console, a local file, or a remote server.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Formatters:&lt;/strong&gt; Define the layout of the log message. A standard format includes: &lt;code&gt;[Timestamp] [Level] [Source/Module] [Message]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Best Practices for Better Logs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Structured Logging:&lt;/strong&gt; Use JSON or key-value pairs instead of plain text to make logs easily searchable by machines.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Include Context:&lt;/strong&gt; Log useful identifiers like &lt;code&gt;user_id&lt;/code&gt; or &lt;code&gt;transaction_id&lt;/code&gt;, but &lt;strong&gt;never&lt;/strong&gt; log sensitive data like passwords or credit card numbers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Log Exceptions:&lt;/strong&gt; In &lt;code&gt;try-except&lt;/code&gt; blocks, use &lt;code&gt;logger.exception()&lt;/code&gt; to automatically capture the full stack trace.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use UTC Timestamps:&lt;/strong&gt; Standardizing on UTC avoids confusion when working across different time zones.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Centralize Configuration:&lt;/strong&gt; Configure logging once at the project's entry point (e.g., your &lt;code&gt;main.py&lt;/code&gt; or &lt;code&gt;App.java&lt;/code&gt;) rather than in every individual file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Working with logs has saved me a lot of time in debugging and looking for errors where none can be seen. In development its easier to spot issues but in production it can be a nightmare. I encourage every developer especially the beginners to start using logs as early as your current project. It'll save you a lot of time and make your development journey a little bit easier.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>go</category>
      <category>development</category>
    </item>
    <item>
      <title>Understanding Back-End Project Structures in Go: A Guide to Separate Concerns</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Wed, 11 Mar 2026 10:11:18 +0000</pubDate>
      <link>https://dev.to/fcharles/understanding-back-end-project-structures-in-go-a-guide-to-separate-concerns-9ef</link>
      <guid>https://dev.to/fcharles/understanding-back-end-project-structures-in-go-a-guide-to-separate-concerns-9ef</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9l0mov05wqmk6sucwbj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi9l0mov05wqmk6sucwbj.jpg" alt="image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Code on laptop with hands typing in the dark Free Photo&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;When I first started writing Go to make a back-end API, I did what most people do — threw everything into one file. The handler, the business logic, the database calls, all of it crammed together. It worked, until it didn't. The moment I tried to refactor or write tests, three things broke. Sound familiar?&lt;/p&gt;

&lt;p&gt;The fix isn't complicated, but it does require a bit of upfront thinking about how you organize your code. In this article I'll walk through a project structure that I learned recently. Companies like Uber and Netflix use similar patterns to manage large systems. It allows for scaling while remaining resilient to failures.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Bother Separating Concerns?
&lt;/h2&gt;

&lt;p&gt;Most developers have all written messy code at some point. But once things are separated, the breathing room allows for testing, changes and reuse.&lt;/p&gt;

&lt;p&gt;The idea behind separation of concerns is simple: each part of your code should have one job and one job only. When your handler is doing database queries and business logic, changes and tests can get tedious&lt;/p&gt;
&lt;h2&gt;
  
  
  The Four Layers
&lt;/h2&gt;

&lt;p&gt;For this project we use four layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; — the data structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository&lt;/strong&gt; — database access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service&lt;/strong&gt; — business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handler&lt;/strong&gt; — HTTP request handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The payoff is that the same core logic runs with different routers (standard &lt;code&gt;net/http&lt;/code&gt;, Gin, or Chi) and different databases (SQLite or MongoDB) without touching the middle layers at all.&lt;/p&gt;


&lt;h3&gt;
  
  
  1. Model
&lt;/h3&gt;

&lt;p&gt;This is just the shape of your data. No HTTP, no database — just a structure, or skeleton.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Completed&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;
    &lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything else in the app revolves around this.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Repository
&lt;/h3&gt;

&lt;p&gt;The repository is the only layer that talks to the database. Everything above it just calls repository methods.&lt;/p&gt;

&lt;p&gt;You define an interface first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TodoRepository&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;GetByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&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 implement it for each database. Want to switch from SQLite to MongoDB? Write a new implementation, swap it in — nothing else changes.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Service
&lt;/h3&gt;

&lt;p&gt;This is where your actual business logic lives. The service interact with whatever database being used, and it has nothing to do with HTTP. It just takes inputs, does something meaningful with them, and returns a result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TodoService&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Repo&lt;/span&gt; &lt;span class="n"&gt;TodoRepository&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TodoService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Todo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Completed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;CreatedAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice it only knows about the repository interface. That's the point.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Handler
&lt;/h3&gt;

&lt;p&gt;Handlers sit at the edge of the application and deal with HTTP. They decode requests, call the service, and write responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TodoHandler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"title"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;500&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="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&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;Because handlers only talk to the service (not the database), you can write different handlers for different routers — standard &lt;code&gt;net/http&lt;/code&gt;, Gin, Chi — and they all call the exact same service methods underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It All Fits Together
&lt;/h2&gt;

&lt;p&gt;Here's the flow when a request comes in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request → Handler → Service → Repository → Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database → Repository → Service → Handler → HTTP Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer only knows about the one directly below it. The handler doesn't know about the database. The service doesn't know about HTTP. The repository doesn't know about business logic. No bleed-through.&lt;/p&gt;

&lt;p&gt;In practice, wiring it all together in &lt;code&gt;main.go&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;repo&lt;/span&gt;    &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSQLiteRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTodoService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewStdHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;router&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewStdRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want MongoDB instead? Change one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMongoRepo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want Gin instead of &lt;code&gt;net/http&lt;/code&gt;? Change one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewGinHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;router&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewGinRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service layer doesn't move. The repository interface doesn't move. Only the edges change.&lt;/p&gt;

&lt;p&gt;This is the resulting file structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── cmd
│   └── main.go
├── internal
│   └── handlers
│   └── models
│   └── repository
│   └── services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;This structure might feel like extra work upfront compared to dumping everything in one file and it is. This is true only for small projects. But the moment you need to write a test, switch a database, or hand the project to someone else, you'll be glad you did it.&lt;/p&gt;

&lt;p&gt;I built the full working example of this with a &lt;a href="https://github.com/f18charles/go-todolist.git" rel="noopener noreferrer"&gt;Todo List API&lt;/a&gt; — complete with SQLite and MongoDB repositories, and handlers for &lt;code&gt;net/http&lt;/code&gt;, Gin, and Chi. Take a look if you want to see all the pieces in place.&lt;/p&gt;

&lt;p&gt;Start with this structure even on small projects. It's a habit that pays off fast.&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>backenddevelopment</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>A Compiled Review</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Tue, 17 Feb 2026 20:50:03 +0000</pubDate>
      <link>https://dev.to/fcharles/a-compiled-review-28kl</link>
      <guid>https://dev.to/fcharles/a-compiled-review-28kl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.pexels.com%2Fphotos%2F965345%2Fpexels-photo-965345.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.pexels.com%2Fphotos%2F965345%2Fpexels-photo-965345.jpeg" alt="compiled languages" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a new developer using Go, I often wondered how different other compiled languages really are. I was advised to learn Go first because of its simplicity and speed. But what about the others? What are they and what can they offer.&lt;/p&gt;

&lt;p&gt;There are many compiled languages, both popular and obscure. In this article, we focus on just four: C, C++, Rust, and Go. Let’s examine what each brings to the table.&lt;/p&gt;




&lt;h2&gt;
  
  
  Origins and Boom Years
&lt;/h2&gt;

&lt;p&gt;C appeared in 1972, created by Dennis Ritchie at Bell Labs. It was developed to overcome limitations in B and BCPL and to build the Unix operating system. C provided low level memory access while maintaining structured programming concepts, which made it ideal for operating systems and critical performance software.&lt;/p&gt;

&lt;p&gt;C++ was introduced in 1985 by Bjarne Stroustrup. It expanded C with object oriented programming features. The language gained strong popularity in the late 1990s and early 2000s during the rise of large scale software systems and game development.&lt;/p&gt;

&lt;p&gt;Go was released by Google in 2009. It was influenced by C but designed to reduce complexity. It gained traction in the mid 2010s alongside cloud computing and microservices architecture due to its fast compilation and built in concurrency support.&lt;/p&gt;

&lt;p&gt;Rust reached its stable release in 2015 from Mozilla, created by Graydon Hoare. It grew rapidly in the 2020s because of its strict memory safety model and strong performance guarantees. Many companies adopted it to reduce bugs related to memory errors.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Choose One and Leave the Other
&lt;/h2&gt;

&lt;p&gt;As software systems became more complex, languages evolved to solve new problems. C provides control and performance. C++ adds abstraction to manage larger systems. Rust enforces memory safety, and Go simplifies concurrency and improves developer productivity.&lt;/p&gt;

&lt;p&gt;Each language solves a different problem. C and C++ offer flexibility but require careful management. Rust prevents many classes of bugs at compile time. Go focuses on clarity and fast builds, making it practical for distributed systems and cloud services.&lt;/p&gt;

&lt;p&gt;There is no one language that is better. There are trade offs. The best choice depends on what you as the developer want and/or need from whatever language you choose.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concurrency Benchmark Across Languages
&lt;/h2&gt;

&lt;p&gt;This test computes the sum of squares of the first 100,000,000 numbers split across 4 threads or goroutines. Execution time is measured in milliseconds.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Sum&lt;/th&gt;
&lt;th&gt;Time (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;113.4060&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;80.5660&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;333,333,338,333,333,350,000&lt;/td&gt;
&lt;td&gt;1171.7290&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;672,921,401,752,298,880&lt;/td&gt;
&lt;td&gt;48.8229&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/f18charles/c7659fc55323cb43b153486052a01a5a" rel="noopener noreferrer"&gt;View Code&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Test Matters
&lt;/h3&gt;

&lt;p&gt;These benchmarks show more than execution speed. They reveal how each language approaches concurrency and numerical safety under the same workload.  While C, C++, and Go completed the computation without warnings. You see the computed numbers were too big for int64 so Rust refused silent overflow and required a larger integer type i.e. int128 while the other languages used the values as is.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Compiled languages are not interchangeable tools. Each reflects different priorities in software engineering. C and C++ reward experience and precision. Rust enforces correctness and offers strong safety guarantees. Go values simplicity and productivity.&lt;/p&gt;

&lt;p&gt;Understanding these differences allows developers to choose intentionally instead of following trends. The right language is not about which is fastest. It is about which aligns best with the problem you are solving.&lt;/p&gt;

</description>
      <category>go</category>
      <category>c</category>
      <category>cpp</category>
      <category>rust</category>
    </item>
    <item>
      <title>Building an AI Agent for Business Viability In a 24 Hour Hackathon</title>
      <dc:creator>Favor Charles Owuor</dc:creator>
      <pubDate>Thu, 05 Feb 2026 11:16:59 +0000</pubDate>
      <link>https://dev.to/fcharles/building-an-ai-agent-for-business-viability-in-a-24-hour-hackathon-5da0</link>
      <guid>https://dev.to/fcharles/building-an-ai-agent-for-business-viability-in-a-24-hour-hackathon-5da0</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5n18g1si3glzk2qk67g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz5n18g1si3glzk2qk67g.jpg" alt="hackathon" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recently participated in a hackathon focused on building AI agents. The main rule was clear. AI could not be the product by itself. It had to support a real system.&lt;/p&gt;

&lt;p&gt;Our team had five members. We worked for just over 24 hours. The pressure was real. So was the ambition.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We Chose
&lt;/h2&gt;

&lt;p&gt;Many people have business ideas. Very few know if those ideas make financial sense before investing money.&lt;/p&gt;

&lt;p&gt;We saw a gap. People needed a way to test ideas early, using numbers and logic, not hope and vibes.&lt;/p&gt;

&lt;p&gt;Our goal was to build a tool that helps someone answer a simple question. Is this business idea viable or not?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;We built a business viability checker called Microbiz.&lt;/p&gt;

&lt;p&gt;The user enters structured inputs. These include starting capital, pricing, expected monthly sales, operating costs, and time horizon.&lt;/p&gt;

&lt;p&gt;At the core of the system is a calculation engine. It computes revenue, total costs, profit margins, and sustainability indicators over time.&lt;/p&gt;

&lt;p&gt;This part was fully deterministic. Just math and logic to get consistent results every time.&lt;/p&gt;

&lt;p&gt;We wanted users to trust the numbers first.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Design and Team Roles
&lt;/h2&gt;

&lt;p&gt;We used Django for the back-end. I worked mainly on this part.&lt;/p&gt;

&lt;p&gt;My role involved handling inputs, validating data, running financial calculations, and structuring outputs. I also prepared the data so it could be consumed cleanly by the AI component.&lt;/p&gt;

&lt;p&gt;Two teammates worked on the front-end. Their focus was speed and clarity. They designed an interface that made complex inputs easier to manage under time pressure.&lt;/p&gt;

&lt;p&gt;Another teammate focused on prompt engineering. Their job was to control how the AI reasoned, what context it received, and how it communicated results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the AI Fit In
&lt;/h2&gt;

&lt;p&gt;We integrated Groq AI using an API key.&lt;/p&gt;

&lt;p&gt;The AI did not redo the calculations. It received the raw user inputs plus all internal computed values.&lt;/p&gt;

&lt;p&gt;From there, it performed higher level reasoning. It considered market conditions, pricing realism, demand signals, and feasibility based on what is currently visible online.&lt;/p&gt;

&lt;p&gt;The AI produced one output; it gave a recommendation on whether the business idea was likely viable or risky under the given assumptions. It stated reasons based on the input given&lt;/p&gt;

&lt;p&gt;The AI was meant to support decisions, not motivate or sell dreams.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reality Check
&lt;/h2&gt;

&lt;p&gt;We underestimated the workload.&lt;/p&gt;

&lt;p&gt;Writing formulas was not the hardest part. Defining realistic assumptions was.&lt;/p&gt;

&lt;p&gt;We had to research small business behavior, cost structures, margins, and failure points. That research slowed development since none of us have any financial or business backgrounds, but skipping it would have made the system useless.&lt;/p&gt;

&lt;p&gt;Time worked against us. Features piled up faster than we could finish them. We created and broke code again and again until we got to a middle ground that wasn't perfect but works well enough.&lt;/p&gt;

&lt;p&gt;Despite working through the night, we did not complete everything we planned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitch Day
&lt;/h2&gt;

&lt;p&gt;Before demos, all teams were called to a common area and given three minutes for an elevator pitch with slides and demos. When our turn came, we presented with nothing but words.&lt;br&gt;
It still worked in our favor since we understood the product deeply. We explained the problem clearly and answered the judges' questions without much thinking. We explained why pure AI was not enough and  how logic and AI reasoning worked together.&lt;/p&gt;

&lt;p&gt;We did not make the podium. However, the judges told us the product was useful and encouraged us to keep building it. That feedback mattered more than placement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;First, scope matters. AI agents amplify systems. They do not replace solid foundations.&lt;/p&gt;

&lt;p&gt;If your assumptions are wrong, AI makes the output confidently wrong. It's just how systems work; GIGO (Garbage In Garbage Out)&lt;/p&gt;

&lt;p&gt;Second, research is not optional. Especially when dealing with money and real people.&lt;/p&gt;

&lt;p&gt;Third, clear ownership helps under pressure. Back-end, front-end, and AI roles stayed mostly separate. That prevented chaos.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;This project is not finished and it most definitely won't be shelved.&lt;/p&gt;

&lt;p&gt;Our next step is reducing the amount of input required. The system should do more inference with less user effort so that even those who are green in business but would still like to start one can do it but with more knowledge.&lt;/p&gt;

&lt;p&gt;Long term, the goal is idea discovery. The system should recommend business ideas directly, starting with specific regions in Kenya. And as the scope expands maybe even worldwide. Maybe one day you may even interact with it.&lt;/p&gt;

&lt;p&gt;The hackathon may have ended, but the product will live on.&lt;/p&gt;

</description>
      <category>django</category>
      <category>ai</category>
      <category>agents</category>
      <category>hackathon</category>
    </item>
  </channel>
</rss>
