Skip to content
All projects

SHRM

HR and payroll for Indonesian companies, from one system.

Role
Product Owner & Developer
Period
May 2026 - Present
Status
Launched, web and desktop
Administrator dashboard for the multi-company HR and payroll platform.

Overview

A web and desktop HR and payroll platform that runs payroll, PPh 21 income tax, BPJS, payslips, and employee records for several companies, with data kept separate per company.

Problem

HR teams were running payroll in spreadsheets: PPh 21 TER income tax, BPJS Kesehatan and Ketenagakerjaan, overtime, bonus, and THR all calculated by hand every month.

Payslips and annual tax slips had to be produced and sent to every employee, and employees had to ask HR for documents and leave balances.

Several companies needed to share one system without seeing each other's employees, payroll, or leave requests.

My role

Owned the product end to end: requirements, feature specification, architecture, implementation, testing, and handover documentation.

Designed the payroll rules, access model, and security controls, and built both the Flask backend and the React frontend.

Packaged two deployment targets: a Windows desktop app and a Dockerized web app.

Approach

  1. Specify

    Mapped the monthly payroll cycle, tax rules (PPh 21 TER, PMK 168/2023), BPJS contributions, and year-end reconciliation into feature specifications before writing code.

  2. Build the core

    Automated payroll with gross-up and net methods, plus a one-click refresh that updates draft payroll from employee records while keeping overtime, bonus, and THR inputs.

  3. Serve employees directly

    Launched an Employee Self Service portal for payslips, tax slips, leave requests, and leave balances, so staff no longer need to contact HR for them.

  4. Harden and hand over

    Added two-factor login, encrypted PDFs, an audit trail, and a scheduled email queue, then wrote user guides and deployment runbooks.

Secure sign-in for the SinergisHRM platform.
HRM recap with gross pay, PPh 21, take-home pay, and division details.
Employee reports and statistics across companies and employment types.
Payroll engine with input validation and draft review.

Key decisions

Two deployment targets from one codebase

Shipped as a Windows desktop app (PyInstaller, SQLite) and as a web app (PostgreSQL 16 in Docker with gunicorn and Caddy), so each company can run it the way its IT setup allows.

Per-company data isolation with three admin levels

Role-based access means each admin sees only their own group's employees, payroll, and leave requests.

Payslips protected by default

Payslips and BPA1 tax slips (Form 1721-A1) are generated as password-protected PDFs with AES-256 encrypted attachments before they are emailed.

An email queue that survives restarts

Bulk and scheduled sends use atomic job claiming, heartbeat leases, and automatic recovery after a server restart, so a reboot does not drop or duplicate payslip emails.

Outcome

  • Payroll, income tax, BPJS, and employee records run from one system instead of spreadsheets.
  • HR can email payslips to all staff at once or schedule the send for a set date and time.
  • Employees download payslips and tax slips, and submit or cancel leave, without contacting HR.
  • Contract-expiry reminders go out by email 7 days ahead; year-end tax reconciliation is built in.
  • Bilingual (ID/EN) interface with light and dark themes, plus payroll and self-service user guides.
186
automated tests across payroll, access control, leave approval, and email scheduling
2FA
TOTP and email OTP, PBKDF2-SHA256 hashing, 5-rule password policy
2
deployment targets: Windows desktop and Dockerized web

Test counts describe engineering coverage, not business results.

Stack

Backend
Python
Flask 3
gunicorn
Frontend
React 18
Vite
Tailwind CSS
Data
PostgreSQL 16
SQLite
Delivery
Docker
Caddy
PyInstaller
Next case studyMulti-company WhatsApp Service Platform