Portfolio / System Ops / lalafun-pos

One month to build.
A day a week back.

I run a fried chicken restaurant. I was losing a full day every week to admin — re-writing expenses into a ledger, exporting to Excel, computing payroll for 13 staff by hand. Four weeks of build time later, that's two hours.

ClientLalaFun (own restaurant)
ScopePOS · Inventory · Expenses · Payroll
Team13 staff · ~200 tx/day
Timeline4 weeks · 2026
What we built

A single app that runs the whole shop.

One install on every shift phone and the owner's device. Six modules, one database, one login. No add-ons, no plugins, no separate spreadsheet anywhere in the flow. Built specifically for a single-outlet Indonesian F&B with cash-drawer reality — not a generic SaaS bent into shape.

Module 01

Point of Sale

Two-tap checkout optimized for fried chicken combos. Splits cash, QRIS, bank transfer and online orders (GoFood / GrabFood) into their own drawers. Prints a thermal receipt to the kitchen and a customer slip in one action.

ReceiptsDrawer splitOnline
Module 02

Inventory & Stock

Every sale auto-deducts from stock. Low-stock alerts before the shop runs out mid-service. One-screen count-in for supplier deliveries — scan, quantity, price, done.

Auto-deductAlertsCount-in
Module 03

Expense tracking

Every rupiah out of the drawer gets logged at the POS the moment it's paid. Tagged by category, tied to a cash source, photo of the receipt attached. Replaces the hardcover ledger and the monthly Excel export in one swipe.

CategorizedPhoto evidence
Module 04

Attendance

Selfie clock-in with GPS geofence so no one punches in from home. Three-shift aware (morning / mid / evening). Late, early-leave and absences roll straight into the payroll calculation.

SelfieGPS fenceShifts
Module 05

Payroll

Base salary plus attendance-bonus math, plus fines and advances — all computed live as the month runs. Hit "close month" on the 28th and the payout sheet is done. Print, count cash, hand out.

Live calcFines & advances
Module 06

Owner reports

One dashboard, owner's phone. Daily sales vs. yesterday, month-to-date expenses by category, payroll liability, cash-on-hand. Drill into any number to see the raw transactions behind it.

Live KPIsDrill-down
● The problem

Admin ate every Sunday.

Every day I re-wrote the day's expenses into a hardcover ledger — ice, parking, cleaning supplies, the gas bill. Once a month I spent a full day exporting everything into Excel as a backup. None of it talked to each other.

If I wanted to know what I'd spent on packaging last month, the only answer was: flip the pages.

"I could work the shop or I could work the paperwork. Never both." — owner, LalaFun
Expense Book 14 Feb '26
Ice (3 packs)45,000
Ojek parking5,000
Cooking oil120,000
Cooking oil (5L)165,000
Dish soap28,000
LPG gas 12kg180,000
Wheat flour95,000
Packaging box M240,000
Electricity bill680,000
Manual 8 hrs / week
● The fix

Everything, in one app, as it happens.

Every expense — a pack of ice, the electricity bill, a parking slip — gets logged on the POS the moment it's paid, tagged to cash drawer or safe. The ledger is gone. The monthly Excel backup runs itself.

A manager dashboard rolls it all up: today's sales by payment method, month-to-date expenses by category, targets vs. actuals. I open the app, I see the shop.

9:41 ●●●● ◐ ▮▮▮
Dashboard
Saturday · 14 Feb
L
Today's Sales
Rp 4,248,500
+18% vs. yesterday · 208 orders
Expenses
Rp 380K
Monthly Target
76%
Sales · last 7 days
Raw ingredients Rp 1.8M
Operations Rp 420K
Packaging Rp 310K
POS
Orders
Stock
Data
● Second problem

Payroll was two hours of spreadsheet math.

Thirteen staff, three shifts a day, attendance tracked on paper slips. End of month I'd cross-check who showed up when, calculate the attendance-bonus percentage by hand, and plug every line into a spreadsheet.

Two hours if nothing went wrong. Longer when a slip went missing or someone disputed a shift.

Ayu
Morning
07:0215:00
Budi
Mid
10:45
Citra
Evening
leave?
Dimas
Morning
06:5815:04
Eka
Evening
14:5022:10
Fajar
Mid
11:00
Gita
Morninglate
07:4515:00
● The fix

Clock in with your face. Payroll runs itself.

Staff clock in from the POS terminal with a selfie and GPS check — you can't fake it from home, and the slip can't go missing. Shift, attendance %, bonus and penalties compute as the month runs.

When payday comes, I open the payroll tab, read the number, count the cash. Ten minutes, done.

9:41 ●●●● ◐ ▮▮▮
Payroll
Feb 2026 · 13 staff
Ready
A
Ayu Pramesti
26 days · 100%
Rp 3.240K
B
Budi Santoso
25 days · 96%
Rp 3.105K
C
Citra Wulandari
24 days · 92%
Rp 2.980K
D
Dimas Pratama
26 days · 100%
Rp 3.240K
E
Eka Saputra
22 days · 85%
Rp 2.785K
Total payroll · Feb
Rp 38.420K
Print
POS
Orders
Stock
Team
● Third problem

We ran out of chicken on a Sunday night.

Stock lived on a whiteboard in the kitchen. Whoever remembered to cross things off, did. Whoever didn't, didn't. Twice I walked in to find we were out of packaging boxes with a full queue of online orders waiting.

There was no early warning, no consumption rate, no reorder point. Just a marker and the hope that someone was paying attention.

STOCK — Sun
Chicken?? kg Flour2 sacks Oil 5L3 Oil 5L1? Box Mlow Box Lok Sambal jar~15 Rice6 kg LPG2 LPG1
← who crossed?
ran out 21:40 → lost ~18 orders
● The fix

