Building a Halal Food Directory for WLU MSA
A short case study on building a searchable halal food directory for Laurier students, from messy spreadsheet data to a maintained community resource.
Maruf Hossain4 min read
As part of the WLU MSA tech team, I helped build the Halal Food Directory: a searchable list of halal food options on and around campus.
The problem was simple. Students kept asking the same questions: where can I eat, what kind of food is there, and what does the halal verification actually mean? The answers existed, but they were spread across conversations, spreadsheets, Google Maps, and old recommendations.
We wanted one place that was easy to check on a phone between classes.
What We Built
The directory organizes restaurants by cuisine and halal status. Each listing includes the restaurant name, location, short description, website, Google Maps link, category, and slaughter method.
The important part was clarity. Some students are comfortable with machine-slaughtered meat, some only eat hand-slaughtered, and some just need to know when an item is not halal. We did not want a vague "halal-friendly" label to hide those differences.
My Role
I worked on the data model, filtering experience, and the connection between the frontend, CMS, and database.
Data Modeling in Supabase
The first version of the data came from a spreadsheet. It was useful, but not structured enough for an app. I had to think through which fields should be required, which values needed constraints, and how the data would be updated later by non-developers.
Supabase provided the PostgreSQL database. Payload sat above it as the content-management layer, so editors could work with a form while the application still benefited from a structured relational model. A simplified version of the schema looked like this:
CREATE TYPE slaughter_method AS ENUM ('hand', 'machine', 'not_halal');
CREATE TABLE restaurants (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
description TEXT,
category TEXT NOT NULL,
slaughter_method slaughter_method NOT NULL,
location TEXT,
website_url TEXT,
maps_url TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);Using an enum for slaughter_method made the UI more reliable. Instead of handling slightly different spreadsheet values like "hand slaughtered", "hand-slaughter", or "hand", the app could depend on one controlled set of options.
Building the Filter UI
The filtering needed to be fast and obvious. Most people using this page are not browsing for fun; they are trying to decide where to eat.
The main filters were cuisine and halal status. I kept the interaction simple so users could quickly narrow the list without reading every card.
Connecting Payload CMS
We used Payload CMS so the directory would not depend on a developer every time a restaurant changed hours, moved, or needed a correction.
That introduced the most interesting part of the project: keeping the CMS, database, and frontend aligned. The frontend needed clean data, the CMS needed to be easy for team members to manage, and the database needed enough structure to prevent bad entries from slipping through.
The same options and validation rules had to mean the same thing in all three layers. Otherwise a value accepted by the CMS could still break a filter or produce a misleading label on the public page.
What Was Messy
The hardest part was not the UI. It was turning community knowledge into reliable data.
Restaurant information changes. Verification details can be sensitive. A small wording mistake can make the directory less useful. That forced me to think less like I was building a demo and more like I was building a resource people might actually trust.
Maintenance Is Part of the Product
A CMS makes an entry editable; it does not make the entry correct. Someone still needs to own the review process, decide what evidence supports a label, and revisit records when a restaurant changes suppliers or policies.
That changed how I thought about the data model. Fields such as the source of a claim, the date it was checked, and an internal review note can matter as much as the restaurant name. Even if every field is not shown publicly, it gives the team a trail to follow when someone reports a correction.
The interface also needs honest language. A directory can report the information the team has verified, but it should not pretend that a database row is a permanent guarantee. Trust comes from making updates and uncertainty manageable, not from removing nuance.

What I Learned
- Data modeling matters more when real people depend on the labels.
- A CMS is only helpful if the content model is simple enough for the team maintaining it.
- Filters should match the user's decision-making process, not just the database fields.
- Community projects need boring reliability more than flashy features.
- Data ownership and review workflows are product features, even when users never see them.
Check It Out
This was a small project technically, but a meaningful one. It reminded me that good software does not always need to be complicated. Sometimes the win is making useful information easier to trust.
— Maruf