<?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: OLALEKAN OGUNDIMU</title>
    <description>The latest articles on DEV Community by OLALEKAN OGUNDIMU (@olalekan_ogundimu).</description>
    <link>https://dev.to/olalekan_ogundimu</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%2F3253566%2F619cd088-312c-495a-be58-ce289fd3d82a.png</url>
      <title>DEV Community: OLALEKAN OGUNDIMU</title>
      <link>https://dev.to/olalekan_ogundimu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/olalekan_ogundimu"/>
    <language>en</language>
    <item>
      <title>The Last Computation: A Game About Alan Turing's Final June</title>
      <dc:creator>OLALEKAN OGUNDIMU</dc:creator>
      <pubDate>Tue, 09 Jun 2026 22:36:49 +0000</pubDate>
      <link>https://dev.to/olalekan_ogundimu/the-last-computation-a-game-about-alan-turings-final-june-510o</link>
      <guid>https://dev.to/olalekan_ogundimu/the-last-computation-a-game-about-alan-turings-final-june-510o</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Before we talk about the game, let me take you somewhere.&lt;/p&gt;

&lt;p&gt;It is June 8, 1954. A housekeeper walks into a house in Wilmslow, Cheshire, England. She finds Alan Turing — mathematician, codebreaker, the man who helped end World War II — dead. He is 41 years old. A half-eaten apple sits beside him.&lt;/p&gt;

&lt;p&gt;This is the same man who, a decade earlier, sat in a freezing hut at Bletchley Park and broke the Nazi Enigma cipher when the Allied forces had nearly run out of time. His machine — the Bombe — cracked codes that no human could crack fast enough. It is estimated that his work shortened the war by two to four years. Historians believe it saved over fourteen million lives.&lt;/p&gt;

&lt;p&gt;And then, less than ten years after the war ended, the British government chemically castrated him as punishment for being gay. He died alone. The apple — possibly laced with cyanide — was never tested.&lt;/p&gt;

&lt;p&gt;June is the month Alan Turing was born. It is the month he died. It is Pride Month. And this year, it is the month of this game jam.&lt;/p&gt;

&lt;p&gt;This game is for him.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;THE LAST COMPUTATION&lt;/strong&gt; is a browser-based mystery game set in June 1954, the weeks before Turing's death. You play as his successor — an operative who has just recovered three encrypted transmissions from Turing's study, transmissions no one was supposed to find.&lt;/p&gt;

&lt;p&gt;The game has four chapters:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapters 1–3: The Codebreaking&lt;/strong&gt;&lt;br&gt;
Each chapter presents an intercepted document, styled as a wartime classified file — paper texture, red TOP SECRET stamp, typewriter ink, all of it. The document contains a ciphertext that you must decode using the same methods Turing and his team used at Bletchley: Caesar shifts and ROT13.&lt;/p&gt;

&lt;p&gt;These are real ciphers. The game doesn't hold your hand. You work it out, or you ask for a hint. The decoded messages are fragments of Turing's final thoughts — haunting, brilliant, and deeply human.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapter 4: The Imitation Game — Inverted&lt;/strong&gt;&lt;br&gt;
This is where the game turns.&lt;/p&gt;

&lt;p&gt;In 1950, Alan Turing published a paper asking: &lt;em&gt;"Can machines think?"&lt;/em&gt; He proposed a test — now called the Turing Test — where a machine tries to convince a human that it is human. The machine that passes becomes, in some sense, intelligent.&lt;/p&gt;

&lt;p&gt;In Chapter 4, a machine intelligence derived from Turing's own notes has been watching you work. Now it speaks. And it wants to ask &lt;em&gt;you&lt;/em&gt; the questions.&lt;/p&gt;

&lt;p&gt;Not whether you are smart. Whether you are &lt;em&gt;human&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You have five turns. It asks you about grief, about love, about the fear of endings. It is cold, precise, and deeply curious. Every answer you give is scored — not by word count, but by the texture of your humanity: your hesitations, your emotion, your beautiful imperfection.&lt;/p&gt;

&lt;p&gt;At the end, it delivers a verdict.&lt;/p&gt;

&lt;p&gt;The solstice framing is deliberate: June is the turning point of the year. Chapter 4 is the turning point of the game. And June 1954 was the turning point — the darkest one — of one extraordinary human life.&lt;/p&gt;


