Skip to main content

Command Palette

Search for a command to run...

The App I Wish Existed When I Was Knocking on Doors

How frustration with a broken system became a full-stack platform — and what building it actually taught me.

Updated
9 min read
The App I Wish Existed When I Was Knocking on Doors
R

A deep thinker, builder, and learner sharing my journey through tech and thought. This blog is my space to reflect, explore hard questions, and document growth — not just in skills, but in purpose. It’s for anyone who feels lost, curious, or stuck — a reminder that your voice, ideas, and path still matter. Here, I write before ideas become products and code becomes real — the foundation behind Ryom and the questions that drive it.

"The most important thing Computer Science can do is take the burden of a painful, familiar problem — and make it so that the next generation never has to feel it."

The Part Nobody Talks About

Let me paint you a picture. You're a Computer Science student. Third year. You need an industrial attachment — a placement, an internship, real work experience. The university requires it. Your future needs it.

So you do what everyone does.

You Google companies in your city. You find a name. You look for an email. There is no email. You look for a website. There is no website. You check LinkedIn — nothing. You ask around. Someone gives you a physical address.

So you go there. In person. Knock on the door. Ask for the manager. Wait. And then someone comes out and says: "We don't take interns."

You thank them. Walk back out. And start the whole cycle again.

I've been that student. And what burned me — what really burned me — wasn't just the rejection. It was the system. A completely broken, invisible, exhausting system that nobody had bothered to fix. Not because it couldn't be fixed. But because somewhere along the way, people got comfortable with the problem.

And that's the thing that icks me the most. Comfortability with pain that could be solved.

So I built IAMS. Not as an assignment. Not to get a grade. Because I was tired of the wound — and I finally had the tools to close it.


What Is IAMS?

IAMS — the Industrial Attachment Management System — is a full-stack web platform built for the University of Botswana's Computer Science Department. It handles the complete industrial attachment lifecycle, end to end.

Students find organisations. Organisations post vacancies. An algorithm matches them intelligently. Coordinators manage placements. Supervisors log visits. Students submit weekly digital logbooks. Reports get generated — with UB letterhead, signature blocks, timestamps — the full thing.

What used to be paper forms, door-knocking, and unanswered emails is now one unified platform.

Here's the contrast that says it all:

The Old Way IAMS
Paper logbooks easily lost Digital weekly logbooks with auto save
Manual matching by coordinator Heuristic scoring engine with 100-point algorithm
No document enforcement Allocation blocked if CV or transcript is missing
Supervisor visits uncoordinated Two-phase visit scheduling with email notification
No audit trail Every approval stamped with name, title, and timestamp
Physical PDF reports Legally-formatted document with UB letterhead

It's live. It works. And yes — I built it.


How It Actually Works

  • The Matching Engine This was the part I was most proud of getting right. Every student gets scored against every organisation using a 100-point heuristic:

  • Skills match — 50 points. How many of the organisation's required skills does the student actually have?

  • GPA — 30 points. Weighted proportionally, only applied if the student meets the minimum threshold.

  • Location preference — 20 points. Flat bonus if the student's preferred location matches the organisation.

But here's where it gets interesting. The engine is slot-aware. Each organisation has a finite number of vacancies. The highest-scoring students claim slots first. If you get displaced because a slot fills up — the system automatically redirects you to your next-best match. No manual intervention. No coordinator headaches.

And there's an allocation guard built in: if an organisation requires a CV or transcript and you haven't uploaded it, the match engine flags it. The coordinator literally cannot allocate you until the documents are there. No more chasing students for paperwork at the last minute.

This runs as a Supabase Edge Function — because for one student being scored against multiple organisations simultaneously, you need that computation to happen somewhere fast and isolated. It does.

The Logbook System

Students submit weekly logbooks with three structured templates depending on their week type. Every submission has a status tag — pending, approved, flagged — so there's always clear feedback. No more "did my supervisor even see this?" This was actually me applying HCI principles deliberately. Don Norman's seven stages of action, gulf of evaluation, gulf of execution — I wanted the interface to communicate state at every moment so users always know where they stand.

The PDF Generation

