Context
Most growing companies run HR on a mix of spreadsheets, a payroll bureau, email threads for leave and a shared drive for contracts. Each tool holds a different version of the employee. ZekoHR is our own HR platform, built to be sold as software-as-a-service to many companies at once: payroll, attendance, recruitment, document management, expenses and grievance handling in one system, with each company configured rather than coded.
The product sits in the HR technology space, and the decisions below are the ones we now carry into client work in that sector and in any multi-tenant product that holds sensitive personal data.
The challenge
- Isolation. An HR system holds salaries, bank details, medical notes and grievance cases. A cross-tenant leak would end the product.
- Payroll correctness. Every payslip must be reproducible months later and explainable line by line. Rules change between periods and vary by jurisdiction.
- Need-to-know access. Employees, managers, HR, finance and administrators all see different slices. Grievances need restricted visibility even from HR administrators.
- Auditability. Who changed a salary, when, and what was it before?
- Where AI fits. Recruitment and policy questions benefit from language models. Payroll must never depend on one.
What we built
- Multi-tenancy. One codebase. The tenant is resolved at sign-in, carried in the session and applied by the data-access layer. No repository method can be called without a tenant scope.
- Payroll engine. Rules are versioned data, not code. A dry run shows the difference from the previous period before anyone approves. Approved periods lock, and every payslip stores the rule-set version and the inputs that produced it.
- Attendance and leave. Clock-in from web and mobile, timesheets, leave balances and approvals that feed payroll directly.
- Recruitment. Job postings, a pipeline per role, interview scheduling, and AI-assisted parsing of CVs into structured fields that a recruiter confirms.
- Documents. Contracts, letters and certificates in encrypted storage, served through short-lived signed URLs with a per-document access list.
- Expenses. Claims with receipts, policy limits, approval chains and export into the payroll run.
- Grievances. Cases with a restricted access list, a separate audit trail and no appearance in general reporting.
Architecture
Key decisions
1. One codebase, with the tenant filter in a single layer
We considered a database per tenant. It isolates well but makes migrations, reporting and onboarding slow. We chose shared tables with a mandatory tenant scope in the data-access layer, backed by continuous-integration tests that deliberately try to read across tenants. The scope is impossible to forget because the repository API has no method without it.
2. Payroll is a deterministic engine
Rules live as versioned data with effective dates. A payroll run is a pure function of the rule-set version and the inputs, so re-running an old period gives the same result. The dry run produces a diff against the previous period, which is where most mistakes are caught. No language model is anywhere near this path.
3. Need-to-know access rather than role-to-everything
Roles grant broad access; grievances subtract from it. A case is visible only to the people named on it, and an HR administrator who is not named cannot see that it exists. The audit trail for cases is separate, so a routine audit export does not reveal them.
4. An append-only audit log
Every change to a salary, contract, claim or role writes a before-and-after record that cannot be edited. This turned out to be the feature finance teams ask about first.
5. AI only at the edges, with a human in the loop
Language models parse CVs into structured fields, answer policy questions with citations to the company's own handbook, and draft job descriptions. In every case a person confirms the output before it becomes a record. The pattern is the same one we use in recruiting AI engagements, and it keeps the product on the right side of data-privacy expectations for employee data.
6. Onboarding by configuration
A new company is a set of configuration records: pay elements, leave types, approval chains, document templates. Nothing is deployed to add a tenant.
Outcome
Companies are onboarded by configuration rather than by a project. Payroll runs are reproducible and explainable line by line, and audit questions are answered from the log rather than from memory. AI features in recruitment and policy support were added without any change to the tenant model or the payroll engine. The design has held as the product has grown in modules and in companies.
What this means for you
If your product holds sensitive data for many customers, decide where tenant scope is enforced before you write a feature, make the audit log append-only from day one, and keep language models out of any calculation that someone must reproduce later. We bring those rules to HR tech builds, to multi-tenant SaaS in other sectors, and to AI implementation work where a model is being added to an existing system of record.