<?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: Mohamad Obeid</title>
    <description>The latest articles on DEV Community by Mohamad Obeid (@mohamadobeid9).</description>
    <link>https://dev.to/mohamadobeid9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3881224%2F456aa506-5c81-4fa7-b3e9-21d26fa44e89.jpeg</url>
      <title>DEV Community: Mohamad Obeid</title>
      <link>https://dev.to/mohamadobeid9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohamadobeid9"/>
    <language>en</language>
    <item>
      <title>From Supabase-only to production Go: Month 1 of rebuilding Info Links</title>
      <dc:creator>Mohamad Obeid</dc:creator>
      <pubDate>Sat, 20 Jun 2026 06:29:27 +0000</pubDate>
      <link>https://dev.to/mohamadobeid9/from-supabase-only-to-production-go-month-1-of-rebuilding-info-links-3a4p</link>
      <guid>https://dev.to/mohamadobeid9/from-supabase-only-to-production-go-month-1-of-rebuilding-info-links-3a4p</guid>
      <description>&lt;p&gt;Two months ago I wrote about building &lt;a href="https://infolinks.app/" rel="noopener noreferrer"&gt;Info Links&lt;/a&gt; — a free course resource platform for students at Le CNAM Lebanon. Telegram channel, 300+ students, 50+ courses, no paywall, ever.&lt;/p&gt;

&lt;p&gt;At the end of that post I said the next step was learning Go and rebuilding the backend properly. Not a tutorial todo app. A real REST API behind a live product people actually use.&lt;/p&gt;

&lt;p&gt;That was the plan. This is what Month 1 actually looked like.&lt;/p&gt;




&lt;h2&gt;
  
  
  The promise vs. the starting point
&lt;/h2&gt;

&lt;p&gt;When I wrote that first post, the "backend" was mostly Supabase. The frontend talked to Postgres through Supabase's client. GitHub Pages served static files. It worked — but it wasn't a backend I could defend in an interview.&lt;/p&gt;

&lt;p&gt;My Month 1 goal wasn't "learn Go syntax." It was: &lt;strong&gt;make Info Links survive a senior engineer reading the repo for 15 minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real layered architecture (not everything in handlers)&lt;/li&gt;
&lt;li&gt;Tests you can run without a database&lt;/li&gt;
&lt;li&gt;Observability, health checks, CI&lt;/li&gt;
&lt;li&gt;Documentation that explains &lt;em&gt;why&lt;/em&gt;, not just &lt;em&gt;what&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I gave myself one month. Here's the scorecard.&lt;/p&gt;




&lt;h2&gt;
  
  
  What shipped
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. A real Go backend (not a rewrite for the sake of it)
&lt;/h3&gt;

