Jiwoo Shim

Blog

I got tired of collecting 100 passports over KakaoTalk, so I built a website

August 11, 2026

nextjssupabaseclaude-codevolunteer

Hong Kong's delegation at the 106th National Sports Festival, Busan.
Hong Kong's delegation at the 106th National Sports Festival, Busan.

Every year, the Korean Sports Association in Hong Kong (KSAHK) sends a delegation to the National Sports Festival in Korea. This year: a 96-person delegation. Athletes across seven sports (football, bowling, tennis, kumdo, golf, squash, table tennis), plus team officials and observers. I'm the association's secretary general, which is a volunteer title that mostly means: I do the paperwork.

Here is what the paperwork actually looked like. For every participant, the Korean Sport & Olympic Committee needs a passport scan, a Hong Kong ID, an ID photo, a resident registration number, and, depending on the person, an entry-exit certificate and flight tickets. None of this arrives at once. It trickles in for a couple of weeks. A passport photo lands in one KakaoTalk room, someone's HKID comes by email, a third person sends their documents to another director, and in between, questions: is this photo okay? I sent it last week, did you get it?

Then you sit down at night, open each photo, squint at it, and type what you see into a spreadsheet. About a hundred times, across four or five document types each. The deadline crew was two or three of us, and deadline week meant consecutive late nights. Also typos, the kind you find at the worst possible moment, because a form going to a national sports body is not a form you want typos in.

At some point I stopped thinking of this as a paperwork problem and started thinking of it as a systems problem.

The fix wasn't software first. It was org design.

The real issue was that every document flowed through the same small bottleneck, the president and me and sometimes one more director, and every question did too. So before writing any code, I redrew the roles:

  • Machines do what machines are good at: collecting files, checking them instantly, filling official templates, counting who's missing what.
  • People do what only people can do: taking a decent photo of their own passport, and deciding "our team's roster is final."
  • The bottleneck (us) stops being a human inbox and becomes the people who handle exceptions.

Then I built a small web service around that split.

What participants see

One link, dropped into each team's KakaoTalk room. It opens the participant's own page. No app install, no account creation. Our delegation runs from people in their twenties to people in their sixties and beyond, and whatever the age, "please download this app" is where you lose a good number of them.

Their page shows two lists: what's needed now, and what can wait. Documents they already handed to their team captain show up as done. The site meets people where the process actually is, instead of pretending everyone starts from zero.

The participant's own page: "needed now" versus "can wait." Shot on a demo account.
The participant's own page: "needed now" versus "can wait." Shot on a demo account.

Uploading is three steps: a short guide, the camera, a confirmation. The moment a photo is taken, it's checked for brightness and blur, because the single most common failure mode is a dark, tilted passport photo taken on a dinner table, discovered two weeks later when nobody remembers taking it.

The upload flow: guide, shoot, confirm, with instant quality checks.
The upload flow: guide, shoot, confirm, with instant quality checks.

What the organizing team sees

A dashboard: who has submitted what, sliced by team and by role. Sport captains get their own view and a button that formally declares "my team's list is final," with a record of who declared it and when. That one button ended a whole genre of message: "wait, is the tennis roster actually final or not?"

The whole delegation's status on one screen.
The whole delegation's status on one screen.

And then my favorite part. The committee requires submissions in its official Excel templates: specific dropdowns, print settings, formulas. The site doesn't re-create those files; it fills the official templates directly, dropdowns and formulas intact, for all 96 people, from one button. The thing that used to be an all-nighter is now a download.

Official templates, filled and ready. The all-nighter is now a button.
Official templates, filled and ready. The all-nighter is now a button.

In the previous years, the document close meant two or three of us and consecutive late nights. This year it was two of us, the president and me, and it took us a couple of hours. I didn't measure the hours saved and I'm not going to invent a figure, so the honest version is just that: several late nights became an evening.

How it was built

I'll be honest about the process: I vibe-coded this with Claude Code. The stack is deliberately boring: Next.js on Vercel, Supabase behind it, photos going straight from the phone to storage without passing through a server. Claude wrote most of the code. Every decision about what to build, what to refuse, and where the fences go was mine. On this project, writing the code was the fast part; working out what it should do wasn't.

The build took evenings and weekends, which would not have been remotely possible two years ago. A small volunteer org getting custom internal software used to be a fantasy. It isn't anymore.

The part I have to be careful writing about

This system holds passports and IDs, which is the most sensitive data most people own. So: every participant gave individual consent for collection and use. Sensitive fields are encrypted at rest, with keys kept outside the database. Access is role-scoped, so a sport captain sees their own team rather than the whole delegation, and every view is logged. Backups run daily, and I've actually tested a restore, because a backup you've never restored is a hope, not a backup.

And that's as specific as this post is going to get. Describing the exact mechanisms in public would mostly be useful to the wrong audience. If you're building something similar and want to compare notes, my email inbox is open.

The part all the paperwork is actually for.
The part all the paperwork is actually for.

What's next

The roster and document phase is done, so the next builds are already underway:

  • A dispatch board for festival week: taxis, rental cars, and buses for a delegation moving between venues, with fair load-balancing across volunteer drivers.
  • Receipts: upload, categorize, reconcile.
  • A support agent participants can just talk to in a messenger, one that answers the questions that used to land in my KakaoTalk at 11pm. I'm planning to give it bounded permission to fix small bugs in the site itself, inside a harness that keeps it on rails, and have it ping me when something needs a human. Building the harness is the interesting part; I've come to believe the harness is the product.

The goal: by next year's festival, everything that can be self-serve is self-serve, end to end. I want the document close to be one click.

Credits

This project exists because President Han Seung-hee (한승희) and Advisor & Former President Shin Yong-hoon (신용훈) supported it from the start, and because ninety-six people trusted a link in a group chat. Thank you.

The people this was built for.
The people this was built for.

← All writing