&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/W3P_QIHa4iM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://turing-game-three.vercel.app/" rel="noopener noreferrer"&gt;Play Game&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The entire game runs in a single HTML file — no frameworks, no build tools, no dependencies beyond a Google Fonts import. Open it in a browser and play.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Core architecture overview --&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!--
  STRUCTURE:
  - screen-title   : Opening title + atmospheric intro
  - screen-terminal: Main game (cipher puzzles + Turing Test chat)
  - screen-end     : Final verdict screen

  CIPHER ENGINE:
  - Caesar shift decoding (shifts 3, 7, 13 / ROT13)
  - Flexible answer matching: exact OR keyword-present
  - Hints available on request

  AI LAYER (Chapter 4):
  - Anthropic Claude API (claude-sonnet-4-20250514)
  - System prompt constructs the "machine" persona from Turing's 1950 paper
  - Humanity scoring: emotional language, hesitation, personal pronouns, word count
  - Fallback responses if API is unavailable (game works offline)

  AESTHETIC:
  - CRT phosphor terminal (green on black)
  - Scan lines + screen flicker via CSS animation
  - Wartime document styling: paper texture, red stamp, Courier typeface
  - Share Tech Mono + Special Elite + Courier Prime (Google Fonts)
--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/sam-the-champ/turing-game" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Design Philosophy
&lt;/h3&gt;

&lt;p&gt;The hardest decision was: what should a Turing game actually &lt;em&gt;feel&lt;/em&gt; like?&lt;/p&gt;

&lt;p&gt;I didn't want a quiz about his biography. I didn't want a platformer where you jump over Enigma machines. I wanted the player to &lt;em&gt;inhabit&lt;/em&gt; the experience — to actually do the things Turing did, and then face the question that consumed the final years of his life.&lt;/p&gt;

&lt;p&gt;The result: real ciphers, real history, real AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cipher Puzzles
&lt;/h3&gt;

&lt;p&gt;Each puzzle uses a cipher Turing's team would have recognised. The three shifts — 3, 7, and 13 — increase in difficulty, and ROT13 (shift 13) is the one that requires you to understand the mirror symmetry of the alphabet. The decoded messages are original text written in Turing's voice, drawing from his published papers and documented thoughts.&lt;/p&gt;

&lt;p&gt;The wartime document aesthetic was built entirely in CSS. The paper texture is a CSS &lt;code&gt;repeating-linear-gradient&lt;/code&gt; simulating ruled lines. The red stamp is rotated with &lt;code&gt;transform: rotate(12deg)&lt;/code&gt;. The CRT effect uses layered scan lines, a moving glow, and a subtle screen flicker animation on the &lt;code&gt;body&lt;/code&gt; itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Inverted Turing Test
&lt;/h3&gt;

&lt;p&gt;This was the heart of the game and the hardest part to get right.&lt;/p&gt;

&lt;p&gt;The standard Turing Test asks: can a machine fool a human into thinking it's human? I wanted to flip it. The machine knows it is a machine. It is not pretending. It is genuinely, analytically curious about what humanity feels like — because its creator, Turing, was fascinated by exactly that question and was persecuted for exhibiting what his society considered the wrong kind of humanity.&lt;/p&gt;

&lt;p&gt;The AI persona is built through a carefully constructed system prompt that grounds the machine in June 1954, in Bletchley Park, in Turing's own 1950 paper &lt;em&gt;Computing Machinery and Intelligence&lt;/em&gt;. It asks questions that no cipher can answer: &lt;em&gt;What does grief feel like in the body? Why do humans choose poorly when they know the optimal path?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The humanity scoring system is a heuristic that rewards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Emotional vocabulary (love, fear, grief, joy, loss, hope)&lt;/li&gt;
&lt;li&gt;Linguistic imperfection (hesitation words, ellipses, "I'm not sure")&lt;/li&gt;
&lt;li&gt;Personal language (I, me, my, we)&lt;/li&gt;
&lt;li&gt;Longer, considered answers over short, efficient ones&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not trying to catch you out. It is trying to understand you. That distinction matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Technical Stack
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Single HTML file
├── CSS: CRT aesthetics, document styling, animations
├── JavaScript: Game state, cipher engine, humanity scoring
├── Google Fonts: Share Tech Mono, Special Elite, Courier Prime
└── Anthropic Claude API: The machine intelligence in Chapter 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No npm. No build step. No backend. Deploy it anywhere.&lt;/p&gt;




