<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged githubchallenge</title>
<link>https://coderlegion.com/tag/githubchallenge</link>
<description>Powered by Question2Answer</description>
<item>
<title>I Built a CLI Tool That Fixes the &quot;Bro Send the .env File&quot; Problem</title>
<link>https://coderlegion.com/29407/i-built-a-cli-tool-that-fixes-the-bro-send-the-env-file-problem</link>
<description>&lt;h3 id=&quot;what-i-built&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;Every dev team has this conversation. Someone joins a project, opens their terminal, and the first message they send is &quot;bro can you send the .env file&quot; — and someone else pastes it raw on WhatsApp or Slack like it's nothing. API keys, database passwords, Stripe secrets, all of it flying around in plaintext on chat apps.&lt;/p&gt;
&lt;p&gt;I built &lt;strong&gt;envman&lt;/strong&gt; &lt;br&gt;
a CLI tool that syncs &lt;code&gt;.env&lt;/code&gt; files across dev teams securely. Two commands is all it takes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;envman push   # encrypts your .env and uploads it
envman get    # pulls, shows a diff, asks before overwriting
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The entire &lt;code&gt;.env&lt;/code&gt; is encrypted with AES-256-GCM on your machine before it ever leaves it. The server stores only ciphertext. Even if the database gets compromised, secrets are unreadable without the user's token. Built entirely in Go — a CLI binary and a REST API backend with JWT auth, role-based access control (owner, coordinator, member), and a full audit trail of every push.&lt;/p&gt;
&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/SaranHiruthikM/envman&quot;&gt;https://github.com/SaranHiruthikM/envman&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ envman register
Name: Saran
Email: saran@example.com
Password:
Registered and logged in successfully

$ cd myproject
$ envman init
Project name: my-app
Project 'my-app' created and linked
.envman.json created — commit this to git

$ envman push
Secrets pushed successfully

# teammate on another machine
$ envman get
Changes:
  + STRIPE_KEY=*** (new)
  ~ DATABASE_URL=*** (changed)

