One company's entire HR operation, in one system.
B.M Enterprises needed one place for everything to do with an employee — personal details, passport and visa status, contracts, family information, documents, and company assets — plus the day-to-day operational layer on top of it: attendance, leave requests, and who's allowed to see or approve what.
Built by a 6-person team as both a web console and a mobile app, and used daily by 50+ employees and 50+ system users across the company.
Build the operational logic, not just the data screens.
An HR system is easy to under-build as a set of forms over a database. The parts that actually mattered here were the ones with real rules behind them.
A profile, not a page
Personal info, passport/visa, contracts, family, documents, and assets each live as their own structured record, linked under one employee — not one long form.
Attendance as logic, not a log
Check-in and check-out compute working hours, late arrival, and early departure automatically — status, not just a timestamp.
Requests as a tracked workflow
Leave and early-leave requests move through creation, review, and a visible status — not an email that disappears into an inbox.
One Supabase backend, two real clients.
Web and mobile weren't a responsive site and an afterthought wrapper — they were two separate applications, React for web and React Native (Expo) for mobile, sharing the same Postgres schema, auth, and business logic through Supabase. The same attendance rules and permission checks apply whichever client a user is on.
Web
React · TypeScript
Mobile
React Native · Expo · React Native Paper
Backend
Supabase — Postgres, auth, storage
Data & forms
Refine · React Hook Form · Zod
State
Zustand
Permissions
CASL
Dates & locale
date-fns · date-fns-tz · expo-localization
Workflow
Git · GitHub
Different jobs for each platform, same rules underneath.
The web console was built for HR and management — the full employee profile, reporting, and approvals, where a larger screen and a keyboard do real work. The mobile app was built for employees themselves — check-in and check-out from wherever they actually are, and submitting or tracking a leave request without opening a laptop.
Both read and write through the same Supabase tables and the same CASL permission rules, so a role change or a new field in the employee profile only has to be defined once to be correct on both platforms.
Attendance and requests as real state, not status text.
Check-in and check-out times feed directly into working-hours, late-arrival, and early-departure calculations, computed from company shift rules rather than entered by hand. A leave or early-leave request moves through its own lifecycle — submitted, under review, approved or declined — with that status visible to both the employee who filed it and whoever needs to act on it, on web or mobile.
A few calls that came from real HR complexity, not a template.
Looking back at it, three decisions do more work than they look like they do:
A profile that's actually a data hub
Passport, visa, contracts, family, documents, and assets are separate structured records under one employee, not fields crammed into a single form.
Permissions enforced once, honored twice
CASL-based role access is defined centrally and respected by both the web console and the mobile app — not reimplemented per screen or per platform.
Two real products, one source of truth
Web and mobile are genuinely separate applications with different jobs, not one codebase stretched to fit two screens — yet neither can drift out of sync with the other's data.
Built so a new role or request type wouldn't mean a rebuild.
Because permissions ran through CASL rather than scattered if-checks, and requests were modeled as a generic status lifecycle rather than one-off logic per request type, adding a new role or a new kind of request was meant to be a configuration change — new rules and a new status set — not new screens from scratch.
A real system, in daily use, for about two years.
SFYR ran in production for roughly two years, used daily by 50+ employees and 50+ system users across B.M Enterprises for attendance, leave, and employee records on both web and mobile — before development was paused and the project was not carried further.