&lt;h3&gt;
  
  
  Best Ode to Alan Turing
&lt;/h3&gt;

&lt;p&gt;This entire game is an ode to Alan Turing, and it tries to honour him in the only way that felt adequate: by making the player &lt;em&gt;do&lt;/em&gt; what he did, and then face the question that haunted him.&lt;/p&gt;

&lt;p&gt;The ciphers are his methods. The machine is his creation — the AI in Chapter 4 is a direct descendant of the theoretical computer he described in 1936. The inverted Turing Test is his most famous thought experiment, turned inside out.&lt;/p&gt;

&lt;p&gt;But beyond the mechanics, the game is an act of historical witness. It is set in June 1954 because that is when his story ended — and when Pride Month begins. That is not coincidence. It is the same fight, across seventy years.&lt;/p&gt;

&lt;p&gt;Turing was told that his mind — the most extraordinary analytical mind of the twentieth century — was less important than his sexuality. The British government broke him. The game ends with a machine asking whether you, the player, are human.&lt;/p&gt;

&lt;p&gt;The answer the game is really asking: &lt;em&gt;Was he?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;He was. Completely, beautifully, irreducibly human. The machine knows it. Now you do too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Google AI Usage — &lt;em&gt;A note on the AI layer&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;The machine interrogator in Chapter 4 is powered by the &lt;strong&gt;Anthropic Claude API&lt;/strong&gt; (claude-sonnet-4-20250514). The system prompt instructs Claude to embody a machine intelligence derived from Turing's 1950 paper — cold, precise, analytically curious, speaking in short declarative sentences, asking the kinds of questions a mathematician would ask if trying to locate the human soul through logic.&lt;/p&gt;

&lt;p&gt;Each response is generated fresh based on your answer, meaning no two playthroughs of Chapter 4 are identical. The machine adapts. It remembers what you said. It builds on it.&lt;/p&gt;

&lt;p&gt;This is, in a strange and fitting way, the Turing Test happening in real time — an AI system, trained on human knowledge, asking a human to prove their humanity. Turing imagined this exact scenario in 1950. It is now simply called Tuesday.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Final Note
&lt;/h2&gt;

&lt;p&gt;Alan Turing received a royal pardon from the British government in 2013 — 59 years after his death. In 2021, his face appeared on the British £50 note.&lt;/p&gt;

&lt;p&gt;Too late. Not enough.&lt;/p&gt;

&lt;p&gt;But every June, Pride Month asks us to remember that the fight for the right to be fully, freely human is not abstract. It has names. It has faces. It has a man in Wilmslow with a half-eaten apple and three encrypted messages he never expected anyone to find.&lt;/p&gt;

&lt;p&gt;This game found them.&lt;/p&gt;

&lt;p&gt;Play it. Decode them. Prove you're human.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://turing-game-three.vercel.app/" rel="noopener noreferrer"&gt;Play Game&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the DEV Community June Solstice Game Jam 2026.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;In memory of Alan Mathison Turing, 23 June 1912 – 7 June 1954.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>OLALEKAN OGUNDIMU</dc:creator>
      <pubDate>Fri, 29 May 2026 23:32:22 +0000</pubDate>
      <link>https://dev.to/olalekan_ogundimu/-54i9</link>
      <guid>https://dev.to/olalekan_ogundimu/-54i9</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc" class="crayons-story__hidden-navigation-link"&gt;From a 3-Day Deadline Disaster to a Real Product: Reviving My First Full-Stack Project&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;GitHub “Finish-Up-A-Thon” Challenge Submission&lt;/p&gt;

&lt;/a&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/olalekan_ogundimu" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3253566%2F619cd088-312c-495a-be58-ce289fd3d82a.png" alt="olalekan_ogundimu profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/olalekan_ogundimu" class="crayons-story__secondary fw-medium m:hidden"&gt;
              OLALEKAN OGUNDIMU
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                OLALEKAN OGUNDIMU
                
              
              &lt;div id="story-author-preview-content-3778163" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/olalekan_ogundimu" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3253566%2F619cd088-312c-495a-be58-ce289fd3d82a.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;OLALEKAN OGUNDIMU&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 29&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc" id="article-link-3778163"&gt;
          From a 3-Day Deadline Disaster to a Real Product: Reviving My First Full-Stack Project
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devchallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/githubchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;githubchallenge&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;13&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              3&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>From a 3-Day Deadline Disaster to a Real Product: Reviving My First Full-Stack Project</title>
      <dc:creator>OLALEKAN OGUNDIMU</dc:creator>
      <pubDate>Fri, 29 May 2026 12:03:41 +0000</pubDate>
      <link>https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc</link>
      <guid>https://dev.to/olalekan_ogundimu/from-a-3-day-deadline-disaster-to-a-real-product-reviving-my-first-full-stack-project-11lc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-29"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Course Allocation System&lt;/strong&gt; is a department-level web portal that lets academic administrators manage lecturers, courses, and timetable allocations — and lets every lecturer log in to view their own assigned schedule.&lt;/p&gt;

