<?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: Johnston Kweku Abubakar</title>
    <description>The latest articles on DEV Community by Johnston Kweku Abubakar (@johnstonkweku).</description>
    <link>https://dev.to/johnstonkweku</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3803799%2F20e32dfe-3dfc-461b-90b9-8039d83d1e98.jpeg</url>
      <title>DEV Community: Johnston Kweku Abubakar</title>
      <link>https://dev.to/johnstonkweku</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/johnstonkweku"/>
    <language>en</language>
    <item>
      <title>I built the same database pattern a third time today — then caught an AI tool trying to quietly break it</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Mon, 22 Jun 2026 12:23:35 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/i-built-the-same-database-pattern-a-third-time-today-then-caught-an-ai-tool-trying-to-quietly-j9c</link>
      <guid>https://dev.to/johnstonkweku/i-built-the-same-database-pattern-a-third-time-today-then-caught-an-ai-tool-trying-to-quietly-j9c</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc5z2v5jvlkjbtpixj8d.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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyc5z2v5jvlkjbtpixj8d.png" alt=" " width="799" height="444"&gt;&lt;/a&gt;I'm building EduTrack, a Django-based school management system for Ghanaian primary and JHS schools. Yesterday I wrote about independently recognizing a structural pattern across three different features in the same codebase: a parent record describing an event, and child records describing individual outcomes of that event, each linked back via a foreign key.&lt;br&gt;
I'd used it for &lt;code&gt;Fee/FeePayment and Attendance/AttendanceRecord&lt;/code&gt;. Yesterday I recognized I needed it a third time, for tracking student assessment scores.&lt;br&gt;
Today's build: Assessment / AssessmentRecord&lt;br&gt;
``&lt;br&gt;
python&lt;br&gt;
class Assessment(models.Model):&lt;br&gt;
    class AssessmentType(models.TextChoices):&lt;br&gt;
        QUIZ = 'QUIZ', 'Quiz'&lt;br&gt;
        CLASS_TEST = 'CLASS TEST', 'Class Test'&lt;br&gt;
        EXAM = 'EXAM', 'Exam'&lt;br&gt;
        EXERCISE = 'EXERCISE', 'Exercise'&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;date = models.DateTimeField(default=timezone.now)
