Full-stack engineer — HRIS, payroll, and operations systems
Tacloban City, Philippines · open to remote and Cebu/Tacloban roles
I build the software a BPO actually runs on: time and attendance, Philippine statutory payroll, leave, and multi-site inventory. Most of these systems are designed, built, and shipped solo end to end — data model, permissions, payroll math, UI, and deployment.
prime-hris · live — HRIS and payroll for multi-site BPO operations
Next.js 16 · React 19 · Prisma 6 · PostgreSQL · Socket.IO
33-model HRIS covering employees, shift templates, attendance, leave, and payroll.
- Philippine payroll engine — DOLE, SSS (RA 11199), PhilHealth UHC, Pag-IBIG, and TRAIN withholding computed from bracket tables stored in the database, so a rate change is a data update, not a redeploy.
- Attendance to payslip pipeline — shift assignments, overtime and holiday rules, payroll exceptions, payslips with adjustments, and an audit entry for every mutation.
- Real-time layer — Socket.IO chat and HR inbox on a custom Next server, with online presence and typing state tracked server-side.
mebs_inventory · live — asset and inventory management for multi-site BPOs
Next.js · Prisma · Auth.js v5 · Vitest
36-model inventory system: assets, consumables, transfers, maintenance, and offboarding clearance.
- Authorization is server-side only — 52 permissions across 8 roles, enforced by
requirePermissionin every action and page, withsiteScopekeeping site admins inside their own sites. - Custody trail — multi-line site-to-site transfers and an exit clearance workflow that blocks offboarding until equipment comes back.
- Tested — 8 Vitest suites plus a smoke script that boots the production build and asserts routes, login, and CSV exports.
Next.js 16 · Prisma 7 · Argon2 · TOTP
- Security first — Argon2 password hashing, TOTP MFA for staff, server-side RBAC matrix, audit log, and validated uploads.
- Rate limiting that survives serverless — Postgres counters with an in-memory short-circuit per instance, so a burst of traffic stops hammering the database.
- Retention by policy — visitor photos live in private blob storage and are purged by a scheduled retention job.
- CI on every push — lint, typecheck, 9 Vitest suites, and a production build.
Next.js 16 · Drizzle ORM · Neon · Vitest
- Statutory contributions with timezone-correct daily cutoffs (Asia/Manila) and a manual DTR review step before pay runs.
- Sensitive identifiers encrypted at rest — AES-256-GCM with a key that hard-fails in production if missing.
- 12 Vitest suites covering payroll math, leave, lockout, and access scope.
Also shipping: saripos (multi-store POS), jorify (multi-tenant commerce SaaS), plus client storefronts for retail, food, and gym businesses.
- Typed boundaries. Zod at every input, server actions for every mutation, nothing trusted from the browser. Permissions are checked in the data layer, not in the component.
- Money and access control get tests. Payroll arithmetic, statutory tables, and permission checks are the code I refuse to ship on vibes.
- Boring infrastructure. Postgres, migrations in version control, CI that runs lint, typecheck, tests, and a build on every push.
- Readable over clever. Every repo here is something a new hire could pick up.
Off the clock
The arcade in this profile is a canvas game I built for fun — character select, collision, and save state with no engine.