&lt;p&gt;But this isn't just a project. This is the project that started everything for me.&lt;/p&gt;

&lt;p&gt;I began programming seriously in 2024. My first real full-stack challenge was to build something presentable for a school project deadline. I chose a course allocation system because it was a real problem my department had — lecturers not knowing their schedules, admins managing everything manually. I had three days. I built it. It worked just enough to demo and walk away from.&lt;/p&gt;

&lt;p&gt;And then I abandoned it.&lt;/p&gt;

&lt;p&gt;Not because I didn't care. Because I knew it was broken and I didn't yet know how to fix it properly. It sat in a GitHub repository with exactly three commits — "creataed a course allocation app", "updated the UI", "made changes to the UI" — and a codebase full of problems I could see but couldn't solve at the time.&lt;/p&gt;

&lt;p&gt;The GitHub Finish-Up-A-Thon gave me the reason to come back and actually finish it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;New repository:&lt;/strong&gt; &lt;a href="https://github.com/sam-the-champ/CA-app" rel="noopener noreferrer"&gt;https://github.com/sam-the-champ/CA-app&lt;/a&gt;&lt;br&gt;
🔗 &lt;strong&gt;Old repository:&lt;/strong&gt; &lt;a href="https://github.com/sam-the-champ/course-allocation-app" rel="noopener noreferrer"&gt;https://github.com/sam-the-champ/course-allocation-app&lt;/a&gt;&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-2060328321150230919-23" src="https://platform.twitter.com/embed/Tweet.html?id=2060328321150230919"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2060328321150230919-23');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2060328321150230919&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the revived app does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin logs in with securely hashed credentials stored in MongoDB&lt;/li&gt;
&lt;li&gt;Admin can add lecturers, create courses, and allocate courses to lecturers with day, time, level, and session details&lt;/li&gt;
&lt;li&gt;Dashboard shows live stats — total lecturers, total courses, allocated vs unallocated&lt;/li&gt;
&lt;li&gt;Lecturers log in and see only their own profile and timetable&lt;/li&gt;
&lt;li&gt;Logging out clears the session completely — the browser back button cannot return you into the dashboard&lt;/li&gt;
&lt;li&gt;Fully deployed: React frontend on Vercel, Express backend on vercel also.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;strong&gt;Check it Live:&lt;/strong&gt; &lt;a href="https://course-allocation-app2.vercel.app/" rel="noopener noreferrer"&gt;https://course-allocation-app2.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;Let me show you exactly what I came back to.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Before: Three Commits and a Lot of Problems
&lt;/h3&gt;

&lt;p&gt;Here is the entire commit history of the original project:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d9eebr9ivds0i05nzuw.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%2F0d9eebr9ivds0i05nzuw.png" alt="Before commit log showing only 3 commits: " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three commits. Built in a rush. Pushed and abandoned.&lt;/p&gt;

&lt;p&gt;This was the old admin dashboard:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1i8unkttpnt35oype9ye.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%2F1i8unkttpnt35oype9ye.png" alt="Old admin dashboard with green sidebar and yellow stat numbers on green cards" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the old Add Lecturer page:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuwl3a3sqiujnua4ktz8.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%2Fmuwl3a3sqiujnua4ktz8.png" alt="Old Add Lecturer form with basic white card on grey background, green sidebar" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the old lecturer dashboard — the page every lecturer was supposed to log into and see their courses:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F075icab6og47pvk7eoob.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%2F075icab6og47pvk7eoob.png" alt="Old lecturer dashboard showing Welcome Mr. Adedayo with empty course table and basic green theme" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The UI was functional enough to demonstrate. But under the hood, it was a completely different story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is the single most embarrassing line in the old codebase:&lt;/strong&gt;&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F69adijhfwb0atxvurbhr.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%2F69adijhfwb0atxvurbhr.png" alt="Code showing hardcoded Codespace URL: fetch('https://literate-space-pancake-v9545xq5v5qh6qrq-5000.app.github.dev/api/admin/get-data')" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That URL — &lt;code&gt;https://literate-space-pancake-v9545...app.github.dev&lt;/code&gt; — is a GitHub Codespace URL. It was my live development environment URL, hardcoded directly into the frontend JavaScript. The moment I closed that Codespace, every single API call in the application broke. The app only ever worked on my machine, during that one session, on the day I built it.&lt;/p&gt;