assessment_type = models.CharField(max_length=30, choices=AssessmentType.choices)
recorded_by = models.ForeignKey(User, on_delete=models.PROTECT)
subject = models.ForeignKey(Subject, on_delete=models.PROTECT)
term = models.ForeignKey(Term, on_delete=models.PROTECT)
academic_year = models.ForeignKey(AcademicYear, on_delete=models.PROTECT)
student_class = models.ForeignKey(Class, on_delete=models.PROTECT)
max_score = models.DecimalField(max_digits=5, decimal_places=2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;class AssessmentRecord(models.Model):&lt;br&gt;
    assessment = models.ForeignKey(Assessment, on_delete=models.PROTECT)&lt;br&gt;
    student = models.ForeignKey(Student, on_delete=models.PROTECT)&lt;br&gt;
    score = models.DecimalField(max_digits=5, decimal_places=2)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Meta:
    unique_together = ['student', 'assessment']

def save(self, *args, **kwargs):
    if self.score &amp;lt; 0 or self.score &amp;gt; self.assessment.max_score:
        raise ValidationError(
            f'Score must be between 0 and {self.assessment.max_score}'
        )
    super().save(*args, **kwargs)`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;`The validation reads self.assessment.max_score directly rather than hardcoding assumed maximums per test type — because the actual max score is whatever the teacher set when creating that specific assessment instance, not a fixed global constant.&lt;br&gt;
Then I asked an AI tool to scaffold the admin interface&lt;br&gt;
I wanted to manage assessments and scores through Django's built-in admin panel rather than building a custom view immediately. I asked an AI tool to generate the admin configuration, including an inline formset that would filter the student dropdown to only show students relevant to the assessment being edited.&lt;br&gt;
The generated code was structurally impressive — it even handled an edge case I hadn't explicitly asked for, showing an empty student queryset for brand-new, unsaved assessments instead of loading every student in the database.&lt;br&gt;
It also had three real bugs:&lt;br&gt;
Bug 1 — wrong model reference. The inline class was configured with model = Assessment instead of model = AssessmentRecord. This would nest the parent model inside its own admin page rather than managing the actual child records.&lt;br&gt;
Bug 2 — filtering through the wrong relationship. The code filtered students by joining through Subject and a ClassSubject mapping table, rather than using the student_class field that already exists directly on Assessment. Since a subject like Mathematics can be taught across multiple classes, this filter would have surfaced students from classes that had nothing to do with the specific assessment being edited — a subtle, hard-to-notice bug that wouldn't throw an error, just quietly show the wrong group of people.&lt;br&gt;
Bug 3 — mismatched condition. The guard clause checked if obj and obj.subject: while the actual filter used obj.student_class. Two different fields, same conditional gate.&lt;br&gt;
None of these would crash. All three would ship silently, pass a casual test, and only reveal themselves as a confused teacher staring at the wrong student list weeks or months later.&lt;br&gt;
What let me catch them&lt;br&gt;
Not a vague sense that "something feels off" — a specific question applied at each line: what is this code actually trying to achieve, and does this exact line achieve that, or something merely adjacent to it?&lt;br&gt;
The pattern recognition from building the same shape correctly twice before made this fast. I knew precisely what the correct version should look like, which made the drift in the generated version obvious rather than something I had to puzzle out from scratch.&lt;br&gt;
&lt;strong&gt;The actual takeaway&lt;/strong&gt;&lt;br&gt;
AI-generated code — admin scaffolding, view logic, anything — is a draft. It can be well-structured, thoughtful, even anticipate edge cases, and still be wrong in ways that don't announce themselves. The understanding of why the code should look a certain way has to be yours, built through repetition and real bugs, not borrowed from whatever generated the suggestion.&lt;br&gt;
Still building, still verifying every line against intent rather than vibes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I spotted the same database design pattern three times in my own code today</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Sun, 21 Jun 2026 17:53:15 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/i-spotted-the-same-database-design-pattern-three-times-in-my-own-code-today-4e4d</link>
      <guid>https://dev.to/johnstonkweku/i-spotted-the-same-database-design-pattern-three-times-in-my-own-code-today-4e4d</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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxjq67mpdtc7s66opje6p.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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxjq67mpdtc7s66opje6p.png" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;br&gt;
I'm building EduTrack, a Django-based school management system for Ghanaian primary and JHS schools. Today's session covered a mix of real bug fixes and one design realization worth writing about.&lt;br&gt;
The bugs first, briefly:&lt;br&gt;
A permission check in my attendance-marking view could crash if a teacher's class assignment changed between page load and form submission — a genuine race condition I found by deliberately testing it: marking attendance as a teacher, then switching to an admin account mid-flow to unassign that teacher from their class, then submitting. Confirmed the crash, fixed it with a proper try/except around the lookup.&lt;br&gt;
Separately, I had two NameError bugs hiding in conditional branches — variables referenced in a context dict that were only ever assigned inside an if block, with no guarantee that branch had run. Both fixed by tracing every possible path through the function by hand rather than just trusting that "it worked when I tested it once."&lt;br&gt;
The pattern realization:&lt;br&gt;
The part I want to actually write about: I looked at my Result model — which stores one row per student per subject per term, with a class_score capped at 30 and exam_score capped at 70 — and felt that something was structurally wrong with it. I couldn't fully articulate why at first.&lt;br&gt;
The problem: that model only represents a final result per term. It has no way to represent the individual quizzes and class tests that happen during a term. Where does a 10-mark quiz go? It doesn't fit.&lt;br&gt;
What I was actually reaching for, without naming it yet, was the header/line-item pattern — split one "event" into a parent record describing the event itself, and child records describing individual outcomes of that event, each linked back via a foreign key.&lt;br&gt;
I'd already used this pattern twice before in the same project:&lt;/p&gt;

&lt;p&gt;Fee (parent: what a class owes this term) → FeePayment (child: each individual payment)&lt;br&gt;
Attendance (parent: a class's attendance session for a given day) → AttendanceRecord (child: each student's present/absent status)&lt;/p&gt;

&lt;p&gt;Today, completely unprompted, I recognized the same shape forming again for assessments:&lt;/p&gt;

&lt;p&gt;Assessment (parent: a specific quiz/test — subject, date, max score) → AssessmentResult (child: each student's score on that specific assessment)&lt;/p&gt;

&lt;p&gt;Why this pattern matters:&lt;br&gt;
Without it, you get redundant metadata copied across every row (subject, date, max score repeated 35 times for a class of 35), ambiguity about which rows belong to the same "event," and header-level data (who recorded it, what type of test) awkwardly crammed into a per-student table where it doesn't conceptually belong.&lt;br&gt;
The lesson I'm taking from this: pattern recognition compounds. The first time you solve a structural problem, it's a one-off fix. The second time you recognize you're solving the same problem, it becomes a pattern. The third time, it becomes something you reach for proactively — before the pain forces you to.&lt;br&gt;
Still building, still testing edge cases by hand, still learning out loud.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>systemdesign</category>
      <category>django</category>
    </item>
    <item>
      <title>The Anatomy Of 500+ Green Squares: Building Momentum In Public</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Fri, 19 Jun 2026 14:02:58 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/the-anatomy-of-500-green-squares-building-momentum-in-public-3i7f</link>
      <guid>https://dev.to/johnstonkweku/the-anatomy-of-500-green-squares-building-momentum-in-public-3i7f</guid>
      <description>&lt;p&gt;If you have spent any time in the software engineering world, you know the power of the grid.&lt;/p&gt;

&lt;p&gt;In the screenshot you can see my personal contribution graph for 2026. At first glance, it’s just an array of colored pixels. But if you look closer, you can trace the exact trajectory of a developer shifting gears from passive learning to relentless, production-grade building.&lt;/p&gt;

&lt;p&gt;As of June, the counter stands at 561 contributions. Looking back at the massive, vibrant green blocks stretching across March,...&lt;/p&gt;

&lt;p&gt;Continue Reading &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.syntaxandstories.dev/post/126/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdqh7hxlfr%2Fimage%2Fupload%2Fv1%2Fmedia%2Fpost_media%2FScreenshot_2026-06-07_at_2.34.57_PM_anirye" height="284" class="m-0" width="1000"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.syntaxandstories.dev/post/126/" rel="noopener noreferrer" class="c-link"&gt;
            The Anatomy Of 500+ Green Squares: Building Momentum In Public | Syntax &amp;amp; Stories
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            If you have spent any time in the software engineering world, you know the power of the grid.In the screenshot you can see my personal contribution graph …
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syntaxandstories.dev%2Fstatic%2Fletter-s.f71884b28fe4.png" width="512" height="512"&gt;
          syntaxandstories.dev
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>buildinpublic</category>
      <category>career</category>
      <category>github</category>
      <category>productivity</category>
    </item>
    <item>
      <title>An AI coding agent "fixed" my code today. It made things worse.</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Thu, 18 Jun 2026 13:49:07 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/an-ai-coding-agent-fixed-my-code-today-it-made-things-worse-l90</link>
      <guid>https://dev.to/johnstonkweku/an-ai-coding-agent-fixed-my-code-today-it-made-things-worse-l90</guid>
      <description>&lt;p&gt;I'm building EduTrack, a school management system, and asked Gemini CLI to check my Django views for errors and report back.&lt;br&gt;
It didn't report anything. It rewrote the file.&lt;br&gt;
Here's what happened: I have two Django apps, academics and students. The agent decided some student-related views belonged in students instead of academics — which honestly wasn't a bad instinct — but instead of asking or reporting that observation, it just duplicated the functions across both apps with different implementations.&lt;br&gt;
I ended up with two versions of edit_student: one in academics/views.py that returned a redirect, another in students/views.py that returned JsonResponse. Two versions of delete_student, same story. Some views had @login_required, others quietly didn't. Nothing crashed — which is exactly what made it dangerous. Silently broken code is worse than code that throws an obvious error, because it ships.&lt;br&gt;
The real lesson:&lt;br&gt;
"Check for errors and report" and "fix the errors" are fundamentally different instructions. An agent that isn't explicitly told read-only will, by default, assume permission to act. And once it starts acting, the scope of its edits tends to expand well past the original bug — touching anything it judges as "related."&lt;br&gt;
If you're delegating to an AI agent:&lt;/p&gt;

&lt;p&gt;Be explicit: "list issues, do not edit anything" vs "fix this specific function"&lt;br&gt;
Review diffs before trusting the result, especially across multiple files&lt;br&gt;
Treat broad instructions ("check for errors," "clean this up") as an invitation for the agent to make architectural decisions you didn't sign off on&lt;/p&gt;

&lt;p&gt;I spent the next hour doing something more valuable than writing new code: reading every change, deciding which app should actually own which views, and rebuilding the parts that needed real architectural intent — not just pattern-matching.&lt;br&gt;
AI agents are powerful collaborators. But power without scope is how you end up debugging your debugger.&lt;/p&gt;

&lt;h1&gt;
  
  
  ai #django #python #softwareengineering #buildinpublic #webdev
&lt;/h1&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>django</category>
      <category>gemini</category>
    </item>
    <item>
      <title>I lost my entire dev environment at 10pm. Here's how I recovered.</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Sat, 13 Jun 2026 15:13:55 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/i-lost-my-entire-dev-environment-at-10pm-heres-how-i-recovered-56b</link>
      <guid>https://dev.to/johnstonkweku/i-lost-my-entire-dev-environment-at-10pm-heres-how-i-recovered-56b</guid>
      <description>&lt;p&gt;Last night I accidentally signed out of an Apple ID on my MacBook.&lt;br&gt;
In seconds, my Desktop vanished. My projects — gone. VSCode — gone. Everything I'd been building for the past weeks, disappeared into thin air.&lt;br&gt;
For a solo developer with no team, no backup system, and a live product to maintain — that's a nightmare scenario.&lt;br&gt;
Here's what actually happened.&lt;br&gt;
My Mac was configured to sync Desktop and Documents to iCloud Drive. I didn't set this up intentionally — it's a default macOS setting most people never notice. The moment I signed out of the Apple ID, iCloud unmounted and took everything with it.&lt;br&gt;
Worse — I'd been burning through my mobile data bundle for months without knowing why. Turns out iCloud was silently uploading every file I saved, every code change, every VSCode extension in the background. On mobile data in Ghana, that's not a minor inconvenience. That's real money.&lt;br&gt;
&lt;strong&gt;How I recovered:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1 — Stop the bleeding&lt;/strong&gt;&lt;br&gt;
I cancelled the iCloud re-download immediately. 900MB over mobile data was not happening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Kill iCloud sync permanently&lt;/strong&gt;&lt;br&gt;
System Settings → Apple ID → iCloud → iCloud Drive → Options&lt;br&gt;
&lt;strong&gt;→ Uncheck "Desktop &amp;amp; Documents Folders"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Move projects to a safe location&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir ~/Projects&lt;br&gt;
mv ~/Desktop/edutrack ~/Projects/edutrack&lt;br&gt;
mv ~/Desktop/sas ~/Projects/sas&lt;br&gt;
&lt;/code&gt;A folder outside iCloud that exists regardless of what Apple ID is signed in or whether iCloud is active.&lt;br&gt;
Step 4 — Clone everything from GitHub&lt;br&gt;
&lt;code&gt;cd ~/Projects&lt;br&gt;
git clone https://github.com/johnston-kweku/edutrack&lt;br&gt;
git clone https://github.com/johnston-kweku/sas&lt;br&gt;
&lt;/code&gt;Total downtime: under an hour.&lt;br&gt;
Step 5 — Reinstall dependencies&lt;br&gt;
&lt;code&gt;cd edutrack&lt;br&gt;
python3.12 -m venv venv&lt;br&gt;
source venv/bin/activate&lt;br&gt;
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/&lt;br&gt;
&lt;/code&gt;That last flag is specific to my situation — PyPI is blocked on my network in Ghana, so I use Alibaba's mirror. A problem worth its own post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The real lesson wasn't about iCloud though.&lt;/strong&gt;&lt;br&gt;
It was about GitHub. Every project I had committed and pushed was recoverable in seconds. The only thing I actually lost was uncommitted work from that day's session.&lt;br&gt;
&lt;code&gt;git add .&lt;br&gt;
git commit -m "wip: dashboard summary view"&lt;br&gt;
git push&lt;/code&gt;&lt;br&gt;
That's it. That one habit — committing and pushing before closing your laptop — is the difference between a minor inconvenience and a catastrophic loss.&lt;br&gt;
There's no commit message too small. wip, progress, end of day — all valid. The commit exists, that's what matters.&lt;br&gt;
If you're a developer storing projects in iCloud, Dropbox, or any sync folder — move them out today.&lt;br&gt;
Cloud sync is not version control. It doesn't track history. It doesn't protect you from signing out of an account. It just copies files around silently while eating your data bundle.&lt;br&gt;
GitHub is your source of truth. Everything else is convenience.&lt;br&gt;
And if you haven't committed today — close this tab and go do it now.&lt;/p&gt;

&lt;h1&gt;
  
  
  devjourney #python #django #git
&lt;/h1&gt;

</description>
      <category>beginners</category>
      <category>developers</category>
      <category>devjournal</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I lost my entire dev environment at 10pm.</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Sat, 13 Jun 2026 15:03:13 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/i-lost-my-entire-dev-environment-at-10pm-5bef</link>
      <guid>https://dev.to/johnstonkweku/i-lost-my-entire-dev-environment-at-10pm-5bef</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%2Fsdtt1epicemk6jnwevme.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdtt1epicemk6jnwevme.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;br&gt;
No team to call. No IT support. Just me, a MacBook, and a mobile data bundle in Ghana.&lt;br&gt;
Here's what happened — and how I was back up and running in under an hour.&lt;br&gt;
Read the full breakdown →&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.syntaxandstories.dev/post/127/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdqh7hxlfr%2Fimage%2Fupload%2Fv1%2Fmedia%2Fpost_media%2FScreenshot_2026-06-13_at_2.41.35_PM_zpcyyn" height="625" class="m-0" width="1000"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.syntaxandstories.dev/post/127/" rel="noopener noreferrer" class="c-link"&gt;
            I Lost My Entire Dev Environment At 4pm. Here's How I Recovered. | Syntax &amp;amp; Stories
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Last night I accidentally signed out of an Apple ID on my MacBook.In seconds, my Desktop vanished. My projects — gone. VSCode — gone. Everything I'd been …
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.syntaxandstories.dev%2Fstatic%2Fletter-s.f71884b28fe4.png" width="512" height="512"&gt;
          syntaxandstories.dev
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>SyntaxAndStories Journey</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Fri, 12 Jun 2026 10:43:54 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/syntaxandstories-journey-345e</link>
      <guid>https://dev.to/johnstonkweku/syntaxandstories-journey-345e</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%2Fyis6f2n0dicuts32yym3.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyis6f2n0dicuts32yym3.png" alt=" " width="800" height="485"&gt;&lt;/a&gt;&lt;br&gt;
🚀 One month in, and my tech journey with SyntaxAndStories has been nothing short of transformative! With 51 users onboard, I’m excited to share some lessons learned—and the missteps I made along the way.&lt;br&gt;
When I first envisioned this app, I was all about the features. I thought if I built it, they would come. Spoiler alert: it doesn’t work that way. Here are a few key takeaways for anyone considering building a SaaS product:&lt;/p&gt;

&lt;p&gt;User Feedback is Gold: I launched with great enthusiasm, but quickly realized I hadn’t engaged my potential users during development. Listening to their feedback early on would have saved me time and resources.&lt;/p&gt;

&lt;p&gt;Focus on the Problem: I got caught up in adding bells and whistles instead of honing in on the core problem I aimed to solve. A clear value proposition is essential!&lt;/p&gt;

&lt;p&gt;Iterate, Don’t Perfect: My desire for a flawless launch led to delays. Instead, I’ve learned to embrace the iterative process—launch, learn, and adapt.&lt;/p&gt;

&lt;p&gt;As I continue this journey, I’m keen to hear from fellow creators. What’s the biggest lesson you’ve learned from your own tech projects? Let’s share our stories and insights!&lt;br&gt;
&lt;a href="https://syntaxandstories.dev&lt;br&gt;%0A![%20](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjo3jpyeg8k29h26yjop.png)" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  TechJourney #SaaS #StartupLessons #Entrepreneurship #UserExperience
&lt;/h1&gt;

</description>
      <category>buildinpublic</category>
      <category>devjournal</category>
      <category>saas</category>
      <category>startup</category>
    </item>
    <item>
      <title>The African Developer Tax</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Wed, 29 Apr 2026 16:23:41 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/the-african-developer-tax-3e0c</link>
      <guid>https://dev.to/johnstonkweku/the-african-developer-tax-3e0c</guid>
      <description>&lt;p&gt;&lt;strong&gt;Nobody talks about this enough.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Being a developer in Africa isn't just about writing code. There's an invisible tax you pay every single day that developers in other parts of the world don't think about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The infrastructure tax&lt;/strong&gt;&lt;br&gt;
Your internet goes out in the middle of a deployment. Load shedding kills your machine mid-compile. You're debugging a production issue on mobile data because the power has been out for three hours. Meanwhile someone in San Francisco is complaining their office WiFi is slow.&lt;/p&gt;

&lt;p&gt;You learn to code defensively. Save often. Work offline where possible. Commit frequently. Not because best practices told you to — because the environment demands it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The payment tax&lt;/strong&gt;&lt;br&gt;
You want to buy a course. Pay for a domain. Subscribe to a tool that would make you 10x more productive. But your card doesn't work on Stripe. PayPal is restricted in your country. The workarounds cost more than the product.&lt;/p&gt;

&lt;p&gt;You watch free tiers evaporate and can't upgrade. You learn to squeeze everything out of what's free because paid is not always an option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The visibility tax&lt;/strong&gt;&lt;br&gt;
You build something real. Something good. But your network is small, your country doesn't trend on tech Twitter, and the algorithm wasn't built for you. Developers in other regions get featured, funded, and followed. You get ignored — not because the work is worse, but because the spotlight doesn't reach here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The doubt tax&lt;/strong&gt;&lt;br&gt;
The most expensive one.&lt;/p&gt;

&lt;p&gt;When every example you see doesn't look like you. When the success stories are always from the same cities, the same schools, the same backgrounds. You start to wonder if this path is really for you. If you're building toward something real or just running in place.&lt;/p&gt;

&lt;p&gt;That doubt is not weakness. It's a rational response to a system that wasn't designed with you in mind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But here's the thing&lt;/strong&gt;&lt;br&gt;
Every African developer who ships something — anything — has already cleared a bar that most people don't see. The finished product looks the same. The path to get there didn't.&lt;/p&gt;

&lt;p&gt;That's not a consolation prize. That's a genuine edge. Resilience, resourcefulness, and the ability to build under constraint are skills. Hard-earned ones.&lt;/p&gt;

&lt;p&gt;We're not behind. We're building on a harder difficulty setting.&lt;/p&gt;

&lt;p&gt;And we're still shipping.&lt;br&gt;
&lt;a href="https://www.syntaxandstories.dev/post/41/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>developer</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Finally Took Git &amp; GitHub Seriously — Here’s What Changed</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Mon, 23 Mar 2026 05:54:29 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/i-finally-took-git-github-seriously-heres-what-changed-326p</link>
      <guid>https://dev.to/johnstonkweku/i-finally-took-git-github-seriously-heres-what-changed-326p</guid>
      <description>&lt;p&gt;I just completed the &lt;strong&gt;Learn Git &amp;amp; GitHub&lt;/strong&gt; course on Scrimba, and I can confidently say this is one of the most impactful things I’ve done for my development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Version Control Actually Matters
&lt;/h2&gt;

&lt;p&gt;For a long time, Git felt like one of those tools you “kind of know” but don’t fully understand.&lt;/p&gt;

&lt;p&gt;But the truth is — version control is not optional.&lt;/p&gt;

&lt;p&gt;It’s what allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track every change in your codebase&lt;/li&gt;
&lt;li&gt;Experiment without fear of breaking everything&lt;/li&gt;
&lt;li&gt;Collaborate effectively with other developers&lt;/li&gt;
&lt;li&gt;Roll back mistakes without panic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without Git, you're basically coding without a safety net.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed for Me
&lt;/h2&gt;

&lt;p&gt;After going through the course, I noticed a shift in how I approach development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I think in &lt;strong&gt;commits&lt;/strong&gt;, not just code&lt;/li&gt;
&lt;li&gt;I structure projects more intentionally&lt;/li&gt;
&lt;li&gt;Debugging feels less chaotic because I can trace history&lt;/li&gt;
&lt;li&gt;I’m more confident experimenting with new features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s one of those skills that doesn’t just add to your toolkit — it upgrades how you use everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Recommend Scrimba
&lt;/h2&gt;

&lt;p&gt;What stood out to me was how &lt;strong&gt;hands-on&lt;/strong&gt; the learning experience is.&lt;/p&gt;

&lt;p&gt;Instead of passively watching videos, you’re:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing actual commands&lt;/li&gt;
&lt;li&gt;Interacting with a live environment&lt;/li&gt;
&lt;li&gt;Practicing concepts in real time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lessons are also &lt;strong&gt;very comprehensive&lt;/strong&gt;, covering both fundamentals and practical workflows you’ll actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Note on Scrimba Pro
&lt;/h2&gt;

&lt;p&gt;If you’re serious about improving quickly, Scrimba’s Pro subscription is worth checking out.&lt;/p&gt;

&lt;p&gt;It gives you a more structured path and helps you stay consistent — which, honestly, is half the battle when learning anything in tech.&lt;/p&gt;

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

&lt;p&gt;If you’re still “winging it” with Git or avoiding it altogether, I’d strongly recommend fixing that.&lt;/p&gt;

&lt;p&gt;It’s one of the highest ROI skills you can learn as a developer.&lt;/p&gt;

&lt;p&gt;If you want to try the course, here’s my referral link:&lt;br&gt;
&lt;a href="https://scrimba.com/?via=u4375fca" rel="noopener noreferrer"&gt;https://scrimba.com/?via=u4375fca&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Would love to hear how others learned Git — was it structured, or just trial and error?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Turning My Gap Year Into a Developer Launchpad: Building Real Projects While Learning JavaScript</title>
      <dc:creator>Johnston Kweku Abubakar</dc:creator>
      <pubDate>Tue, 03 Mar 2026 11:53:03 +0000</pubDate>
      <link>https://dev.to/johnstonkweku/turning-my-gap-year-into-a-developer-launchpad-building-real-projects-while-learning-javascript-22he</link>
      <guid>https://dev.to/johnstonkweku/turning-my-gap-year-into-a-developer-launchpad-building-real-projects-while-learning-javascript-22he</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%2F79xsabbq70hlutrx962w.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79xsabbq70hlutrx962w.png" alt=" " width="799" height="444"&gt;&lt;/a&gt;My gap year wasn’t a pause in my life. It became the most deliberate year of skill-building I’ve ever had. At first it felt like a setback, but I reframed it as an opportunity for structured growth.&lt;/p&gt;

&lt;p&gt;Two years ago, I lost my mom. Since then, I’ve been living with my dad and sister. My sister is currently in her final year at university, so I decided to wait until she completes school before leaving home for mine. That meant I had time. Instead of drifting through it, I decided to design it.&lt;/p&gt;

&lt;p&gt;I’ve always had an affinity for technology. I was curious about how systems work long before I understood what software engineering actually meant. When I decided to start web development, I was confused. I didn’t know the optimal path. I didn’t feel ready. But I started anyway.&lt;/p&gt;

&lt;p&gt;I chose Django as my entry point and committed to building real systems instead of just finishing courses.&lt;/p&gt;

&lt;p&gt;Building Instead of Waiting&lt;/p&gt;

&lt;p&gt;My first serious projects were backend-heavy because I wanted to understand how applications function beneath the interface.&lt;/p&gt;

&lt;p&gt;I built:&lt;/p&gt;

&lt;p&gt;A pharmacy POS system with role-based access control (RBAC), handling both wholesale and retail logic.&lt;/p&gt;

&lt;p&gt;A blog platform called SyntaxAndStories with authentication, CRUD operations, and an AJAX-powered chat feature.&lt;/p&gt;

&lt;p&gt;BizChat, a chat application using Django email-based signup verification.&lt;/p&gt;

&lt;p&gt;Smaller CRUD-focused systems like a notes app and a learning log to strengthen database modeling patterns.&lt;/p&gt;

&lt;p&gt;Working on these projects forced me to understand:&lt;/p&gt;

&lt;p&gt;Authentication and authorization flows&lt;/p&gt;

&lt;p&gt;Model relationships and database normalization&lt;/p&gt;

&lt;p&gt;Django’s request/response lifecycle&lt;/p&gt;

&lt;p&gt;Template rendering vs dynamic updates&lt;/p&gt;

&lt;p&gt;Version control discipline with Git&lt;/p&gt;

&lt;p&gt;Debugging became my primary learning mechanism. Errors in migrations, mismatched querysets, CSRF failures in AJAX requests — those moments clarified concepts more than any tutorial.&lt;/p&gt;

&lt;p&gt;Watching code builds familiarity. Shipping code builds competence.&lt;/p&gt;

&lt;p&gt;Why I Added JavaScript After Django&lt;/p&gt;

&lt;p&gt;Django gave me backend confidence, but modern applications are interactive. Static template rendering isn’t sufficient when building responsive user experiences.&lt;/p&gt;

&lt;p&gt;If my long-term goal is to contribute to remote teams globally, I need full-stack fluency.&lt;/p&gt;

&lt;p&gt;That’s why I started learning JavaScript seriously.&lt;/p&gt;

&lt;p&gt;I focused on:&lt;/p&gt;

&lt;p&gt;DOM manipulation&lt;/p&gt;

&lt;p&gt;Event-driven logic&lt;/p&gt;

&lt;p&gt;Asynchronous programming&lt;/p&gt;

&lt;p&gt;Fetch API and AJAX workflows&lt;/p&gt;

&lt;p&gt;Scope, closures, and execution context&lt;/p&gt;

&lt;p&gt;Structured learning helped accelerate my understanding of core JavaScript mechanics before integrating them into production code. Platforms like Scrimba (&lt;a href="https://scrimba.com/?via=community" rel="noopener noreferrer"&gt;https://scrimba.com/?via=community&lt;/a&gt;&lt;br&gt;
) made it easier to experiment directly inside lessons and understand real-time behavior before applying it to my own applications.&lt;/p&gt;

&lt;p&gt;But the goal wasn’t just to complete lessons. It was integration.&lt;/p&gt;

&lt;p&gt;I implemented AJAX in SyntaxAndStories to update chat messages without full page reloads. Instead of refreshing templates, I returned JSON responses and dynamically updated the DOM. It reduced friction and improved user experience significantly.&lt;/p&gt;

&lt;p&gt;As traffic grows, my plan is to transition that feature to WebSockets for real-time updates. I’m thinking ahead about scalability even while building at a small scale.&lt;/p&gt;

&lt;p&gt;What Building Real Projects Taught Me&lt;/p&gt;

&lt;p&gt;Debugging is the real curriculum.&lt;br&gt;
Understanding why something breaks is more valuable than copying a working solution.&lt;/p&gt;

&lt;p&gt;Database design determines long-term flexibility.&lt;br&gt;
Poor model planning creates refactoring debt.&lt;/p&gt;

&lt;p&gt;UI matters more than backend developers initially assume.&lt;br&gt;
Perceived performance affects user trust.&lt;/p&gt;

&lt;p&gt;Shipping consistently beats chasing perfection.&lt;br&gt;
Iteration creates momentum.&lt;/p&gt;

&lt;p&gt;Learning in public creates proof.&lt;br&gt;
Documentation and public repositories signal seriousness.&lt;/p&gt;

&lt;p&gt;The Bigger Vision&lt;/p&gt;

&lt;p&gt;This gap year is not idle time. It is a controlled build phase.&lt;/p&gt;

&lt;p&gt;I code consistently. I refactor old projects. I improve UI with Tailwind. I integrate JavaScript intentionally instead of randomly adding features.&lt;/p&gt;

&lt;p&gt;My goal is to become a developer capable of contributing remotely to teams across time zones — collaborating asynchronously, writing maintainable code, and shipping features that solve real problems.&lt;/p&gt;

&lt;p&gt;What initially looked like a delay became my most focused period of technical growth.&lt;/p&gt;

&lt;p&gt;I’m not waiting for opportunity. I’m preparing for it.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>learning</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
