Nexa People

A multi-tenant HR platform: employee records, attendance, leave and payroll on one data model.

49
Employees on the demo tenant
10
Filters
1
Source of truth

What they came with

Most small HR teams keep the same employee three times over: once in a personnel folder, once in an attendance sheet, once in the payroll workbook. When a salary changes mid-month someone has to remember all three, and the payroll run turns into a reconstruction job rather than a calculation. Nexa People puts one record underneath all of it, so attendance, leave and payroll read the same contract, the same salary and the same history. It is multi-tenant, so a group running several companies keeps them apart without running several systems.

What the engagement covered

  • Filterable employee directory with role templates and documents
  • Bulk import, export and credential sending
  • One record feeding attendance, leave, payroll and performance
  • Gross, tax and net pay computed from attendance and leave
  • Approval, payslip sign-off and disbursement in one flow
  • Salary advances, claims and adjustments handled in the same module

Technical detail

Tenancy enforced at the row

Every table carries a tenant id and Postgres row-level security applies it, rather than trusting each query to remember a where clause. The tenant is resolved once from the session in a NestJS request-scoped provider and set on the transaction, so a service method has no way to run without one.

Salary and role kept as history

Contract, role and salary changes append effective-dated rows instead of overwriting the previous value, and payroll reads the row that was valid on each day of the period. A back-dated correction therefore recomputes cleanly and still leaves what was actually paid visible.

Payroll as a resumable run

A run is a BullMQ job that computes one line per employee into a draft state; approval freezes the snapshot and generates payslips from it. Lines are idempotent on run and employee, so a worker that dies halfway resumes without paying anyone twice.

Attendance is the payroll input

Clock events are append-only and leave approvals are reconciled against them, so the payroll run never invents a day. Days with neither attendance nor approved leave are flagged before the run rather than quietly paid or quietly dropped.

The stack

Interface

Next.jsReactTypeScriptTailwind CSS

Application

NestJSNode.jsPrisma

Data and jobs

PostgreSQLRedisBullMQS3-compatible object storage

Run and deploy

DockerTraefikKomodo
Sector
HR platform
Audience
HR and payroll teams
Shape
Built, shipped and run by us
Stack
Next.js, NestJS, PostgreSQL
Next case studyNexa CoverageA growth CRM with AI assistance inside the pipeline: drafts, call scripts and lead scoring where the rep works.

Something like this to build?

Tell us what runs today and where it hurts. An engineer reads it and replies.