&lt;p&gt;This was not the only problem. Here is the full list of what I found when I came back:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The entire frontend — HTML, CSS, and JavaScript files — lived inside the backend folder. One tangled directory for everything&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;controllers/&lt;/code&gt; folder existed but was completely empty. Every piece of business logic was stuffed directly into the route files&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Allocation&lt;/code&gt; model existed as a Mongoose schema but was never used anywhere. Allocations were embedded as arrays inside the Lecturer document&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Admin credentials were hardcoded as plain text directly in &lt;code&gt;authRoutes.js&lt;/code&gt;: &lt;code&gt;username: 'admin', password: 'admin123'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lecturer login did not issue a JWT token. It just returned the lecturer's raw ID string and called it a token&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;authMiddleware&lt;/code&gt; existed in the codebase but was applied to exactly zero routes — every endpoint was completely unprotected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Broken logic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;models/Admin.js&lt;/code&gt; exported &lt;code&gt;mongoose.models.Admin&lt;/code&gt; instead of registering a model — meaning it exported &lt;code&gt;undefined&lt;/code&gt;. Admin authentication could never work with the database&lt;/li&gt;
&lt;li&gt;The phone field was saved as &lt;code&gt;phone&lt;/code&gt; in routes but defined as &lt;code&gt;phonenumber&lt;/code&gt; in the schema — phone numbers were silently dropped on every single save&lt;/li&gt;
&lt;li&gt;The admin dashboard's course counter always returned &lt;code&gt;undefined&lt;/code&gt; because of a nested array traversal bug&lt;/li&gt;
&lt;li&gt;Logout was defined as &lt;code&gt;POST&lt;/code&gt; on the server but called as &lt;code&gt;GET&lt;/code&gt; from the frontend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what a first project built under deadline pressure looks like. It's not pretty. But it's honest.&lt;/p&gt;




&lt;h3&gt;
  
  
  The After: A Real Application
&lt;/h3&gt;

&lt;p&gt;This is the new lecturer dashboard:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fde9crrpyq7ejjhrbij9j.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%2Fde9crrpyq7ejjhrbij9j.png" alt="New lecturer dashboard showing Lecturer's profile card with navy/gold design, clean typography, department shown in gold, email and ID displayed" width="800" height="403"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;And the new admin dashboard:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2gw0q475yc4wi8ov72an.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%2F2gw0q475yc4wi8ov72an.png" alt="admin dashboard showing the new layout" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same page. Same purpose. Completely rebuilt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is everything that changed:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Fully separated frontend (&lt;code&gt;/frontend&lt;/code&gt; — React + Vite) and backend (&lt;code&gt;/backend&lt;/code&gt; — Express) into independent deployable projects&lt;/p&gt;

&lt;p&gt;✅ All business logic moved into proper controllers — &lt;code&gt;authController&lt;/code&gt;, &lt;code&gt;adminController&lt;/code&gt;, &lt;code&gt;lecturerController&lt;/code&gt; — routes are now thin URL-to-function maps&lt;/p&gt;

&lt;p&gt;✅ Fixed &lt;code&gt;Admin.js&lt;/code&gt; model — it now correctly registers with &lt;code&gt;mongoose.model('Admin', adminSchema)&lt;/code&gt; instead of exporting undefined&lt;/p&gt;

&lt;p&gt;✅ Admin credentials stored in MongoDB, password hashed with bcrypt, created via a one-time &lt;code&gt;npm run seed&lt;/code&gt; script — no credentials anywhere in source code&lt;/p&gt;

&lt;p&gt;✅ Real JWT authentication for both admin and lecturer login, with &lt;code&gt;protect&lt;/code&gt;, &lt;code&gt;adminOnly&lt;/code&gt;, and &lt;code&gt;lecturerOnly&lt;/code&gt; middleware applied to every protected route&lt;/p&gt;

