← All projects

hiroshi-grill/

A reservation web app for Hiroshi Master Grill Samgyupsal, an unli samgyupsal restaurant in General Trias, Cavite. My first paying client. Two faces on one codebase: a public site anyone can browse and book from, and a staff portal behind a login.

role
Sole developer. Schema, policies, API, interface
stack
Next.js 16 · TypeScript · Supabase · Tailwind v4 · Zod
tests
132, plus 43 policy tests
status
Live on Vercel, not yet taking real bookings
The Hiroshi Master Grill public site, showing the unli sets and a reserve button.
The public site. No login, because asking a hungry stranger to make an account loses the booking.
The problem

Friday's booking lives in a Messenger thread

An unli samgyupsal place takes bookings over Facebook Messenger, which means the reservation for Friday evening lives in a chat thread somewhere and the staff on shift cannot see it. The restaurant needed a page a guest could book from, and a screen the people working that night could actually open.

The build

A public site, a staff portal, one schema run twice

The staff portal sign-in screen, and the public site on a phone.
The staff portal, and the same site on a phone. Staff accounts are created by the owner: there is no sign-up to attack.

What the owner singled out: the staff portal, where the staff and the owner each sign in to their own account. The site is live, but the restaurant has not started taking bookings through it yet.

Security

Where the strict answer costs something

This is the project where the security work went in at the start rather than at the end, and where several decisions came with a cost worth stating.

Dates are judged in Asia/Manila, not in the server's UTC. Otherwise a 9pm booking made in Manila gets rejected for being yesterday.
Honest notes

Placeholders, and what the tests actually cover

Every business detail on the site is still a placeholder, and they live in two files so they can be corrected in one place. That matters more than it sounds: the address, phone and hours are also fed to Google as structured data, and publishing wrong ones there is worse than publishing none. The repo has a go-live document listing every placeholder field and what each one feeds, so none of them get missed.

The 132 tests run with no server and no database. The 43 policy tests need a scratch Postgres, which CI now provides as a service container, so both suites run on every push that touches this project. The policy tests are the ones worth having there: a policy loosened by a later migration would not fail any of the others.