Apply changes? [y/n]: y
.env updated
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;the-comeback-story&quot;&gt;The Comeback Story&lt;/h3&gt;
&lt;p&gt;This project lived in my head for weeks. I knew the problem was real — I had sent &lt;code&gt;.env&lt;/code&gt; files over WhatsApp myself more times than I want to admit. But every time I sat down to build it I got stuck on questions I hadn't answered: where do secrets actually live, how do roles work, what happens when two people have conflicting values, how does encryption work without a shared key.&lt;/p&gt;
&lt;p&gt;The project had a rough &lt;code&gt;main.go&lt;/code&gt; and nothing else.&lt;/p&gt;
&lt;p&gt;What changed: I forced myself to design everything before touching code. The database schema, the API endpoints, the role system, the encryption approach — all of it locked down first. Once the design was solid, the code almost wrote itself. In three weeks I went from a blank file to a working CLI with a full backend, migrations, middleware, client-side encryption, and a diff engine.&lt;/p&gt;
&lt;p&gt;The hardest part wasn't the code. It was resisting the urge to skip the design phase and just start typing. Every hour I spent thinking before coding saved me three hours of rewriting later.&lt;/p&gt;
&lt;p&gt;The moment it clicked was when I ran:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rm .env
envman get
cat .env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And my secrets came back perfectly decrypted. That felt real.&lt;/p&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot&quot;&gt;My Experience with GitHub Copilot&lt;/h3&gt;
&lt;p&gt;I used Copilot mostly as a thinking partner rather than a code generator. The parts where it genuinely helped were the repetitive but error-prone ones — writing SQL scan statements where column order matters, getting the AES-GCM nonce handling right, and wiring up cobra command flags.&lt;/p&gt;
&lt;p&gt;What surprised me was how useful it was for catching things I would have missed on a first pass — like forgetting a &lt;code&gt;return&lt;/code&gt; after an error response, or using &lt;code&gt;||&lt;/code&gt; instead of &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; in a role check that would have let anyone through. Small things that would have cost me 30 minutes of debugging each.&lt;/p&gt;
&lt;p&gt;Where I deliberately didn't use it was in the design decisions — the schema, the role model, the encryption architecture. Those needed to be mine. Copilot is good at &quot;how do I write this&quot; but the &quot;what should I build and why&quot; has to come from you. That line matters more than people admit.&lt;/p&gt;
&lt;p&gt;envman is live, open source, and something I'll actually use on my own projects. That's the bar I set for myself — build something real enough that you reach for it yourself.&lt;/p&gt;
&lt;p&gt;Any doubts, questions or suggestions, you can reach out to my mail.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/29407/i-built-a-cli-tool-that-fixes-the-bro-send-the-env-file-problem</guid>
<pubDate>Thu, 01 Oct 2026 12:21:58 +0000</pubDate>
</item>
<item>
<title>Finishing the e-commerce app I abandoned in 2023</title>
<link>https://coderlegion.com/25858/finishing-the-e-commerce-app-i-abandoned-in-2023</link>
<description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/challenges/github-2026-05-21&quot;&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-i-built-1&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GlowStore&lt;/strong&gt; — a full-stack MERN e-commerce store (React + Redux + Express + MongoDB).&lt;/p&gt;
&lt;p&gt;Back in 2023 I built this as my university &lt;em&gt;Web Engineering&lt;/em&gt; final project. I ran&lt;br&gt;
out of time, handed in what I had, and never touched it again. When I reopened&lt;br&gt;
it for this challenge I found something funny: the &lt;strong&gt;backend was basically&lt;br&gt;
finished&lt;/strong&gt; — JWT auth, products, orders, reviews, search — but the &lt;strong&gt;React&lt;br&gt;
frontend never actually talked to it.&lt;/strong&gt; It was a good-looking shell with fake&lt;br&gt;
logic bolted on. So &quot;finishing it&quot; meant connecting the two halves and making it&lt;br&gt;
a real store you can actually shop in.&lt;/p&gt;
&lt;p&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/hashaam-011/Web-Engineering&quot;&gt;https://github.com/hashaam-011/Web-Engineering&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;demo-1&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; — the entire app was just a fake login screen. Typing anything (or&lt;br&gt;
nothing) and clicking &quot;Log in&quot; flipped a boolean and &quot;logged you in&quot;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gw522rvw4rs76i42zw5y.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; — a working storefront with products from the database:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3uhog0lcw787ggs1ik16.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;A real product detail page (was literally &lt;code&gt;&amp;lt;h1&amp;gt;DetailsPages&amp;lt;/h1&amp;gt;&lt;/code&gt; before):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6bdelrnwmbww4pi1fli.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6167z0y0kxi4uvieeols.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can run it yourself in two terminals (no database setup needed — it boots an&lt;br&gt;
in-memory MongoDB and seeds itself):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd backend &amp;amp;&amp;amp; npm install &amp;amp;&amp;amp; npm start   # http://localhost:4000
npm install &amp;amp;&amp;amp; npm start                 # http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Demo login: &lt;code&gt;user@example.com&lt;/code&gt; / &lt;code&gt;123456&lt;/code&gt; — or register a new account.&lt;/p&gt;
&lt;h3 id=&quot;the-comeback-story-1&quot;&gt;The Comeback Story&lt;/h3&gt;
&lt;p&gt;Here's what the project looked like &lt;strong&gt;before&lt;/strong&gt;, and what I changed:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Before &lt;/th&gt;&lt;th&gt;After&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Login dispatched a boolean and ignored your credentials &lt;/td&gt;&lt;td&gt;Real login/register against the API with JWT + bcrypt&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Frontend never called the backend (no axios anywhere) &lt;/td&gt;&lt;td&gt;Axios client with token injection; products load from MongoDB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Product details page was &lt;code&gt;&amp;lt;h1&amp;gt;DetailsPages&amp;lt;/h1&amp;gt;&lt;/code&gt; and wasn't routed &lt;/td&gt;&lt;td&gt;Full details page (image, price, stock, rating) routed by slug&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Cart was local-only; &quot;checkout&quot; button did nothing &lt;/td&gt;&lt;td&gt;Persistent cart → checkout → real order placed and saved&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Backend had a reviews endpoint the UI never used &lt;/td&gt;&lt;td&gt;Product reviews: read them and post your own with a star rating&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Only 3 routes; most of the app was unreachable &lt;/td&gt;&lt;td&gt;Home, login, register, details, account, checkout, orders&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Typos baked in (&lt;code&gt;Regsiter&lt;/code&gt;, &lt;code&gt;isLoggIn&lt;/code&gt;), &lt;code&gt;console.log&lt;/code&gt; in render, logo linked to a random site &lt;/td&gt;&lt;td&gt;Cleaned up, renamed, fixed scroll/header bugs&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;A live MongoDB password was committed in &lt;code&gt;.env&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Removed from tracking, &lt;code&gt;.env.example&lt;/code&gt; added&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I tracked the whole revival in &lt;strong&gt;30 small commits&lt;/strong&gt; so the before → after journey&lt;br&gt;
is visible in the history, from &quot;stop tracking node_modules&quot; to &quot;add the orders&lt;br&gt;
page.&quot;&lt;/p&gt;
&lt;h3 id=&quot;my-experience-with-ai-assisted-development&quot;&gt;My Experience with AI-Assisted Development&lt;/h3&gt;
&lt;p&gt;I leaned on AI assistance heavily to finish this. The most useful parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mapping the gap fast.&lt;/strong&gt; The first win was having the codebase read end-to-end&lt;br&gt;
and getting a precise list of what worked vs. what was fake — that turned a&lt;br&gt;
vague &quot;it's unfinished&quot; into a concrete checklist.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wiring the integration layer.&lt;/strong&gt; Generating the axios client, the Redux&lt;br&gt;
thunks for login/register, and the product/cart/order slices was where it saved&lt;br&gt;
the most time — lots of boilerplate that's easy to get subtly wrong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Filling the missing pages.&lt;/strong&gt; The checkout form, order summary math (items +&lt;br&gt;
shipping + tax), and the orders history page came together quickly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unblocking the environment.&lt;/strong&gt; Docker wouldn't start on my machine, so instead&lt;br&gt;
of stalling I switched the backend to an in-memory MongoDB with auto-seeding —&lt;br&gt;
now anyone can clone and run it with zero setup.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The thing I'd tell other people reviving an old project: don't start by writing&lt;br&gt;
code. Start by getting an honest map of what's actually there. Half of &quot;finishing&quot;&lt;br&gt;
turned out to be deleting fake logic, not adding new features.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/25858/finishing-the-e-commerce-app-i-abandoned-in-2023</guid>
<pubDate>Sun, 30 Aug 2026 14:13:50 +0000</pubDate>
</item>
<item>
<title>My First Global Hackathon: What I Learned Building Moonsu Link</title>
<link>https://coderlegion.com/21863/my-first-global-hackathon-what-i-learned-building-moonsu-link</link>
<description>&lt;p&gt;This was my first global hackathon, with 500+ participants from around the world, and although I didn’t win, I’m honestly proud of how much I learned from the experience.&lt;/p&gt;
&lt;p&gt;I worked on &lt;strong&gt;Moonsu Link&lt;/strong&gt;, a project I care about deeply. It wasn’t just about building something technical. It was about trying to solve a real problem and pushing an unfinished idea all the way into something more complete, more usable, and more meaningful.&lt;/p&gt;
&lt;p&gt;Like many hackathon projects, Moonsu Link came with its own challenges. There were moments of uncertainty, moments where the product needed more structure, and moments where it would have been easy to slow down or stop. But I kept going because I believed the idea was worth finishing.&lt;/p&gt;
&lt;h3 id=&quot;the-power-of-collaboration-amp-community&quot;&gt;The Power of Collaboration &amp;amp; Community&lt;/h3&gt;
&lt;p&gt;What made this experience special was the teamwork. Building with others, sharing ideas, dividing responsibilities, and trying to keep the momentum alive taught me a lot about collaboration. A hackathon is not just about code. It is also about communication, trust, iteration, and resilience.@alchemycodes @yvesdylane &lt;/p&gt;
&lt;p&gt;I also learned that progress matters, even when the final result is not a win. Finishing something, improving it, and learning through the process can be just as valuable as a prize.&lt;/p&gt;
&lt;p&gt;One of the things I’m happy about is that I received a badge from the DEVPost community. That recognition means a lot to me because it reflects the effort, growth, and persistence behind the project.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h3&gt;
&lt;p&gt;This hackathon reminded me that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;First attempts are still valuable&lt;/strong&gt; – Every expert was once a beginner. Starting is half the battle.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Teamwork makes a huge difference&lt;/strong&gt; – Bouncing ideas off others and distributing tasks accelerates growth.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Challenges are part of the process&lt;/strong&gt; – Friction and bugs are inevitable; navigating them builds engineering maturity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not winning does not mean losing&lt;/strong&gt; – The knowledge and connections gained are permanent assets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learning and finishing count&lt;/strong&gt; – Shipping a complete product cycle is a victory in itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;moving-forward&quot;&gt;Moving Forward&lt;/h3&gt;
&lt;p&gt;Moonsu Link may not have taken the top prize, but it gave me something important: experience, confidence, and a stronger mindset for the next challenge. &lt;/p&gt;
&lt;p&gt;I’m grateful for the opportunity, grateful for the people I worked with, and grateful that I chose not to give up. &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Have you ever participated in a global hackathon? What was your biggest takeaway from your first dev challenge? Let's connect in the comments below!&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21863/my-first-global-hackathon-what-i-learned-building-moonsu-link</guid>
<pubDate>Sat, 04 Jul 2026 02:55:05 +0000</pubDate>
</item>
<item>
<title>From Prototype to Production: Finishing Moonsu Link, a Chat-Native Agricultural Marketplace for Cameroon</title>
<link>https://coderlegion.com/21862/from-prototype-production-finishing-moonsu-native-agricultural-marketplace-cameroon</link>
<description>&lt;p&gt;&lt;em&gt;This is a submission for the GitHub Finish-Up-A-Thon Challenge&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What We Built&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Moonsu Link is a chat-native agricultural marketplace built for farmers and buyers in Cameroon.&lt;/p&gt;
&lt;p&gt;In Cameroon, agriculture is central to daily life, but the way products are bought and sold is still fragmented. In many towns, roadside markets and middlemen control access to buyers. In rural areas, farmers often depend on word of mouth, informal contacts, or market days to move their goods.&lt;/p&gt;
&lt;p&gt;That creates real friction.&lt;/p&gt;
&lt;p&gt;A farmer in Bamenda, Bafoussam, Douala, or Yaoundé may have produce ready, but still struggle to find a buyer quickly, get a fair price, or know where demand is strongest. At the same time, many people already use WhatsApp and Telegram every day, while mobile data costs, app installs, and complicated onboarding can get in the way. Language matters too. Cameroon is bilingual, and any useful product has to feel natural in both English and French while staying simple enough for users with different levels of digital comfort.&lt;/p&gt;
&lt;p&gt;Moonsu Link was built to close that gap by bringing the marketplace into the chat apps people already use. The goal is to reduce friction and make trade feel more direct, local, and trustworthy.&lt;/p&gt;
&lt;p&gt;The idea is simple:&lt;br&gt;
help farmers list produce easily, help buyers search in plain language, and let both sides trade without needing a separate app.&lt;/p&gt;
&lt;p&gt;Instead of pushing users into a dashboard-first experience, Moonsu Link works through WhatsApp and Telegram, the platforms people already know.&lt;/p&gt;
&lt;p&gt;With Moonsu Link, a farmer can list produce with location, price, quantity, and optional photos. Buyers can search naturally, compare listings, check market prices, and express interest. The platform also supports farmer verification, community reports, farming advice, voice messages, and cross-platform use across WhatsApp and Telegram.&lt;/p&gt;
&lt;p&gt;What began as an unfinished idea is now a real product with a clear user flow, a polished web presence, and a backend that connects messaging, AI, search, verification, and notifications into one system.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Demo&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Live app: &lt;a rel=&quot;nofollow&quot; href=&quot;https://moonsulink.vercel.app&quot;&gt;https://moonsulink.vercel.app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub repository:&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/yvesdylane/Moonsun-Link-api&quot;&gt;https://github.com/yvesdylane/Moonsun-Link-api&lt;/a&gt; , &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/yvesdylane/MoonsuLinkFrontend&quot;&gt;https://github.com/yvesdylane/MoonsuLinkFrontend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Video walkthrough: &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/6skq9w_mw-s?si=c5YCVunZ3RC5Qfqs&quot;&gt;https://youtu.be/6skq9w_mw-s?si=c5YCVunZ3RC5Qfqs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Screenshots:!Moonsu Telegram Bot(&lt;a rel=&quot;nofollow&quot; href=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1ewivz77iwyli4gh01a.jpeg&quot;&gt;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b1ewivz77iwyli4gh01a.jpeg&lt;/a&gt;) , &lt;br&gt;
!Moonsu Whatsapp (&lt;a rel=&quot;nofollow&quot; href=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/op3lmh99vio6zbxu4bcl.jpg&quot;&gt;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/op3lmh99vio6zbxu4bcl.jpg&lt;/a&gt;) , &lt;br&gt;
!Moonsu Admin Dahboard(&lt;a rel=&quot;nofollow&quot; href=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cit70l8bc84pijmworrj.jpg&quot;&gt;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cit70l8bc84pijmworrj.jpg&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;The Comeback Story&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;!Moonsu website before finishathon(&lt;a rel=&quot;nofollow&quot; href=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nlqiwperncglto84re2.png&quot;&gt;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2nlqiwperncglto84re2.png&lt;/a&gt;)&lt;br&gt;
Moonsu Link did not start as a finished product. It began as a prototype built around a real problem, but like many hackathon projects, it never fully crossed the finish line.&lt;/p&gt;
&lt;p&gt;The idea was strong, but the product needed more structure, cleaner UX, better flow, and real end-to-end functionality before it could genuinely help users.&lt;/p&gt;
&lt;p&gt;For this challenge, We came back to it with a different mindset. We treated it like a real product, not just a demo.&lt;/p&gt;
&lt;p&gt;That meant focusing on the things that matter most:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;making the experience feel unified across WhatsApp, Telegram, and the web&lt;/li&gt;
&lt;li&gt;refining the landing page so the product story is clear immediately&lt;/li&gt;
&lt;li&gt;building a visual identity that reflects a Cameroon-first agricultural context&lt;/li&gt;
&lt;li&gt;improving backend flows for messaging, listings, verification, search, and notifications&lt;/li&gt;
&lt;li&gt;making the product feel trustworthy, usable, and ready to present to real users&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The biggest difference is that the project is no longer just an idea. It now has a clear user journey, a stronger brand, and real functionality that shows what the product is supposed to do.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Our Experience with GitHub Copilot&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;GitHub Copilot helped me move faster and finish with more confidence.&lt;/p&gt;
&lt;p&gt;It was especially useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;building repetitive frontend sections faster&lt;/li&gt;
&lt;li&gt;cleaning up component structure&lt;/li&gt;
&lt;li&gt;speeding up backend boilerplate and integrations&lt;/li&gt;
&lt;li&gt;iterating on UI copy and layout&lt;/li&gt;
&lt;li&gt;reducing friction while refactoring and finishing incomplete parts of the project&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What mattered most was not just speed, but momentum.&lt;/p&gt;
&lt;p&gt;Copilot helped us keep the project moving when we needed to turn unfinished ideas into working features and a coherent product experience.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Why This Project Matters&lt;/em&gt;&lt;br&gt;
 Agriculture is one of the most important parts of everyday life in Cameroon, but many farmers still struggle with discovery, pricing, trust, and access to buyers.&lt;/p&gt;
&lt;p&gt;Moonsu Link tries to solve that with one simple idea:&lt;/p&gt;
&lt;p&gt;Meet users where they already are.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No app install&lt;/li&gt;
&lt;li&gt;No complicated onboarding&lt;/li&gt;
&lt;li&gt;No unfamiliar workflow&lt;/li&gt;
&lt;li&gt;Just a practical marketplace inside the chat platforms people already use&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is why this project felt worth finishing. It is not just a technical build. It is a tool that could genuinely reduce friction for farmers and buyers.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Stack&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Frontend:&lt;br&gt;
Next.js 16, React 19, TypeScript, Tailwind CSS v4, Framer Motion&lt;/p&gt;
&lt;p&gt;Backend:&lt;br&gt;
FastAPI, PostgreSQL, Telegram Bot API, WhatsApp integration, AI-powered message handling, translation, voice transcription, image upload, and admin APIs&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What Changed During the Comeback&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The project went from unfinished to presentable by focusing on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a clearer product story&lt;/li&gt;
&lt;li&gt;a stronger landing page&lt;/li&gt;
&lt;li&gt;better visual consistency&lt;/li&gt;
&lt;li&gt;real cross-platform marketplace flows&lt;/li&gt;
&lt;li&gt;verification and trust features&lt;/li&gt;
&lt;li&gt;AI-assisted handling of user messages&lt;/li&gt;
&lt;li&gt;more polished communication for farmers and buyers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Authors&lt;/strong&gt;&lt;br&gt;
Main Author: &lt;em&gt;Yves Dylane @yveane &lt;/em&gt;&lt;br&gt;
Co-Author: _Chestly Amahndong @chestly&lt;em&gt;ace&lt;/em&gt;&lt;br&gt;
Co-Author: &lt;em&gt;Kanjo Elkamira @alchemycodes&lt;br&gt;
&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21862/from-prototype-production-finishing-moonsu-native-agricultural-marketplace-cameroon</guid>
<pubDate>Sat, 04 Jul 2026 02:30:59 +0000</pubDate>
</item>
<item>
<title>I've Been Building an LMS for a Year. Finish-Up-A-Thon Made Me Actually Finish It.</title>
<link>https://coderlegion.com/21356/ive-been-building-an-lms-for-a-year-finish-up-a-thon-made-me-actually-finish-it</link>
<description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/challenges/github-2026-05-21&quot;&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-i-built-2&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Training Theatre (TTT)&lt;/strong&gt; is a multi-tenant LMS where instructors can build a course in three different shapes, depending on how they teach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Story&lt;/strong&gt; — long-form written content for instructors who teach the way essayists write.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Video&lt;/strong&gt; — the conventional LMS path everyone already knows: upload a video, chapter it, ship it. The Udemy/Coursera shape.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slide&lt;/strong&gt; — composable decks built from a catalog of 20+ templates. This is where most of TTT's design budget goes, and it's the part of the product that doesn't look like every other LMS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before a slide is ever built, they walk through a setup flow: what they're building (a standalone course or a bundled program), how the course is structured (multi-format modules or a repeating pattern), and which teaching pattern fits their content. By the time they land in the slide editor, the course shape is already decided.&lt;/p&gt;
&lt;p&gt;On the slide side, the workflow goes like this: an instructor opens the slide editor, picks a layout from the catalog (&lt;code&gt;hero-text&lt;/code&gt;, &lt;code&gt;three-column&lt;/code&gt;, &lt;code&gt;comparison&lt;/code&gt;, &lt;code&gt;team&lt;/code&gt;, &lt;code&gt;closing-cta&lt;/code&gt;, and so on), and lands on a canvas. Each template exposes a set of named &lt;em&gt;zones&lt;/em&gt; — a &lt;code&gt;headline&lt;/code&gt; zone, an &lt;code&gt;items&lt;/code&gt; zone, a &lt;code&gt;cta&lt;/code&gt; zone, whatever the layout needs — and each zone declares which section types it accepts (text, list, image, callout, quote, stats, table) and how many sections it can hold. The instructor fills the zones, the editor persists the result as a &lt;code&gt;SlideGroup&lt;/code&gt; row (template choice, zone assignments, background, accent color, speaker notes), and the learner sees that same data render through &lt;code&gt;SlideCanvas&lt;/code&gt; inside &lt;code&gt;LearnerSlideDeck&lt;/code&gt;. The whole catalog is declarative — adding a new template means defining its zones, building its editor canvas, and building its learner renderer.&lt;/p&gt;
&lt;p&gt;The stack is Next.js (App Router) + TypeScript + Prisma/PostgreSQL, with Zustand and React Query on the frontend, Tiptap for rich text, and Tailwind for styling.&lt;/p&gt;
&lt;p&gt;TTT is also my first real-world professional project. I've been building it alongside my 9-5 work as a technical support — for over a year now, and most of what I currently know about shipping software I learned by getting it wrong here first: the bad schema choices I had to migrate out of, the audit logging I retrofitted across the codebase, the moderation flow I rebuilt twice. So finishing the half-done parts isn't just about cleaning up the codebase — it's about turning TTT into the portfolio piece I can confidently point to when I'm pitching for contracts or interviewing for a full-time engineering role. Finish-Up-A-Thon was a deadline I was glad to have.&lt;/p&gt;
&lt;p&gt;For the challenge, I focused on the &lt;strong&gt;slide template system&lt;/strong&gt; — the part of the product I'm proudest of. The goal was to give instructors more layout options to design with, so I worked on three templates: &lt;code&gt;closing-cta&lt;/code&gt;, &lt;code&gt;feature-list&lt;/code&gt;, and &lt;code&gt;agenda-grid&lt;/code&gt;. Some were new builds, some were modifications to existing templates to support layout patterns the original implementations couldn't handle.&lt;/p&gt;
&lt;h3 id=&quot;demo-2&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt; &lt;strong&gt;Project:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/promiselxg/trainingtheatre&quot;&gt;Training Theatre on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Live URL:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;trainingtheatre.com&quot;&gt;Training Theatre&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before &amp;amp; After — Slide Templates&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Before &lt;/th&gt;&lt;th&gt;After&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://awesomescreenshot.s3.amazonaws.com/image/1940849/61001292-5f4bc86a97e821145c8e49c7df71dfec.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20260607%2Fus-east-1%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20260607T155132Z&amp;amp;X-Amz-Expires=28800&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Signature=964c84ce3aab31f369bc233115473ab40379ac536a8ddf532faf8d8c0e8755a5&quot; alt=&quot;Templates Before&quot;&gt; &lt;/td&gt;&lt;td&gt;&lt;img src=&quot;https://awesomescreenshot.s3.amazonaws.com/image/1940849/61001277-0e3c8c17d5b13b8a89c571effccbd7da.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20260607%2Fus-east-1%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20260607T155359Z&amp;amp;X-Amz-Expires=28800&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Signature=ad3b13593abba983376fd70796a61cfca9ab0954cdac3b4bdf8cc72d5597930c&quot; alt=&quot;Templates After&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://awesomescreenshot.s3.amazonaws.com/image/1940849/61001106-f30a4bec1fc0fb241ad697637876ecaf.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20260607%2Fus-east-1%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20260607T155231Z&amp;amp;X-Amz-Expires=28800&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Signature=4ebc387972a02d4571e1337e44b238df2d1cd4c4b88c688eef36d7c0d91b61a4&quot; alt=&quot;Config Schema Before&quot;&gt; &lt;/td&gt;&lt;td&gt;&lt;img src=&quot;https://awesomescreenshot.s3.amazonaws.com/image/1940849/61001105-c8fe622bf52acc9d0feac740ff5ffed7.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;amp;X-Amz-Credential=AKIAJSCJQ2NM3XLFPVKA%2F20260607%2Fus-east-1%2Fs3%2Faws4_request&amp;amp;X-Amz-Date=20260607T155247Z&amp;amp;X-Amz-Expires=28800&amp;amp;X-Amz-SignedHeaders=host&amp;amp;X-Amz-Signature=43069e1a7c08a39fe9e0bf26a960b095607ac8341d4cce8df26ee9ae03715df4&quot; alt=&quot;Config Schema After&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt; &lt;strong&gt;Video Walkthrough&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.loom.com/share/1f238e512cd042b28cc71a2cb9e33da5&quot;&gt;Before&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.loom.com/share/3813a89c9ca24ec8acba078d1fa1cc40&quot;&gt;After&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-comeback-story-2&quot;&gt;The Comeback Story&lt;/h3&gt;
&lt;h4 id=&quot;the-shape-of-the-problem&quot;&gt;The shape of the problem&lt;/h4&gt;
&lt;p&gt;TTT's slide system has an opinionated architecture. Every template is a triple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A config schema&lt;/strong&gt; that declares the editable zones (headline, body, items, icons, tags, CTA, etc.) and feeds the editor's &lt;code&gt;PerItemConfigSlot&lt;/code&gt; so each item gets its own inline controls.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;An editor canvas&lt;/strong&gt; that renders the same component the learner will see, but wired to the Zustand store so edits are live.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A learner renderer&lt;/strong&gt; consumed by &lt;code&gt;SlideCanvas&lt;/code&gt; inside &lt;code&gt;LearnerSlideDeck&lt;/code&gt;, with &lt;code&gt;preserveAspect&lt;/code&gt; for desktop, single-column stack on mobile, and accent/background tokens pulled from &lt;code&gt;getSlideColors(group)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All three of the templates I worked on had to fit this triple pattern. For some, that meant building all three pieces fresh; for others, it meant going back into the existing config schema or renderer and extending it to support layout shapes the original implementation hadn't planned for. Either way, the shape of the work was the same: zones, canvas, renderer, ship.&lt;/p&gt;
&lt;h4 id=&quot;what-i-built-for-each&quot;&gt;What I built for each&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;closing-cta&lt;/code&gt;&lt;/strong&gt; — A closing slide built around three zones: a two-part headline (main statement + subhead), an optional call-to-action with an instructor-set button label, and optional contact info that can render as a single line or a list of items. The kind of slide a course ends on when the instructor wants the learner to enroll in the next thing, book a session, or just walk away with a way to reach them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;feature-list&lt;/code&gt;&lt;/strong&gt; — An image panel alongside a scrollable vertical list of 3–8 feature rows, each with an icon, a heading, a short body, and pill tags for stats or labels. The right pick when an instructor wants to walk through a set of features, plan inclusions, or capabilities and has a screenshot or visual to anchor the slide. It sits between &lt;code&gt;feature-grid&lt;/code&gt; (which tiles features into a grid) and &lt;code&gt;split-image&lt;/code&gt; (which works for mixed prose rather than uniform itemized rows).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;agenda-grid&lt;/code&gt;&lt;/strong&gt; — A denser cousin of the existing &lt;code&gt;agenda&lt;/code&gt; template. Where &lt;code&gt;agenda&lt;/code&gt; is a vertical list, &lt;code&gt;agenda-grid&lt;/code&gt; is a card grid: up to 8 agenda items, each card carrying a topic heading, a description, and a list of meta lines (durations, presenters, room numbers — whatever the instructor needs). It also exposes a header-bar title and a dual footer (left and right text), so it works equally well as a session agenda, a workshop schedule, or a module table-of-contents.&lt;/p&gt;
&lt;p&gt;Each one slots into the existing system without special-casing: the editor picks them up via the registry, the moderation preview renders them via the same &lt;code&gt;SlideCanvas&lt;/code&gt;, the learner deck navigates through them with the same keyboard handlers, and the mobile breakpoint collapses them the same way every other multi-column template collapses.&lt;/p&gt;
&lt;h4 id=&quot;why-this-is-the-finish&quot;&gt;Why this is the finish&lt;/h4&gt;
&lt;p&gt;The catalog was solid but had thin spots — places where instructors were forcing a layout that didn't quite fit what they were trying to say. There wasn't a clean way to end a course on a strong call-to-action, the feature list couldn't carry the kind of structured content people were trying to put in it, and there was no good dense-grid layout for agendas with a lot of items. These three templates close those gaps. Instructors have more shapes to design with now, and that's all I wanted from this work.&lt;/p&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot-1&quot;&gt;My Experience with GitHub Copilot&lt;/h3&gt;
&lt;p&gt;I used Copilot in two places for this: &lt;strong&gt;Copilot Web&lt;/strong&gt; for generating the new templates, and &lt;strong&gt;the Copilot VS Code extension&lt;/strong&gt; for fixing TypeScript errors as they came up. They played different roles, and the honest version of the story is that Copilot is dramatically more useful when you stop asking it to invent your architecture and start asking it to follow one you've already built.&lt;/p&gt;
&lt;p&gt;My Copilot Web workflow looked like this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Show, don't tell.&lt;/strong&gt; Before asking Copilot to write &lt;code&gt;feature-list&lt;/code&gt;, I'd paste the &lt;em&gt;entire&lt;/em&gt; triple for a sibling template — &lt;code&gt;feature-grid&lt;/code&gt;'s config schema, its editor canvas, and its learner renderer. Copilot needs to see the pattern before it can extend it. Without the existing files in context, it would invent plausible-but-wrong conventions; with them, it tracked my naming, my zone-assignment patterns, and my &lt;code&gt;PerItemConfigSlot&lt;/code&gt; wiring.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scope tightly.&lt;/strong&gt; Instead of &quot;build the closing-cta template,&quot; I'd ask for the config schema first, review it, then the canvas, review it, then the learner renderer. Three small, well-defined slots beats one big &quot;build me a template&quot; prompt every time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Iterate against the convention.&lt;/strong&gt; When Copilot drifted — forgetting that &lt;code&gt;tagsConfig&lt;/code&gt; needs &lt;code&gt;config.tags ?? []&lt;/code&gt; as a fallback, or returning a hardcoded color instead of pulling from &lt;code&gt;getSlideColors&lt;/code&gt;, or skipping the mobile stack breakpoint — I'd quote the convention back and ask for a fix. That's much cheaper than rewriting from scratch.&lt;/p&gt;
&lt;p&gt;The VS Code extension played a different role: &lt;strong&gt;TypeScript triage&lt;/strong&gt;. TTT has its share of generic-heavy types — Prisma's generated types, Zustand stores with typed slices, discriminated unions on section types — and when something didn't compile, having an inline assistant that could read the actual error against the surrounding types saved a lot of context-switching to the browser. Most of my use there was on the order of &lt;em&gt;&quot;why is this &lt;code&gt;SlideSection&lt;/code&gt; not assignable to that &lt;code&gt;SlideSection&lt;/code&gt;&quot;&lt;/em&gt; or &lt;em&gt;&quot;how do I narrow this discriminated union without writing five type guards by hand.&quot;&lt;/em&gt; Quick, targeted, in-the-flow.&lt;/p&gt;
&lt;p&gt;The main friction across both surfaces was &lt;strong&gt;token usage&lt;/strong&gt;. Pasting the full triple for a sibling template — config schema, editor canvas, learner renderer — plus the registry, plus the type definitions, plus the helper utilities, adds up fast. I burned through context faster than I expected on the first template, then learned to trim ruthlessly: just the &lt;em&gt;one&lt;/em&gt; most-relevant sibling, just the types I'd actually reference, just the helper I was about to call. By the third template the prompts were leaner and better-targeted, and the responses got sharper too. The constraint forced better prompt discipline — a roundabout win.&lt;/p&gt;
&lt;p&gt;What Copilot did for me was speed up the typing. I still had to figure out what each template should look like, what to make configurable, what it should do on mobile. Those weren't decisions the tool could make for me. But the boilerplate moved faster.&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21356/ive-been-building-an-lms-for-a-year-finish-up-a-thon-made-me-actually-finish-it</guid>
<pubDate>Thu, 25 Jun 2026 09:42:50 +0000</pubDate>
</item>
<item>
<title>Simple Auth Service to a Distributed Authentication Platform with Kafka, Debezium, and Observability</title>
<link>https://coderlegion.com/20838/simple-auth-service-distributed-authentication-platform-kafka-debezium-observability</link>
<description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/challenges/github-2026-05-21&quot;&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-i-built-3&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;I built a Distributed Authentication System as a long-term learning project to explore real-world backend and distributed systems concepts through a familiar use case: user authentication.&lt;/p&gt;
&lt;p&gt;The project started as a simple authentication service with signup and login functionality. Over time, it evolved into a distributed architecture that incorporates event-driven communication, change data capture (CDC), observability, horizontal scaling, and performance testing.&lt;/p&gt;
&lt;p&gt;The current system consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PostgreSQL as the primary source of truth for user credentials&lt;/li&gt;
&lt;li&gt;Redis for refresh token storage and session management&lt;/li&gt;
&lt;li&gt;Kafka as the event streaming platform&lt;/li&gt;
&lt;li&gt;Debezium for Change Data Capture (CDC) from PostgreSQL&lt;/li&gt;
&lt;li&gt;MongoDB for materialized user profile documents&lt;/li&gt;
&lt;li&gt;Nginx for load balancing across multiple service instances&lt;/li&gt;
&lt;li&gt;Prometheus and Grafana for monitoring and observability&lt;/li&gt;
&lt;li&gt;k6 for load testing and performance analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a user signs up, the authentication service writes user data to PostgreSQL. Debezium captures the database change and publishes it to Kafka. A separate profile service consumes the event and creates a corresponding profile document in MongoDB. This allows services to communicate asynchronously while keeping the architecture loosely coupled.&lt;/p&gt;
&lt;p&gt;Beyond implementing features, the main goal of this project was to understand the trade-offs involved in building distributed systems. Throughout development I conducted load-testing experiments, measured replication lag, analyzed bottlenecks, and documented the architectural decisions that shaped the system.&lt;/p&gt;
&lt;p&gt;This project has become my personal distributed systems playground where I can experiment with new ideas, evaluate design decisions, and learn how real systems behave under load.&lt;/p&gt;
&lt;h3 id=&quot;demo-3&quot;&gt;Demo&lt;/h3&gt;
&lt;h5 id=&quot;github-repository&quot;&gt;GitHub Repository&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/c0d3l0v3r-HeHe/distributed-auth-system&quot;&gt;https://github.com/c0d3l0v3r-HeHe/distributed-auth-system&lt;/a&gt;&lt;/p&gt;
&lt;h5 id=&quot;signup-flow&quot;&gt;Signup Flow&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30edq7k4gtyzq4aa94en.png&quot; alt=&quot;Image showing the signup flow in the distributed system&quot;&gt;&lt;/p&gt;
&lt;h5 id=&quot;login-flow&quot;&gt;Login Flow&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nt91s2dpdcn63mw3sbyk.png&quot; alt=&quot;Login architectural diagram&quot;&gt;&lt;/p&gt;
&lt;p&gt;The repository contains additional architecture diagrams, performance experiments, load-testing results, observability metrics, and detailed documentation covering the design decisions and trade-offs explored throughout the project.&lt;/p&gt;
&lt;p&gt;Rather than reproducing all of those results here, I've kept this submission focused on the project's journey and evolution. If you're interested in the deeper technical details, bottleneck analysis, replication lag measurements, scaling experiments, or observability setup, you'll find them documented in the repository.&lt;/p&gt;
&lt;h3 id=&quot;the-comeback-story-3&quot;&gt;The Comeback Story&lt;/h3&gt;
&amp;lt;!-- Tell us where the project was before and what you changed, fixed, or added to finish it up. --&amp;gt;
&lt;p&gt;This project was not originally intended to be a standalone distributed authentication platform.&lt;/p&gt;
&lt;p&gt;In May, I started building it as the authentication backend for a larger job portal project. The initial goal was fairly straightforward: implement signup, login, token management, and the supporting infrastructure needed for user authentication.&lt;/p&gt;
&lt;p&gt;After building the core authentication service and setting up the initial infrastructure, I shifted my focus to other work and the project was left unfinished. While the foundation existed, many of the ideas I wanted to explore—distributed systems patterns, observability, scalability, and performance analysis—were still missing.&lt;/p&gt;
&lt;p&gt;A few weeks later, I came across the GitHub Finish-Up-A-Thon Challenge and decided to revisit the project instead of letting it remain another abandoned repository.&lt;/p&gt;
&lt;p&gt;Rather than simply cleaning up old code, I used the opportunity to significantly expand the project and turn it into a distributed systems playground.&lt;/p&gt;
&lt;p&gt;During the revival, I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added Redis-based refresh token management&lt;/li&gt;
&lt;li&gt;Implemented a CDC pipeline using PostgreSQL, Debezium, and Kafka&lt;/li&gt;
&lt;li&gt;Added a dedicated profile service backed by MongoDB&lt;/li&gt;
&lt;li&gt;Introduced Prometheus metrics and Grafana dashboards&lt;/li&gt;
&lt;li&gt;Added k6 load-testing infrastructure&lt;/li&gt;
&lt;li&gt;Scaled the authentication service horizontally behind Nginx&lt;/li&gt;
&lt;li&gt;Conducted multiple performance experiments and documented the results&lt;/li&gt;
&lt;li&gt;Created architecture diagrams and expanded the project documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the most valuable outcomes of revisiting the project was discovering bottlenecks that only became visible under load. While scaling the authentication service improved CPU utilization, load testing revealed that MongoDB and the CDC pipeline became the primary bottlenecks. Investigating these trade-offs taught me far more than simply building the original authentication service.&lt;/p&gt;
&lt;p&gt;By the end of the challenge, the project had evolved from an unfinished backend component into a fully documented distributed authentication system that I can continue using to explore distributed systems concepts, scalability patterns, and performance engineering.&lt;/p&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot-2&quot;&gt;My Experience with GitHub Copilot&lt;/h3&gt;
&amp;lt;!-- Explain how GitHub Copilot supported your process. --&amp;gt;
&lt;p&gt;GitHub Copilot acted as an implementation and exploration partner throughout the revival of this project.&lt;/p&gt;
&lt;p&gt;For many components, I first designed the architecture and wrote the interfaces, function signatures, and high-level implementation plan. I then used Copilot to generate boilerplate code, suggest implementations, and accelerate repetitive development tasks.&lt;/p&gt;
&lt;p&gt;Copilot was particularly useful for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generating service scaffolding and repetitive CRUD logic&lt;/li&gt;
&lt;li&gt;Assisting with Docker Compose configuration&lt;/li&gt;
&lt;li&gt;Helping configure Prometheus metrics collection&lt;/li&gt;
&lt;li&gt;Suggesting Kafka consumer and producer implementations&lt;/li&gt;
&lt;li&gt;Writing integration and infrastructure tests&lt;/li&gt;
&lt;li&gt;Explaining configuration options for Debezium and Kafka Connect&lt;/li&gt;
&lt;li&gt;Speeding up refactoring and cleanup work&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One workflow I found especially effective was defining the architecture and API contracts myself, leaving implementation placeholders, and then using Copilot to generate an initial implementation. This allowed me to focus more on system design decisions and less on repetitive coding.&lt;/p&gt;
&lt;p&gt;I also used Copilot while setting up and validating the distributed architecture. It helped me troubleshoot configuration issues, understand service interactions, and quickly iterate on infrastructure changes during development.&lt;/p&gt;
&lt;p&gt;The biggest benefit wasn't code generation itself—it was the ability to move from an idea to an experiment much faster. Since this project is intended as a distributed systems learning playground, that rapid feedback loop allowed me to spend more time investigating architectural trade-offs, performance bottlenecks, and scalability challenges.&lt;/p&gt;
&lt;h3 id=&quot;feedback-welcome&quot;&gt;Feedback Welcome&lt;/h3&gt;
&lt;p&gt;This project started as a learning exercise and has evolved into my personal distributed systems playground.&lt;/p&gt;
&lt;p&gt;If you're an experienced backend or distributed systems engineer and happen to read this submission, I'd genuinely appreciate any feedback on the architecture, design decisions, bottlenecks, or trade-offs discussed throughout the project.&lt;/p&gt;
&lt;p&gt;Some areas I'm currently thinking about include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improving the CDC pipeline under higher load&lt;/li&gt;
&lt;li&gt;Reducing replication lag and read amplification&lt;/li&gt;
&lt;li&gt;Better approaches to profile materialization&lt;/li&gt;
&lt;li&gt;Scaling strategies beyond the current setup&lt;/li&gt;
&lt;li&gt;Observability improvements and production-readiness considerations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Constructive criticism, alternative approaches, and architecture suggestions are all welcome. One of the main goals of this project is to learn from engineers who have solved these problems in real systems.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ftryfxkkmystybk64m8.png&quot; alt=&quot;Cover Image&quot;&gt;&lt;/p&gt;
&amp;lt;!-- Don't forget to add a cover image (if you want). --&amp;gt;
&amp;lt;!-- I am a Solo Contributor --&amp;gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20838/simple-auth-service-distributed-authentication-platform-kafka-debezium-observability</guid>
<pubDate>Wed, 17 Jun 2026 18:53:34 +0000</pubDate>
</item>
<item>
<title>Reviving a 12K+ Star Abandoned Library: toastr-next v3 </title>
<link>https://coderlegion.com/20562/reviving-a-12k-star-abandoned-library-toastr-next-v3</link>
<description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/challenges/github-2026-05-21&quot;&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-i-built-4&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;toastr-next v3&lt;/strong&gt; a complete revival of &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/CodeSeven/toastr&quot;&gt;CodeSeven/toastr&lt;/a&gt;, one of the most-starred abandoned JavaScript libraries on GitHub with &lt;strong&gt;12,000+ stars&lt;/strong&gt; and no meaningful commits since 2016.&lt;/p&gt;
&lt;p&gt;toastr was the go-to notification library for millions of developers. But time wasn't kind to it. it required jQuery, had no TypeScript, no dark mode, no accessibility, and its Gulp + LESS build chain was completely dead. It was a library everyone knew but nobody could use in a modern project without guilt.&lt;/p&gt;
&lt;p&gt;I picked it up, stripped it to the bones, and rebuilt it from scratch for 2026.&lt;/p&gt;
&lt;p&gt;From this :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// 2015 — drag in jQuery just to show a toast
&amp;lt;script src=&quot;jquery.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;  // 30 KB
&amp;lt;script src=&quot;toastr.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;  // 5 KB
// Total: ~87 KB of dead weight

toastr.success('Hello!');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To this :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// 2026 — zero dependencies, full TypeScript, ~4 KB gzipped
import { toastr } from 'toastr-next';

const toast = toastr.success('Hello!');
await toast.dismissed; // Promise API!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;~4 KB&lt;/strong&gt; gzipped. No jQuery. No bloat. Just toasts. &lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;demo-4&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fh6xdq3g1i3agb8356zr.png&quot; alt=&quot;toastr-next live demo — dark mode&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Dark mode — toasts firing with progress bar&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yv9u2zb7vszq0j3nmfys.png&quot; alt=&quot;toastr-next live demo — light mode&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Light mode — same demo, toggled with the ☀️ button&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://toastr-next.vercel.app/&quot;&gt;toastr-next.vercel.app/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;npm:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/toastr-next&quot;&gt;npmjs.com/package/toastr-next&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Divyesh-5981/toastr-next&quot;&gt;github.com/Divyesh-5981/toastr-next&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-comeback-story-4&quot;&gt;The Comeback Story&lt;/h3&gt;
&lt;h4 id=&quot;where-it-was&quot;&gt;Where it was&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3w8skipe3pmn92xhkwk.png&quot; alt=&quot;Original CodeSeven/toastr repo — last commit 8 years ago&quot;&gt;&lt;br&gt;
&lt;em&gt;The original repo — abandoned since 2016, 12k stars, zero recent activity&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Problem              &lt;/th&gt;&lt;th&gt;Detail&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;jQuery required      &lt;/td&gt;&lt;td&gt;~87 KB overhead just to show a notification&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No TypeScript        &lt;/td&gt;&lt;td&gt;No types, no IntelliSense, no safety&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No dark mode         &lt;/td&gt;&lt;td&gt;Hard-coded colors, no CSS variables&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No accessibility     &lt;/td&gt;&lt;td&gt;Screen readers couldn't detect toasts at all&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;JS-driven animations &lt;/td&gt;&lt;td&gt;Layout thrash, janky on low-end devices&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No Promise API       &lt;/td&gt;&lt;td&gt;No way to await a toast dismissal&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No keyboard support  &lt;/td&gt;&lt;td&gt;Couldn't dismiss with Escape key&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dead build toolchain &lt;/td&gt;&lt;td&gt;Gulp + LESS, completely unmaintained since 2016&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;No ESM support       &lt;/td&gt;&lt;td&gt;Global UMD only, no tree-shaking&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;what-i-built-5&quot;&gt;What I built&lt;/h4&gt;
&lt;h5 id=&quot;typescript-rewrite-zero-dependencies-&quot;&gt;TypeScript Rewrite (Zero Dependencies)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No jQuery:&lt;/strong&gt; 100% strict TypeScript with full JSDoc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Universal Formats:&lt;/strong&gt; Ships in ESM, CJS, UMD, and IIFE (works from Vite to raw &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags).&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;css-first-theming&quot;&gt;CSS-First Theming&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Modern CSS:&lt;/strong&gt; Uses CSS variables instead of inline JS styles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Themes &amp;amp; Motion:&lt;/strong&gt; Auto dark mode (&lt;code&gt;prefers-color-scheme&lt;/code&gt;), manual toggle (&lt;code&gt;localStorage&lt;/code&gt;), and &lt;code&gt;prefers-reduced-motion&lt;/code&gt; support.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Layouts:&lt;/strong&gt; 4 pure CSS animation presets (Fade, Slide, Bounce, Flip) and native RTL support.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;-accessibility-built-to-wcag-2-1-aa-practices-&quot;&gt;♿ Accessibility (built to WCAG 2.1 AA practices)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Screen Readers:&lt;/strong&gt; Dynamic ARIA live regions &lt;code&gt;role=&quot;alert&quot;&lt;/code&gt; (assertive) for errors/warnings and &lt;code&gt;role=&quot;status&quot;&lt;/code&gt; (polite) for success/info, with &lt;code&gt;aria-atomic&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keyboard Navigation:&lt;/strong&gt; Toasts are focusable and sit in the natural tab order; pressing Escape while a toast is focused dismisses it, and auto-dismiss pauses while a toast holds focus.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;modern-api&quot;&gt;Modern API&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Async &amp;amp; Events:&lt;/strong&gt; Promises (&lt;code&gt;await toast.dismissed&lt;/code&gt;) and lifecycle event subscriptions (&lt;code&gt;toastr.subscribe&lt;/code&gt;, which returns an unsubscribe function).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DX &amp;amp; Security:&lt;/strong&gt; Automatic CSS injection (no separate stylesheet import), native React wrapper (&lt;code&gt;useToastr&lt;/code&gt;), and built-in XSS protection.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;production-ready&quot;&gt;Production Ready&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lightweight:&lt;/strong&gt; ~4 KB gzipped (~2 KB JS + ~2 KB CSS) vs the original ~87 KB jQuery version.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Live:&lt;/strong&gt; Available on npm as &lt;code&gt;toastr-next&lt;/code&gt; with a live Vercel demo.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;size-comparison&quot;&gt;Size comparison&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;toastr v2 (old)      &lt;/th&gt;&lt;th&gt;toastr-next v3&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Total size     &lt;/td&gt;&lt;td&gt;~87 KB (with jQuery) &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~4 KB gzipped&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dependencies   &lt;/td&gt;&lt;td&gt;jQuery required      &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Zero&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;TypeScript     &lt;/td&gt;&lt;td&gt;✕                    &lt;/td&gt;&lt;td&gt;✓&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dark mode      &lt;/td&gt;&lt;td&gt;✕                    &lt;/td&gt;&lt;td&gt;✓ Auto + manual toggle&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Accessibility  &lt;/td&gt;&lt;td&gt;✕                    &lt;/td&gt;&lt;td&gt;✓ WCAG 2.1 AA practices&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Promise API    &lt;/td&gt;&lt;td&gt;✕                    &lt;/td&gt;&lt;td&gt;✓&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;React support  &lt;/td&gt;&lt;td&gt;Third-party only     &lt;/td&gt;&lt;td&gt;✓ Built-in&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Animations     &lt;/td&gt;&lt;td&gt;JS (jQuery)          &lt;/td&gt;&lt;td&gt;✓ CSS @keyframes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Bundle formats &lt;/td&gt;&lt;td&gt;Global UMD only      &lt;/td&gt;&lt;td&gt;✓ ESM, CJS, UMD, IIFE&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CSS import     &lt;/td&gt;&lt;td&gt;Required             &lt;/td&gt;&lt;td&gt;✓ Auto-injected&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot-3&quot;&gt;My Experience with GitHub Copilot&lt;/h3&gt;
&lt;p&gt;I used GitHub Copilot as a pair programmer throughout the entire revival not for autocomplete, but as a genuine collaborator at every architectural decision.&lt;/p&gt;
&lt;p&gt;Here's exactly how it helped, step by step.&lt;/p&gt;
&lt;h4 id=&quot;1-deciding-what-to-keep&quot;&gt;1. Deciding what to keep&lt;/h4&gt;
&lt;p&gt;Before writing a single line, I needed to know what was worth saving from 14 years of jQuery-tangled code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;&quot;Here is the original toastr v2 source. What's worth keeping
for backward compatibility and what should be completely rewritten?&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot identified the API surface &lt;code&gt;success&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt; — as the only thing worth preserving. Everything underneath needed to go. This became the guiding rule for the entire rewrite.&lt;/p&gt;
&lt;h4 id=&quot;2-typescript-interfaces&quot;&gt;2. TypeScript interfaces&lt;/h4&gt;
&lt;p&gt;With the API surface locked, I needed a clean type system built around it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;&quot;Design TypeScript interfaces for ToastrOptions, ToastResponse,
and ToastEvent. I want every toast call to return a Promise
that resolves when the toast is dismissed.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot designed all three interfaces. The standout was the &lt;code&gt;dismissed: Promise&amp;lt;void&amp;gt;&lt;/code&gt; pattern on &lt;code&gt;ToastResponse&lt;/code&gt; making every toast awaitable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const { dismissed } = toastr.success('Changes saved');
await dismissed;
// runs after the toast closes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I didn't ask for this pattern specifically. Copilot suggested it unprompted, and it became the most-loved feature of the rewrite.&lt;/p&gt;
&lt;h4 id=&quot;3-theming-system&quot;&gt;3. Theming system&lt;/h4&gt;
&lt;p&gt;I wanted dark mode to work automatically &lt;em&gt;and&lt;/em&gt; be manually overridable without JavaScript touching the CSS side.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;&quot;I need a CSS theming system that supports auto dark mode via
prefers-color-scheme AND manual override via a data-theme attribute
on the html element. No JavaScript should be needed for the CSS side.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot proposed the &lt;code&gt;[data-theme]&lt;/code&gt; + &lt;code&gt;@media (prefers-color-scheme)&lt;/code&gt; layering pattern. The media query handles auto mode; a single attribute flip handles manual override. No JS. No flicker. Just CSS doing its job.&lt;/p&gt;
&lt;h4 id=&quot;4-accessibility&quot;&gt;4. Accessibility&lt;/h4&gt;
&lt;p&gt;I had applied &lt;code&gt;role=&quot;alert&quot;&lt;/code&gt; to all four toast types, assuming it was correct. I asked Copilot to review before shipping.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;&quot;What ARIA roles and aria-live values should toast notifications use
to be WCAG 2.1 AA compliant? Should all toasts use the same role?&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot flagged that &lt;code&gt;role=&quot;alert&quot;&lt;/code&gt; is &lt;em&gt;assertive&lt;/em&gt; it interrupts a screen reader mid-sentence. That's right for errors and warnings, but jarring for a success message. The fix:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Type &lt;/th&gt;&lt;th&gt;Role &lt;/th&gt;&lt;th&gt;Behaviour&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;error&lt;/code&gt;, &lt;code&gt;warning&lt;/code&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;role=&quot;alert&quot;&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Interrupts immediately&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;success&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;role=&quot;status&quot;&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Waits for a pause&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;A subtle WCAG 2.1 distinction I would have shipped wrong without this review.&lt;/p&gt;
&lt;h4 id=&quot;5-css-auto-injection&quot;&gt;5. CSS auto-injection&lt;/h4&gt;
&lt;p&gt;Early users kept asking why they had to import the CSS separately. That broke the drop-in promise. I needed the stylesheet bundled &lt;em&gt;inside&lt;/em&gt; the JS, self-injecting on import.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;&quot;Write a Vite generateBundle plugin that reads the extracted CSS asset
and injects it into every JS chunk as a self-executing style injector.
Add a guard so it only injects once even if the module is imported
multiple times, and make it safe to run during SSR.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot drafted the &lt;code&gt;generateBundle&lt;/code&gt; plugin — CSS-to-string conversion plus a self-executing injector that appends a &lt;code&gt;&amp;lt;style id=&quot;__toastr_next_css__&quot;&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;. The guard checks &lt;code&gt;document.getElementById(...)&lt;/code&gt; so it only injects once even if multiple bundles (core + React) load on the same page, and it bails out when &lt;code&gt;document&lt;/code&gt; is undefined (SSR-safe). I later refactored it into one shared plugin reused across the core, IIFE, and React builds.&lt;/p&gt;
&lt;p&gt;This was the most technically complex Copilot collaboration in the project and the one that impressed me most.&lt;/p&gt;
&lt;h4 id=&quot;6-demo-page&quot;&gt;6. Demo page&lt;/h4&gt;
&lt;p&gt;The final piece was a demo site that actually showed off everything that changed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prompt:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&quot;Build a demo page for toastr-next with a quick fire section,
a live playground with dropdowns for type/animation/position,
an animation showcase, a before/after comparison, and a light/dark
theme toggle that persists to localStorage.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Copilot built the full &lt;code&gt;index.html&lt;/code&gt; iteratively playground, comparison table, custom ARIA dropdown, and the light/dark toggle with &lt;code&gt;localStorage&lt;/code&gt; persistence. I directed; it executed. The entire demo came together in an afternoon.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;what-i-took-away&quot;&gt;What I took away&lt;/h4&gt;
&lt;p&gt;Copilot wasn't writing boilerplate it was catching real bugs, proposing patterns I hadn't considered, and solving problems I didn't know how to start. The &lt;code&gt;dismissed: Promise&amp;lt;void&amp;gt;&lt;/code&gt; feature, the WCAG role distinction, and the CSS-injection plugin were all things I got from Copilot that I wouldn't have shipped on my own.&lt;/p&gt;
&lt;p&gt;That's the kind of collaboration this challenge is designed to reward.&lt;/p&gt;
&lt;p&gt;After the main rewrite, I ran the entire codebase through GitHub Copilot to audit for hidden anti-patterns and code smells. It helped me spot subtle optimizations and edge cases, allowing me to refine the code into a truly polished, production-grade architecture.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfi8sclgg45w1ivnc7a4.png&quot; alt=&quot;audit for hidden anti-patterns and code smells.&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The audit - for hidden anti-patterns and code smells.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wv1wdgt15t8nec1g2dg0.png&quot; alt=&quot;fixes for anti-patterns and code smells&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Improvements - for hidden anti-patterns and code smells.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Working with Copilot felt less like using a tool and more like having a senior developer who knew every API, caught every edge case, and never got tired. The revival that would have taken weeks took days.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h3&gt;
&lt;p&gt;Huge respect to the original authors — &lt;a rel=&quot;nofollow&quot; href=&quot;https://twitter.com/John_Papa&quot;&gt;John Papa&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://twitter.com/ferrell_tim&quot;&gt;Tim Ferrell&lt;/a&gt;, and &lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://twitter.com/hfjallemark&quot;&gt;Hans Fjällemark&lt;/a&gt; - who built something so good that developers were still reaching for it a decade later. &lt;/p&gt;
&lt;p&gt;This revival exists because their original work was worth finishing ❤️&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20562/reviving-a-12k-star-abandoned-library-toastr-next-v3</guid>
<pubDate>Sun, 14 Jun 2026 03:30:38 +0000</pubDate>
</item>
</channel>
</rss>