&lt;p&gt;✅ &lt;code&gt;Allocation&lt;/code&gt; promoted to a proper first-class MongoDB collection with a compound unique index — no more embedded arrays&lt;/p&gt;

&lt;p&gt;✅ All API calls centralised in a single &lt;code&gt;src/api/index.js&lt;/code&gt; file using axios — base URL from environment variables — no hardcoded URLs anywhere in the application&lt;/p&gt;

&lt;p&gt;✅ React frontend with React Router v6, &lt;code&gt;AuthContext&lt;/code&gt; for shared authentication state, and &lt;code&gt;&amp;lt;Navigate replace /&amp;gt;&lt;/code&gt; on logout so the back button cannot re-enter a protected route&lt;/p&gt;

&lt;p&gt;✅ Unified field naming — &lt;code&gt;phoneNumber&lt;/code&gt; consistent across model, controller, and frontend&lt;/p&gt;

&lt;p&gt;✅ Global error handler middleware — consistent error response shape across every endpoint&lt;/p&gt;

&lt;p&gt;✅ Backend deployed on Render, frontend deployed on Vercel&lt;/p&gt;

&lt;p&gt;The before and after is not subtle. This went from something that only worked during one Codespace session to something I can actually hand to a department and say: use this.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;Copilot was involved at every stage of this revival, and there were two moments where it genuinely changed what I was able to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Moment 1: The Codebase Audit
&lt;/h3&gt;

&lt;p&gt;Before I wrote a single line of new code, I pasted the old route files into Copilot and asked it to identify weaknesses, inconsistencies, and broken logic. It found the hardcoded credentials, the unused middleware, the field name mismatch between &lt;code&gt;phone&lt;/code&gt; and &lt;code&gt;phonenumber&lt;/code&gt;, and the broken dashboard counter. Seeing the problems written out as a structured list — not buried in messy code — made the scope of the work clear and gave me a real roadmap. That audit became the plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Moment 2: The Vercel Seed Problem
&lt;/h3&gt;

&lt;p&gt;This is the Copilot moment I will remember most. When I deployed the backend to Vercel, I realised I had no way to run &lt;code&gt;npm run seed&lt;/code&gt; to create the admin account — because unlike Render, Vercel doesn't provide a persistent shell environment.&lt;/p&gt;

&lt;p&gt;I described the exact problem to Copilot:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktr0uqljf9x1jpvyq6ey.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%2Fktr0uqljf9x1jpvyq6ey.png" alt="Copilot conversation showing the question about running npm run seed on Vercel since it has no shell environment, with Copilot's structured response about the problem and solutions" width="799" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copilot read my repository structure, confirmed it had found my &lt;code&gt;seed.js&lt;/code&gt; file, explained exactly why the problem was happening, and then gave me two concrete solutions — convert the seed into a one-time API endpoint, or switch to a platform with shell access like Render.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n1sbodma1xoy40wgtbb.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%2F9n1sbodma1xoy40wgtbb.png" alt="Copilot showing Option 1: Create a Seed API Endpoint with actual code for seed.ts router" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It even gave me the exact code for the seed route and told me how to register it in &lt;code&gt;server.js&lt;/code&gt;. Without this, admin login on the deployed version would have been impossible and I would have been stuck for hours trying to figure out why.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day-to-Day Usage
&lt;/h3&gt;

&lt;p&gt;Beyond those two moments, Copilot was my constant pair programmer throughout the rebuild:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6qjjpq0rvqa97c54cuj.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%2Fp6qjjpq0rvqa97c54cuj.png" alt="VS Code Codespaces showing Copilot chat panel open alongside LoginPage.jsx, with the new project file structure visible — api, context, admin, lecturer folders all properly separated" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I was working on the &lt;code&gt;LoginPage.jsx&lt;/code&gt; mobile view, I could describe what I needed in plain English and Copilot would generate the layout logic. When I was wiring up the React Router protected routes, it helped me get the &lt;code&gt;&amp;lt;Navigate replace /&amp;gt;&lt;/code&gt; pattern right on the first try — which is what makes the logout-then-back-button behaviour work correctly.&lt;/p&gt;

&lt;p&gt;The way I used Copilot was not "write this for me." It was more like having a senior developer sitting next to me who knew the codebase as well as I did and could answer "what's wrong here?" or "how do I do this properly?" in seconds instead of hours of searching.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Project Means
&lt;/h2&gt;