&lt;p&gt;The frontend stayed vanilla HTML/CSS/JS — same UX students already knew. What changed is everything behind it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go REST API&lt;/strong&gt; serving &lt;code&gt;/api/*&lt;/code&gt; endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same Postgres database&lt;/strong&gt; (Supabase-hosted), but the Go server owns the API layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT admin auth&lt;/strong&gt; through the backend instead of direct client-side Supabase calls for admin operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static file serving&lt;/strong&gt; from the Go binary — one deploy, one service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repo went from ~6 backend files with SQL mixed into handlers to &lt;strong&gt;100+ Go files&lt;/strong&gt; across &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;service&lt;/code&gt;, &lt;code&gt;repository&lt;/code&gt;, &lt;code&gt;middleware&lt;/code&gt;, &lt;code&gt;seo&lt;/code&gt;, and more.&lt;/p&gt;

&lt;p&gt;That sounds like a lot. It is. But it's organized now — not accidental complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Architecture I can explain out loud
&lt;/h3&gt;

&lt;p&gt;The biggest single win wasn't a feature. It was structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; global &lt;code&gt;DB&lt;/code&gt; singleton, SQL in handlers, hard to test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP request → router → handler → service → repository → Postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal/repository&lt;/code&gt;&lt;/strong&gt; — SQL lives here, behind interfaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal/service&lt;/code&gt;&lt;/strong&gt; — validation and business rules, no HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;internal/api&lt;/code&gt;&lt;/strong&gt; — thin handlers: decode JSON, call service, return status codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dependency injection from &lt;code&gt;main&lt;/code&gt;. No globals. Handlers mockable. This was the refactor I was most afraid of. It's also the one I'm most glad I did.&lt;/p&gt;

&lt;p&gt;I wrote &lt;strong&gt;6 Architecture Decision Records&lt;/strong&gt; (&lt;code&gt;docs/adr/&lt;/code&gt;) explaining choices like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why &lt;code&gt;net/http&lt;/code&gt; instead of Gin/Fiber&lt;/li&gt;
&lt;li&gt;Why Supabase stays for Postgres hosting&lt;/li&gt;
&lt;li&gt;Why Render instead of GitHub Pages for the full stack&lt;/li&gt;
&lt;li&gt;Why server-side SEO pages exist alongside the SPA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an interviewer asks "why didn't you use X?" — I have an answer that isn't "I didn't know about X."&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Production hygiene (the unglamorous stuff that matters)
&lt;/h3&gt;

&lt;p&gt;This is the part that doesn't screenshot well but shows up in every backend job description:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Thing&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Structured logging (&lt;code&gt;slog&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/healthz&lt;/code&gt; + &lt;code&gt;/readyz&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus &lt;code&gt;/metrics&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Request ID + panic recovery middleware&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate limiting (&lt;code&gt;golang.org/x/time/rate&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI: &lt;code&gt;go test -race&lt;/code&gt;, golangci-lint, govulncheck&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-stage Dockerfile + docker-compose&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Load testing with k6 + written results&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The load test was genuinely fun. I hammered &lt;code&gt;/api/content&lt;/code&gt; at 4,400 req/s from a single IP — the rate limiter returned 429 in under 1ms without touching the database. Zero crashes. That's interview gold: &lt;em&gt;"I load-tested my own service and documented what broke."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Test coverage on &lt;code&gt;internal/api&lt;/code&gt; (~93%) and &lt;code&gt;internal/service&lt;/code&gt; (~96%) — table-driven tests, mocked repositories, the works.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. SEO without abandoning the SPA
&lt;/h3&gt;

&lt;p&gt;Students still get the fast client-side app. Crawlers get server-rendered HTML for course pages, sitemap, and robots.txt. Best of both worlds, one Go server.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Learnings docs (the "AI-pair, human-owned" habit)
&lt;/h3&gt;

&lt;p&gt;For every major package I wrote a &lt;code&gt;docs/learnings/*.md&lt;/code&gt; file — my own words explaining request flow, middleware order, error mapping, SEO rendering. Not for GitHub stars. So I can whiteboard my own code without an agent open beside me.&lt;/p&gt;

&lt;p&gt;That habit was the hardest part of Month 1. More on that below.&lt;/p&gt;




&lt;h2&gt;
  
  
  What broke (and what I learned from it)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The "product looks bigger than the code" problem
&lt;/h3&gt;

&lt;p&gt;My first post made Info Links sound like a big platform. And it &lt;em&gt;is&lt;/em&gt; — for students. But an interviewer can read your backend in one sitting. Month 1 wasn't about adding features. It was about making the engineering match the story.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI-pair coding is fine. Not understanding your own code is not.
&lt;/h3&gt;

&lt;p&gt;I used AI heavily — same as the first build. The difference this month: I added a rule. &lt;strong&gt;45 minutes daily, no AI.&lt;/strong&gt; Refactor something. Explain a file out loud. If I can't, I don't ship it yet.&lt;/p&gt;

&lt;p&gt;Some nights that 45 minutes felt pointless. Then I'd hit an interview-style question in my own head — &lt;em&gt;"why is the service layer separate from the repository?"&lt;/em&gt; — and realize I actually knew the answer. That matters more than any LeetCode streak right now.&lt;/p&gt;




&lt;h2&gt;
  
  
  By the numbers (Month 1)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Supabase-direct → Go REST API on Render&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go files:&lt;/strong&gt; ~6 → 100+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ADRs:&lt;/strong&gt; 0 → 6&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test coverage:&lt;/strong&gt; ~0% → ~93% (api) / ~96% (service)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware stack:&lt;/strong&gt; none → logging, metrics, rate limit, auth, recovery, request ID&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load test doc:&lt;/strong&gt; yes, with real k6 numbers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog posts planned:&lt;/strong&gt; 2 → this is #2 (closing Month 1)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The product still serves the same community. Same free ethos. Same &lt;a href="https://t.me/Info_Links9" rel="noopener noreferrer"&gt;Telegram channel&lt;/a&gt;. Same &lt;a href="https://github.com/MohamadObeid9/Info_Links" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. The engineering finally caught up to the story I was telling.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Month 1 honestly
&lt;/h2&gt;

&lt;p&gt;Did I hit every checkbox on my roadmap? Almost. The important ones — architecture, tests, observability, CI, ADRs, load testing, learnings docs — yes.&lt;/p&gt;

&lt;p&gt;What's still ahead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Month 2:&lt;/strong&gt; a companion Go service (link health checker worker — goroutines, context, errgroup)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSS contributions&lt;/strong&gt; to popular Go repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job applications&lt;/strong&gt; with this repo as the centerpiece&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mock interviews&lt;/strong&gt; and the uncomfortable parts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Month 1 was about making Info Links &lt;strong&gt;interview-grade&lt;/strong&gt;. I think it is now — or at least, it's the first version of my backend I'd be willing to walk a senior engineer through without sweating.&lt;/p&gt;

&lt;p&gt;Month 2 is about proving it wasn't a one-time effort.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to find it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Live site:&lt;/strong&gt; &lt;a href="https://infolinks.app/" rel="noopener noreferrer"&gt;infolinks.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/MohamadObeid9/Info_Links" rel="noopener noreferrer"&gt;github.com/MohamadObeid9/Info_Links&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📢 &lt;strong&gt;Telegram:&lt;/strong&gt; &lt;a href="https://t.me/Info_Links9" rel="noopener noreferrer"&gt;@Info_Links9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📖 &lt;strong&gt;Part 1:&lt;/strong&gt; &lt;a href="https://dev.to/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645"&gt;I built a free course resource platform for my university&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you rebuilt a project specifically to learn a language — not as a tutorial clone, but as something real people use — what was the hardest part? Architecture? Testing? Deployment? Convincing yourself you actually understood what you shipped?&lt;/p&gt;

&lt;p&gt;For me it was the gap between &lt;em&gt;"it works"&lt;/em&gt; and &lt;em&gt;"I can explain every layer without looking at the screen."&lt;/em&gt; Month 1 was about closing that gap.&lt;/p&gt;

&lt;p&gt;The best projects still start with a real problem. Mine started in a group chat full of students asking for the same link every semester. Two months and one Go backend later — still the same problem, better engineering.&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>career</category>
      <category>showdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Mohamad Obeid</dc:creator>
      <pubDate>Thu, 16 Apr 2026 15:36:17 +0000</pubDate>
      <link>https://dev.to/mohamadobeid9/-olf</link>
      <guid>https://dev.to/mohamadobeid9/-olf</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645" class="crayons-story__hidden-navigation-link"&gt;I built a free course resource platform for my university — here's the real story&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&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="/mohamadobeid9" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3881224%2F456aa506-5c81-4fa7-b3e9-21d26fa44e89.jpeg" alt="mohamadobeid9 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mohamadobeid9" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Mohamad Obeid
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Mohamad Obeid
                
              
              &lt;div id="story-author-preview-content-3508883" 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="/mohamadobeid9" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3881224%2F456aa506-5c81-4fa7-b3e9-21d26fa44e89.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Mohamad Obeid&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/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 16&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/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645" id="article-link-3508883"&gt;
          I built a free course resource platform for my university — here's the real story
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/showdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;showdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&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/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645" 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/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/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.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;7&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/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&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;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&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>I built a free course resource platform for my university — here's the real story</title>
      <dc:creator>Mohamad Obeid</dc:creator>
      <pubDate>Thu, 16 Apr 2026 07:24:41 +0000</pubDate>
      <link>https://dev.to/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645</link>
      <guid>https://dev.to/mohamadobeid9/i-built-a-free-course-resource-platform-for-my-university-heres-the-real-story-1645</guid>
      <description>&lt;p&gt;I'm a CS student in my third year at Le CNAM Lebanon. A few months ago I noticed something frustrating — students were constantly asking each other in random group chats: &lt;em&gt;"does anyone have the link for X course materials?"&lt;/em&gt; Every semester, the same chaos. No central place. No organization. Just noise.&lt;/p&gt;

&lt;p&gt;So in February 2025 I started a Telegram channel called &lt;strong&gt;Info Links&lt;/strong&gt; — just me, manually organizing course links, Telegram groups, Google Drive folders, and Google Classroom links by program, year, and semester. No code. No fancy tools. Just organization and consistency.&lt;/p&gt;

&lt;p&gt;What started as one person with a simple idea grew to &lt;strong&gt;300+ students in under a year.&lt;/strong&gt; Posts were hitting &lt;strong&gt;3000+ views.&lt;/strong&gt; I realized the problem was real — and bigger than I thought.&lt;/p&gt;

&lt;p&gt;For months I dreamed about turning it into a proper website. A couple days ago, on April 11th, I finally did.&lt;/p&gt;




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

&lt;p&gt;Info Links is now a full platform covering &lt;strong&gt;50+ courses&lt;/strong&gt; — from foundational subjects all the way through License and partial Master's degrees in Computer Science.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For students:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Smart search by course name or code&lt;/li&gt;
&lt;li&gt;📋 Courses organized by program, year, and semester&lt;/li&gt;
&lt;li&gt;🔗 Multiple resource types per course — Google Drive, Google Classroom, Telegram, and external links&lt;/li&gt;
&lt;li&gt;🏷️ Optional vs mandatory course tagging&lt;/li&gt;
&lt;li&gt;🌓 Light/Dark mode, fully responsive&lt;/li&gt;
&lt;li&gt;💬 Submit new resources or report broken links directly from the site&lt;/li&gt;
&lt;li&gt;⭐ Feedback System — Rate the platform and provide suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For me as admin:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full course management — add, edit, delete, organize&lt;/li&gt;
&lt;li&gt;Analytics dashboard — daily visitors, 7/30/90-day and all-time stats&lt;/li&gt;
&lt;li&gt;Contribution review — approve or reject user-submitted resources&lt;/li&gt;
&lt;li&gt;Report management — handle broken link reports&lt;/li&gt;
&lt;li&gt;JSON export for full data backup&lt;/li&gt;
&lt;li&gt;Feedback Management — View and manage user feedback and ratings&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The tech
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Pure HTML5, CSS3, Vanilla JavaScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend/Database:&lt;/strong&gt; Supabase (PostgreSQL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; GitHub Pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built with:&lt;/strong&gt; Claude AI as my pair programmer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No framework. No build step. One focused project that does exactly what it needs to do.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why free, always
&lt;/h2&gt;

&lt;p&gt;Someone asked me why I don't charge for access — I could easily charge for the content, honestly.&lt;/p&gt;

&lt;p&gt;My answer: if I was a broke student looking for my course materials, I wouldn't pay. So I won't charge. Simple as that.&lt;/p&gt;

&lt;p&gt;This project exists because of the community. It belongs to the community.&lt;/p&gt;




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

&lt;p&gt;I'm learning Go and plan to rebuild the backend as a proper REST API with PostgreSQL. The frontend stays the same — the backend becomes my real Go learning project, with an actual use case instead of another tutorial todo app.&lt;/p&gt;

&lt;p&gt;The goal isn't just to learn Go. It's to eventually open this up so any university can self-host their own version of Info Links for their students.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to find it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🌐 &lt;strong&gt;Live site:&lt;/strong&gt; &lt;a href="https://infolinks.app" rel="noopener noreferrer"&gt;infolinks.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/MohamadObeid9/Info_Links" rel="noopener noreferrer"&gt;github.com/MohamadObeid9/Info_Links&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📢 &lt;strong&gt;Telegram channel:&lt;/strong&gt; &lt;a href="https://t.me/Info_Links9" rel="noopener noreferrer"&gt;@Info_Links9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;What's the most useful thing someone built for their university or local community that you've seen? Looking for inspiration on where to take this next.&lt;/p&gt;

&lt;p&gt;The best projects start with a real problem. This one started with students asking the same question over and over in a group chat. Sometimes that's all it takes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Update (Jun 2026): Month 1 of the Go rebuild is done — &lt;a href="https://dev.to/mohamadobeid9/from-supabase-only-to-production-go-month-1-of-rebuilding-info-links-3a4p"&gt;read what shipped&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
