DEV Community

Cover image for From a 3-Day Deadline Disaster to a Real Product: Reviving My First Full-Stack Project
OLALEKAN OGUNDIMU
OLALEKAN OGUNDIMU

Posted on

From a 3-Day Deadline Disaster to a Real Product: Reviving My First Full-Stack Project

GitHub “Finish-Up-A-Thon” Challenge Submission

This is a submission for the GitHub Finish-Up-A-Thon Challenge


What I Built

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

But this isn't just a project. This is the project that started everything for me.

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

And then I abandoned it.

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

The GitHub Finish-Up-A-Thon gave me the reason to come back and actually finish it.


Demo

🔗 New repository: https://github.com/sam-the-champ/CA-app
🔗 Old repository: https://github.com/sam-the-champ/course-allocation-app

What the revived app does:

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

🔗 Check it Live: https://course-allocation-app2.vercel.app/


The Comeback Story

Let me show you exactly what I came back to.

The Before: Three Commits and a Lot of Problems

Here is the entire commit history of the original project:

Before commit log showing only 3 commits:

Three commits. Built in a rush. Pushed and abandoned.

This was the old admin dashboard:

Old admin dashboard with green sidebar and yellow stat numbers on green cards

And the old Add Lecturer page:

Old Add Lecturer form with basic white card on grey background, green sidebar

And the old lecturer dashboard — the page every lecturer was supposed to log into and see their courses:

Old lecturer dashboard showing Welcome Mr. Adedayo with empty course table and basic green theme

The UI was functional enough to demonstrate. But under the hood, it was a completely different story.

Here is the single most embarrassing line in the old codebase:

Code showing hardcoded Codespace URL: fetch('https://literate-space-pancake-v9545xq5v5qh6qrq-5000.app.github.dev/api/admin/get-data')

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

This was not the only problem. Here is the full list of what I found when I came back:

Architecture:

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

Security:

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

Broken logic:

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

This is what a first project built under deadline pressure looks like. It's not pretty. But it's honest.


The After: A Real Application

This is the new lecturer dashboard:

New lecturer dashboard showing Lecturer's profile card with navy/gold design, clean typography, department shown in gold, email and ID displayed

And the new admin dashboard:
admin dashboard showing the new layout

Same page. Same purpose. Completely rebuilt.

Here is everything that changed:

✅ Fully separated frontend (/frontend — React + Vite) and backend (/backend — Express) into independent deployable projects

✅ All business logic moved into proper controllers — authController, adminController, lecturerController — routes are now thin URL-to-function maps

✅ Fixed Admin.js model — it now correctly registers with mongoose.model('Admin', adminSchema) instead of exporting undefined

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

✅ Real JWT authentication for both admin and lecturer login, with protect, adminOnly, and lecturerOnly middleware applied to every protected route

Allocation promoted to a proper first-class MongoDB collection with a compound unique index — no more embedded arrays

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

✅ React frontend with React Router v6, AuthContext for shared authentication state, and <Navigate replace /> on logout so the back button cannot re-enter a protected route

✅ Unified field naming — phoneNumber consistent across model, controller, and frontend

✅ Global error handler middleware — consistent error response shape across every endpoint

✅ Backend deployed on Render, frontend deployed on Vercel

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


My Experience with GitHub Copilot

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

Moment 1: The Codebase Audit

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

Moment 2: The Vercel Seed Problem

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

I described the exact problem to Copilot:

Copilot conversation showing the question about running npm run seed on Vercel since it has no shell environment, with Copilot's structured response about the problem and solutions

Copilot read my repository structure, confirmed it had found my seed.js file, explained exactly why the problem was happening, and then gave me two concrete solutions — convert the seed into a one-time API endpoint, or switch to a platform with shell access like Render.

Copilot showing Option 1: Create a Seed API Endpoint with actual code for seed.ts router

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

Day-to-Day Usage

Beyond those two moments, Copilot was my constant pair programmer throughout the rebuild:

VS Code Codespaces showing Copilot chat panel open alongside LoginPage.jsx, with the new project file structure visible — api, context, admin, lecturer folders all properly separated

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

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


What This Project Means

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

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

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

That is what finishing things does.


Built with Node.js, Express, MongoDB, React, Vite, and GitHub Copilot.
Frontend: Vercel | Backend: Vercel

Top comments (3)

Collapse
 
ogundimuemmanuel profile image
Ogundimu Emmanuel oluseyi

Lfg 🔥🔥

Collapse
 
olagraphics_ee1c75ba57d35 profile image
OlaGraphics

This is massive👍🏻

Collapse
 
opeyemi_e679ada1906d22f1d profile image
Opeyemi

This is great 🔥