Stock deducts itself. It warns you before it runs out.

Every sale automatically subtracts the right amount from the right SKU — the recipe map is set up once, then it just works. When stock drops under the reorder point for that day's sales velocity, the owner gets a push notification that morning.

Deliveries get counted in on the same app — scan, quantity, supplier, photo of the receipt. The whiteboard is now empty. The kitchen likes it that way.

9:41 ●●●● ◐ ▮▮▮
Stock
48 SKUs · 2 alerts
Low
!
Chicken thigh
4.2 kg · reorder now
1.8 days
!
Packaging box M
28 pcs · reorder now
0.6 days
~
Cooking oil 5L
2 jugs · watch
3.2 days
Wheat flour
24 kg · ok
6.1 days
LPG 12kg
3 tanks · ok
9.0 days
Inventory value
Rp 12.8M
Count in
POS
Orders
Stock
Team
Before & after

What a Sunday used to look like.

Sunday was supposed to be my day. Instead it was catch-up day — the one day I could sit down and untangle the week. Here's what changed.

Before Sunday · 9h 30m
  • 0:00startCollect the week's expense receipts from the ops drawer, the staff room, my wallet.
  • 0:30+30 minRe-write every slip into the hardcover ledger by hand.
  • 3:00+3 hrCross-check cash drawer against the day-end reports — hunt for a 15k gap for 40 minutes.
  • 4:30+4 hr 30Open Excel. Retype the ledger into the monthly sheet. Fix a formula someone broke.
  • 6:30+6 hr 30Collect the week's attendance slips from the shift manager's clipboard.
  • 8:00+8 hrPhone a staff member to confirm a Tuesday shift. Voice note back: "I forgot to sign."
  • 9:30+9 hr 30Halfway through payroll math. Realize I missed a late-penalty.
9h 30m
After Sunday · 20 min
  • 0:00startOpen the app on the couch. Glance at yesterday's drawer reconciliation — it matches.
  • 0:05+5 minSkim the expense log. Two photos I need to re-categorize. Tap, tap, done.
  • 0:10+10 minCheck the stock alert from earlier — chicken reordered by the shift manager Friday.
  • 0:15+15 minPeek at the payroll preview. On track. Closes itself on the 28th.
  • 0:20+20 minPut the phone down. Go somewhere.
20m · 3.5% of before
How it came together

Four weeks, end to end.

01

Week 1 — design

Mapped every admin task I was doing by hand. Cut anything that wasn't load-bearing for a single-outlet shop — no recipes, no ingredient trees, no customer CRM. Just the things I actually re-typed every week.

02

Weeks 2–3 — build

React Native + Expo on the phone, PHP + MySQL on the back end. Offline-first sync from day one — the kitchen doesn't stop when the wi-fi blinks. Audit log on every mutation so nothing disappears silently.

03

Week 4 — rollout

Trained 13 staff across morning, middle and evening shifts. Written SOP in Bahasa. Ledger and spreadsheets retired the week after. Ship over-the-air updates whenever something pinches.

Outcome · real numbers from the live system

Eight months in, here's what the database says.

Every number below is pulled from the production database — not a pitch-deck estimate. The counters start when you scroll here.

0 hrs
Admin time saved
6 hrs/week × 52 weeks — a full month of owner time back
Rp 0M
Payroll auto-calculated
across 8 months · zero disputes, zero manual re-runs
0
Low-stock alerts fired
caught before the shop ran out — 0 missed-order incidents since launch
0%
Drawer reconciliation match
240 day-ends · drawer variance under Rp 5K on 99.4% of them
0min
Median payroll close time
down from 1 hour to 14 minutes · tap close, print, count cash
Under the hood

Built for a shop, not for a pitch deck.

The tech is deliberately unglamorous. Every decision answered one question: what happens when the wi-fi drops during a rush and 40 online orders are queued up?

Architecture

Offline-first, server-authoritative

The phone is the source of truth for the next 30 seconds; the server is the source of truth for everything older. Orders, sales and stock deductions write locally first, then sync — the kitchen never stops because the tower went down.

React Native · SQLite cache · WAL sync
Stack

React Native + PHP / MySQL

Expo for OTA updates so fixes ship in minutes, not app-store weeks. PHP + MySQL on the back end because the hosting bill is $6/month and the owner's cousin can read the code if I get hit by a bus.

Expo · PHP 8.2 · MySQL 8 · Nginx
Data integrity

Audit log on every mutation

Every sale, void, expense, payroll edit leaves a row with the user, timestamp and before/after value. Nothing disappears silently. If a number looks wrong a week later, you can see exactly who touched it and what it was before.

Append-only log · soft deletes · time-travel reads
Hardware

Runs on phones the staff already own

No custom POS terminal, no proprietary tablet. A shared Android at the counter for checkout, a thermal printer (ESC/POS over Bluetooth) for receipts, and the owner's phone for the dashboard. Total hardware cost: under Rp 2M.

Android 10+ · Bluetooth thermal · QRIS scanner
Integrations

Online orders, QRIS, WhatsApp

GoFood and GrabFood orders pulled into the same order queue as walk-ins. QRIS payments auto-reconcile against the drawer. Payroll slips go out by WhatsApp when the month closes — no more printed envelopes.

Merchant APIs · QRIS callback · WA Business
Security

Owner sees all, staff sees their lane

Role-based permissions from day one. Cashiers can take orders and log expenses but can't void, can't edit payroll, can't see margins. Every elevated action needs the owner's PIN.

RBAC · PIN elevation · device binding
Next → SNAP self-photo

Something
broken like this?

Free scope-out call. We'll tell you the cheapest thing that fixes it.