Coordinators can generate legally-formatted placement reports — complete with the UB letterhead and signature blocks. This was one of those features that when it finally rendered correctly, I just sat back and stared at the screen for a moment.


The Real Story: What Building This Actually Felt Like

I'm going to be honest with you the way I always am on this blog.

I started March 18th, 2026. I finished May 3rd. Today is May 10th and I'm still polishing.

That's roughly seven weeks of building something that had to actually work — not just demo well, but actually work.

Before I started, I genuinely thought this would be straightforward. Create a table for organisations. Build the interface. Done. I had no real plan — just excitement and a blank editor.

What I didn't understand yet was that the most important part of building software is the invisible part. The architecture. The design. The requirements. The planning that happens before a single line of code gets written.

I learned that the hard way.

The code — the React, the SQL, the TypeScript — that's just the glue. It's what holds everything together. But it is not the most important thing. Getting the design right before you touch the keyboard — that is what separates a project that works from one that collapses under its own weight.

The Supabase Wake-Up Call

React has always been my comfort zone. Supabase was a foreigner.

I understood SQL. But Supabase's policies and Row Level Security — that was a whole new world. And because I hadn't properly understood the requirements before diving into the interface, I ended up going back and forth constantly. The coordinator couldn't read organisation data. The student couldn't see their own placement. I was rewriting policies in circles.

It became a mess. And the mess was entirely self-inflicted — by skipping the thinking and jumping straight to the doing.

Cache Busting at 2am

When you update a profile picture in Supabase, the URL stored in the bucket doesn't change. Only the file does. So the browser, seeing the same URL it cached before, just keeps showing the old photo.

The fix? I started appending a timestamp to the URL. Supabase ignores parameters that don't make sense to it — but the browser sees a new URL and forces a refresh. Problem solved. Inelegant. Effective. Real.

That's software engineering. Nobody tells you about the 2am cache busting.

The Vercel Trap

Everything worked perfectly on localhost. Then I deployed to Vercel and every route returned "Page Not Found."

Vercel, by default, looks for index.html when a request comes in. React Router DOM bypasses that entirely. The fix was a vercel.json file with a single redirect rule — but I spent hours thinking my React code was broken before I figured that out.

It taught me something I won't forget: debugging is not just reading your code. You have to read your environment. Your dependencies. Your deployment context. The world your code lives in matters as much as the code itself.

The Tailwind Version That Broke Everything

A version of Tailwind CSS I was using wasn't compatible with React Router DOM. That's it. That was the bug. But I spent a significant chunk of time convinced something was deeply wrong with my React setup — running in circles — before I finally looked at my dependencies and found the conflict.

Look beyond the code. Always.

What I Want You to Take From This This blog is for anyone who's innovative. Anyone who wants to be inspired to build whatever they want. Computer Science doesn't have a target audience. It's for anyone with the desire to listen, observe, and turn those observations into solutions.

Because that's what Computer Science is actually for.

Not to be impressive. Not to land a job title. But to look at a painful, familiar problem — one that real people experience every day — and decide: I have the tools. I don't have to accept this.

The next generation of CS students at University of Botswana shouldn't have to knock on doors with no email addresses. They shouldn't have to navigate a paper-based system while studying technology. That's not just inefficient — it's a contradiction.

IAMS exists because I got tired of the problem. And I finally had enough to do something about it.

What's Next

The app is live. The system works. But adoption is the next mountain.

A platform without users is just a very good idea sitting in the cloud. What I want — more than anything — is for students to actually use it. For organisations to register. For coordinators to run the matching engine and watch it work.

If you're a student at University of Botswana, or know someone who is — share this. If you're an organisation open to taking CS interns — the portal is open.

And if you're a developer reading this from anywhere in Africa: build the thing that hurts you. Build the app you needed but didn't have. Build it even when the stack is unfamiliar, even when the policies don't make sense yet, even when Vercel breaks everything on the first deploy.

Build it because the wound is real. And code, when it's applied with purpose, is one of the most powerful ways to close it.


Built with React, Tailwind CSS, TypeScript, and Supabase. Started March 18th. Finished (mostly) May 10th. Still adding finishing touches — because that's just how it goes.


Try IAMS