MiaGo is a campus and municipality based food delivery platform that connects customers, vendors, and freelance riders through a structured ordering and dispatch system.
Why we built it
Around the municipality of Miagao, Iloilo, food ordering is usually handled through Messenger chats, Facebook posts, and direct coordination between customers, vendors, and riders.
Since food delivery apps like UberEats and Grab Food are not available in local areas like Miagao, we built our own.
MiaGo was built to turn this informal system into a structured job based delivery system where orders become dispatchable tasks for riders instead of informal requests.
How it turned out
Users and their roles
The system is split into three roles:
- Customers create orders and track status
- Riders browse and accept open delivery jobs
- Vendors act as pickup points and manage menu items
Each role has a separate workflow but shares the same underlying order system.
Stores and their items
Vendors manage stores and items through a simple catalog system:
- Create and update store profiles
- Manage item availability
- Control pricing and menu visibility
Customers browse stores and items directly before placing orders.
Orders
Orders are treated as structured jobs that move through a clear lifecycle from draft to delivered.
This removes ambiguity in coordination between customers and riders.
Riders
Riders operate through a job board where they can view open orders, accept delivery jobs, and update pickup and delivery status.
Once accepted, an order is locked to a single rider to prevent conflicts.
How we built it
System architecture
MiaGo uses a modular monolith style backend with a 3 tier structure:
- Frontend built with React and Vite
- Backend built with Express in a controller service repository pattern
- PostgreSQL database accessed through Slonik with dbmate migrations
Turborepo is used to manage shared packages and keep the system consistent.
Modules
- Auth module for login and registration
- Users module for role based profiles
- Stores module for vendor store and item management
- Orders module for cart, order creation, and lifecycle tracking
- Deliveries module for job browsing and delivery updates
Data model approach
Key entities include users, stores, store items, orders, and order items.
The design focuses on:
- clear separation between order state and delivery state
- snapshot pricing at order time
- strict role based access control
- controlled state transitions to avoid inconsistent updates
Tech stack
| Layer | Stack |
|---|---|
| Frontend | React, Vite, Tailwind CSS, shadcn/ui |
| Backend | Express, TypeScript |
| Database | PostgreSQL, Slonik |
| Validation | Zod |
| Monorepo | Turborepo |
| DevOps | Docker, GitHub Actions |
| Deployment | Vercel, Render, Neon |
What I learned
First time using Express for a full backend. It was more manual compared to frameworks I used before, but it gave me a clearer understanding of request flow, controllers, and services.
No ORM in this project. I worked directly with SQL using Postgres and enforced type safety using Slonik together with Zod on raw queries. It made database work more explicit and forced me to be careful with data shape and validation.
I also learned how to deal with a more complicated RBAC system. The app has three roles: customer, rider, and vendor. Handling this was not just business logic but also UI complexity. Every feature had to account for what each role can and cannot do, and keeping those boundaries consistent across the system was harder than expected.