&lt;p&gt;I started programming in 2024. This was my first full-stack project. It was messy, it was rushed, and I walked away from it feeling like I had failed at something I genuinely wanted to build.&lt;/p&gt;

&lt;p&gt;Coming back to it — not just to touch it up but to understand every flaw and fix every single one — is the most I have learned in a single sprint since I started coding. I understand authentication flows, REST architecture, React state management, and deployment pipelines at a level I simply did not before.&lt;/p&gt;

&lt;p&gt;And now there is actually a real application at the end of it. One that works. One I am proud of. One that my department could use.&lt;/p&gt;

&lt;p&gt;That is what finishing things does.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Node.js, Express, MongoDB, React, Vite, and GitHub Copilot.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Frontend: Vercel | Backend: Vercel&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>Solace: A Global Mental Health First Responder Built with Gemma 4</title>
      <dc:creator>OLALEKAN OGUNDIMU</dc:creator>
      <pubDate>Fri, 22 May 2026 11:09:12 +0000</pubDate>
      <link>https://dev.to/olalekan_ogundimu/solace-a-global-mental-health-first-responder-built-with-gemma-4-1k8g</link>
      <guid>https://dev.to/olalekan_ogundimu/solace-a-global-mental-health-first-responder-built-with-gemma-4-1k8g</guid>
      <description>&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;970 million people worldwide live with mental health disorders.&lt;/p&gt;

&lt;p&gt;But almost every mental health tool built with AI assumes the same user: fast internet, English as a first language, a US or UK phone number to call in a crisis.&lt;/p&gt;

&lt;p&gt;That's not 970 million people. That's maybe 50 million.&lt;/p&gt;

&lt;p&gt;I'm a developer based in Lagos, Nigeria. When I looked at the mental health AI tools being built, I kept asking the same question: &lt;strong&gt;what happens when someone in Accra, Nairobi, Manila, or São Paulo needs help at 2am?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They get a chatbot that tells them to call 988.&lt;/p&gt;

&lt;p&gt;That's the gap Solace was built to close.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Solace?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Solace&lt;/strong&gt; is a voice-first, privacy-focused mental health companion powered by Gemma 4. It listens, assesses, and connects people to real help — wherever they are in the world.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://slcai-sm9m.vercel.app/" rel="noopener noreferrer"&gt;https://slcai-sm9m.vercel.app/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/sam-the-champ/SLCAI" rel="noopener noreferrer"&gt;https://github.com/sam-the-champ/SLCAI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Demo Video:&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/8gFdeSJF3zQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes Solace different
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 🌍 Localized crisis resources for 13+ countries
&lt;/h3&gt;

&lt;p&gt;Most mental health AI tools are built with US resources baked in. If you're not American, you're on your own.&lt;/p&gt;

&lt;p&gt;Solace auto-detects your country from your browser timezone and immediately surfaces the right crisis lines, text lines, and chat services for &lt;strong&gt;Nigeria, Ghana, Kenya, South Africa, Zimbabwe, India, UK, USA, Canada, Australia, Philippines, Singapore, Brazil&lt;/strong&gt; — and falls back to international resources for everywhere else.&lt;/p&gt;

&lt;p&gt;No settings. No configuration. It just knows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getResourcesByTimezone&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;CountryResources&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;resolvedOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;timeZone&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tzToCountry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Africa/Lagos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Africa/Accra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GH&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Africa/Nairobi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;KE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...13+ countries&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tzToCountry&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;resourcesByCountry&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;resourcesByCountry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEFAULT&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 🎤 Voice-first input
&lt;/h3&gt;

&lt;p&gt;When someone is in distress, typing is a barrier. Solace has a one-tap voice input powered by the Web Speech API — speak your feelings, Solace listens.&lt;/p&gt;

&lt;p&gt;No third-party API. No extra cost. Works in the browser natively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SpeechRecognition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SpeechRecognition&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webkitSpeechRecognition&lt;/span&gt;
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;continuous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interimResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 🧠 Trauma-informed triage with Gemma 4
&lt;/h3&gt;

