Taewon Kwon

OLLE

Payroll for a 20-person NYC restaurant, built on the owner’s own spreadsheet. Then a validation sprint that told me not to scale it.

Role
Sole builder: discovery, product, engineering
Type
Paid client engagement
When
2026 [TK: start month] – ongoing
Status
In weekly use · productization paused Sep 2026
Stack
Google Apps Script, Google Sheets
Scale
~$30K payroll and tips a week · 20 staff

A restaurant owner had already tried and dropped a payroll product. I built her a tool that runs on her own Google Sheet and stops exactly where her judgment starts. Then I tested whether it could be a business, and decided on the evidence that it shouldn’t be, yet.

~$30K
payroll and tips processed every week
20
employees on the roster, hourly and salaried
15 → 1
cold calls in the first validation batch, and the one interested lead they produced

The problem

The owner had tried Toast Payroll and dropped it. Her CPA already handled tax filing, so the product added cost without adding value, and it couldn’t bend to her rules for tips, overtime and the other ways she pays people.

Underneath the feature gaps was trust. She didn’t want her staff’s wage data sitting with another vendor.

So the job wasn’t “payroll software.” It was: turn a week of POS data into a gross-pay figure per person, her way, without anyone else holding the numbers.

Train of thought

How my read of the problem changed, in order. The filled markers are the moments the plan changed.

  1. Start [TK: month]I assumed the gap was software. She had left Toast, so she needed a better payroll product.
  2. First conversationsWhat she actually needed was her own rules and her own data. Tax was already solved by her CPA. That moved the tool onto the spreadsheet she already trusted, rather than into a new system.
  3. Running real pay periodsI sat in on pay runs instead of designing from a spec. Most of the features came from watching what went wrong on a real week, such as salaried staff, shifts over 10 hours and names in the POS export that didn’t match the roster.
  4. The mismatchPast periods didn’t match her old summary sheet. The quick fix was to adjust the math until it agreed. Instead I traced the raw CSVs: the app was right, and the gaps were her deliberate adjustments, like zeroing tips for trainees. Those are judgment calls, so they stayed hers.
  5. Could others use this?A competitor already offered generic CSV import. That narrowed the idea: the wedge would be fitting each restaurant’s own exports and house rules, not importing files.
  6. Before the sprintI set the stop rule first: continue only with 2–3 signed clients from a one-month NYC sprint.
  7. Discovery & first calls15 cold calls to restaurants from a community job board produced one interested lead. The discovery meeting also removed the CPA-side value I had assumed.
  8. Sep 2026I paused productization before committing the month. The evidence didn’t show enough value to justify it.

What I built

A web app layered on her existing Google Sheets: a dashboard, a payroll run that takes her POS export as a CSV, a publish step, and an employee roster. Gross pay per employee lands in her Sheet, which she sends to her CPA.

Where the math stops. The tool owns the repeatable part. Everything that depends on a person’s situation stays with the owner.

Features that came from real pay runs

  • Salaried staff: fixed gross, hours still tracked, and shifts over 10 hours flagged.
  • Undo last publish and safe re-runs, so a mistake on payday is recoverable, not scary.
  • Unknown-name detection in raw POS exports, so a new hire or a typo can’t silently drop someone’s hours.
Image: the payroll run screenScreenshot with names and amounts blurred [TK]
The payroll run. [TK: one line on what the owner sees, e.g. the import, the flags, and the publish step.]
Image: unknown-name warningClose crop of the flag on a real export, anonymized [TK]
Caught before publish. A name in the POS export that isn’t on the roster stops the run instead of disappearing.

Key decisions

  1. Stopped the math at gross pay.Each employee’s withholding arrangement was too specific to automate reliably, so net pay, cash bonuses and tips stay with the owner.
  2. Said no to a per-employee tax-rate field.It would have looked automated while hiding judgment calls.
  3. Investigated the mismatch instead of patching it.Tracing the raw CSVs showed the app was right and the gaps were deliberate. They stayed her call rather than becoming hard-coded rules.
  4. Kept the data in her account.The Sheet lives in her own Google account, so no payroll vendor holds her staff’s wages. That answered the trust problem directly.

Could it be a product?

One restaurant using it every week is a signal, not a market. Before spending a month finding out, I designed the smallest version that could be sold and decided in advance what would make me stop.

  • Positioning: narrowed after finding a competitor already offered generic CSV import. The wedge became customization around each restaurant’s own exports and house rules.
  • Architecture: all payroll math runs in the browser and writes to the restaurant’s own Sheet, so the server never holds wage data.
  • Pricing: cut from three tiers to one flat implementation fee.
  • Stop rule: continue only with 2–3 signed clients from a one-month NYC sprint.
  1. Step 1Kill rule set2–3 signed clients from a one-month sprint, or stop
  2. Step 2DiscoveryWith the original client: the CPA-side value I’d assumed wasn’t there
  3. Step 315 cold callsRestaurants sourced from a community job board: one interested lead
  4. Sep 2026PausedBefore committing the month
Validation, in order. The stop decision came from the rule I set before the first call.

Outcome

The tool runs the client’s weekly payroll. I paused productization in September 2026, before committing a month to the sprint, because the evidence didn’t show enough value to justify it.

[TK: anything the owner has said about it since, or what you’d need to see to restart it.]

What it shows: scoping to what can be done reliably, discovery that changed my assumptions, and stopping on evidence rather than momentum.