← Projects
LiveRailway · SQLite · Litestream backups

YayaHR

Household-staff payroll built for Philippine families — biweekly periods, 13th month, leave, loans, advances.

Flask 3SQLiteAlembicHTMXTailwindAuthlib
●●●
Payroll · June 2026
Biweekly · 4 staff
Ready to run
13TH
13TH
13TH
13TH
Period

The problem

Most Philippine households with maids, drivers and nannies still run payroll on paper or in a WhatsApp thread, because off-the-shelf payroll software doesn't model the things we actually need. Biweekly cycles, 13th-month pay, partial-payment loans against a maid's salary, leave that draws down from a yearly allowance — none of that maps onto a US-shaped payroll product. So families end up rebuilding the same spreadsheet over and over, and the moment anyone goes on leave or takes an advance, the math gets fuzzy.

The solution

YayaHR is a friend-scale multi-tenant web app that I spun out of Joint Venture's staff-payroll module once it was clearly more than just our household. The employer logs in with Google, adds their staff, picks the right pay frequency (weekly, biweekly, semi-monthly or monthly), and the app handles the rest. Biweekly periods anchor on a deterministic Saturday so there's never any drift, absence math uses work days rather than calendar days, 13th-month pay accrues automatically with every payslip, and loans and advances support partial recovery with full audit history. There's no staff-facing portal on purpose — this is a single-user product where staff exist as records, not users.

Features

  • Multi-tenant: each employer has their own organization, with strict isolation
  • All four common pay frequencies: weekly, biweekly, semi-monthly and monthly
  • Absence math computed by work days, not calendar days
  • 13th-month pay accrues automatically with every payslip
  • Loans and advances against salary with partial recovery and full audit history
  • Leave tracking with a yearly allowance and per-date constraints
  • Per-organization module toggles for payroll, leave and attendance

Architecture

  • A single Flask app on Railway, with SQLite under the hood and Litestream handling continuous backups
  • Three layers of tenant isolation: an `@require_org_member` decorator, an `org_id` filter on every query, and per-route `_*_or_404` helpers that fail closed
  • Modules can be toggled per organization via an `Organization.features` JSON field — payroll and leave are live; attendance is scaffolded but not turned on yet
  • Per-period salary model, where biweekly is a real `pay_type` and not a value derived from something else
  • Soft-delete on staff, advances and loans; hard-delete on leave (which has a unique-per-date constraint) and on payslips (which restores any advance and loan balances they had drawn down)
  • Three hundred passing tests across the rate-basis logic, the absence math and the 13th-month accrual