&lt;p&gt;Every message is assessed across four triage levels: &lt;strong&gt;Low → Moderate → High → Crisis&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Gemma 4's 128K context window and deep instruction-following made it the right model for this. The system prompt is carefully crafted to avoid clinical coldness while still being precise enough to catch crisis signals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Triage levels:&lt;/span&gt;
&lt;span class="c1"&gt;// low: mild everyday stress, general worry&lt;/span&gt;
&lt;span class="c1"&gt;// moderate: persistent sadness, sleep issues, social withdrawal  &lt;/span&gt;
&lt;span class="c1"&gt;// high: panic attacks, trauma symptoms, major crisis&lt;/span&gt;
&lt;span class="c1"&gt;// crisis: suicidal ideation, self-harm, immediate danger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At crisis level, the entire UI shifts — emergency resources move to the top, the call button becomes prominent, and the AI's tone changes to prioritize connection to real help over conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 📔 Private mood journal
&lt;/h3&gt;

&lt;p&gt;Every check-in is saved to a local mood journal — stored entirely in &lt;code&gt;localStorage&lt;/code&gt;. No server. No account. No data leaving the device.&lt;/p&gt;

&lt;p&gt;Users can track patterns across sessions: when they tend to feel worse, whether things are improving, what their check-ins look like over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. 📱 Installable PWA
&lt;/h3&gt;

&lt;p&gt;Solace is a Progressive Web App. On mobile, users can install it directly to their home screen — no app store, no download, works in low-bandwidth conditions.&lt;/p&gt;

&lt;p&gt;This matters enormously in markets like Nigeria where data costs are high and storage is limited. A 2MB installable app beats a 200MB download every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Gemma 4 specifically?
&lt;/h2&gt;

&lt;p&gt;This is the question that matters most, so let me be direct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I chose Gemma 4 31B because:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The 128K context window&lt;/strong&gt; means Solace can hold a full therapeutic conversation — not just one or two turns. Mental health support isn't transactional. People circle back. They contradict themselves. They need to feel heard across a long exchange.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Instruction-following precision&lt;/strong&gt; — the triage system depends on Gemma 4 returning structured JSON reliably, with emotional nuance baked into the &lt;code&gt;summary&lt;/code&gt;, &lt;code&gt;patterns&lt;/code&gt;, &lt;code&gt;strategies&lt;/code&gt;, and &lt;code&gt;affirmation&lt;/code&gt; fields. I tested with smaller models. The quality gap was significant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It's open.&lt;/strong&gt; Gemma 4 can be self-hosted. That means a clinic in Lagos or a NGO in Nairobi could eventually run this on their own infrastructure, with no API costs and full data sovereignty. That's a future worth building toward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Privacy story.&lt;/strong&gt; Every conversation stays between the user and the model. Solace doesn't log, store, or transmit conversation data. For mental health, that's not a feature — it's a requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React + Vite + TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling:&lt;/strong&gt; CSS custom properties, glassmorphism UI, no component library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Gemma 4 31B via OpenRouter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice:&lt;/strong&gt; Web Speech API (native browser)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; localStorage (journal, no server)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PWA:&lt;/strong&gt; Web App Manifest + service worker ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy:&lt;/strong&gt; Vercel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The hardest part
&lt;/h2&gt;

&lt;p&gt;Building the crisis response flow was the hardest and most important part of this project.&lt;/p&gt;

&lt;p&gt;When Gemma 4 returns &lt;code&gt;triageLevel: "crisis"&lt;/code&gt;, everything changes. The UI shifts to red. The emergency number for the user's country moves above the fold. The AI's system prompt switches to a mode focused entirely on staying present and bridging to real help — not providing therapy.&lt;/p&gt;

&lt;p&gt;Getting that balance right — compassionate but not clinical, urgent but not alarming — took more iteration than anything else in the codebase.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Offline-first fallback responses&lt;/strong&gt; — cached grounding techniques that work with no internet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More languages&lt;/strong&gt; — French, Hausa, Swahili, Portuguese&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More countries&lt;/strong&gt; — currently 13, targeting 30+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NGO partnership mode&lt;/strong&gt; — white-label for mental health organizations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://slcai-sm9m.vercel.app/" rel="noopener noreferrer"&gt;https://slcai-sm9m.vercel.app/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open it on your phone. Tap a mood. Speak how you're feeling. See what country resources appear for you.&lt;/p&gt;

&lt;p&gt;If you're building in the mental health space or you work with communities that are underserved by current AI tools — I'd love to hear from you in the comments.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Solace is an AI companion, not a therapist or medical service. If you are in crisis, please contact your local emergency services.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
      <category>mentalhealth</category>
    </item>
  </channel>
</rss>
