Evergreen open source reference for multi-tenant HR software built for agent-assisted, compliance-aware development — a runnable scaffold you can clone, learn from, and extend. It is not a certified payroll vendor or turnkey HRIS replacement.
HR ERP models a human resources platform for mid-market organizations (roughly 250–5,000 employees): one place for people operations—not a patchwork of payroll, time, benefits, and recruiting tools.
Employees get a single portal for pay, time and leave, benefits, profile, and learning. Managers run hiring through offer, team approvals, and workforce tasks without a separate ATS. HR and payroll operate pay runs, period lock, benefits life events, compliance-oriented workflows, and operational dashboards from the same application. Payroll math is native and deterministic (packages/payroll-calc) with auditable inputs; it is not certified IRS/HMRC e-filing. Tenancy and access are designed for SaaS: JWT, policy checks, and Postgres row-level security per tenant.
| Layer | What you learn / reuse |
|---|---|
| HR domain reference | ESS, manager recruiting, payroll runs, benefits flows, SCIM/partner connectors — stakeholder value plan |
| Agent governance harness | Risk tiers (T0–T4), Cursor hooks, handoffs, evidence CI — AGENTS.md, docs/meta/cursor-3-native-runtime.md |
Full positioning (scope, honest demo paths, pairing with external agent-security OSS): docs/meta/evergreen-open-source-positioning.md.
Under the hood: Next.js (App Router) + PostgreSQL (Prisma), with defaults for multi-tenant security, integrations (Redis, optional Kafka), and governance docs (compliance, AI ethics, architecture ADRs). Human contributors and Cursor-orchestrated agents share the same merge bar.
Jump to: Open source positioning · Prerequisites · Quick start · Authentication · Documentation · Tech stack · Security · Containers · Contributing · License
Use this repo to:
- Run a local demo and walk W1–W5 product paths (portal, payroll math, tenancy, hiring) in ~30 minutes — stakeholder value plan
- Study regulated SaaS patterns: RLS, contracts, payroll kernel, counsel-gated compliance docs
- Copy agent harness patterns: manifest overlay,
npm run governance:*, Collaboration plane (Harness HITL) - Fork and extend — jurisdictions, IdP, connectors, bounded-context extraction per ADRs
Do not use it as-is for: production payroll compliance, legal HR advice, or “deploy tomorrow as your company HRIS” without your own counsel and SecOps review.
Companion agent execution governance OSS (policy simulation, sandboxed commands, attestation, forensic receipts) pairs naturally as an optional runtime gateway; HR ERP remains the reference application + in-repo harness. See evergreen positioning.
Buyer / reference-customer demos: stick to employee and HR paths in the value plan — not deferred mock, Track D, or lab routes (deferred-platform-track.md).
| Area | Location |
|---|---|
| Web app | src/ — employee home (/employee) with Feature 022 shell; manager/HR routes; dashboards (/analytics); Phase 3 capability hub (/demo/capabilities when ANALYTICS_DEMO_MODE=1); L10n lab; governance APIs; versioned REST under /api/v1. |
| Server modules | lib/ — domain logic, security, integrations (CODEBASE.md) |
| Data plane | prisma/ — app DB and RLS-oriented migrations; optional bounded-context Postgres via Docker (docker-compose.yml). |
| Security | middleware.ts for /api/v1/*; tenant session GUCs via lib/security/with-authorized-transaction.ts. |
| Contracts | OpenAPI in contracts/openapi/ and Protobuf in proto/ (see npm run contracts:*). |
| Workers | Outbox → Kafka (workers/outbox-publisher/); BullMQ jobs (npm run worker:integrations). |
| ML / analytics (optional) | Python under services/ — training, ETL, FastAPI serving (see Predictive HR). |
- Node.js 22+ (matches CI and the production container; older Node may work for local-only experiments).
- npm (comes with Node; the repo uses a committed lockfile — prefer
npm cifor clean installs). - Docker (optional, recommended) for Postgres, Redis, and optional Kafka/architecture profiles via Compose.
git clone https://github.com/SafetyMP/HR-ERP.git
cd HR-ERP
npm ci
cp .env.example .envEdit JWT_SECRET in .env. The default app database is exposed on host port 15432 (see docker-compose.yml); override with HR_ERP_PG_PUBLISH if that port is taken.
npm run db:up
npm run demo:bootstrap
npm run devdemo:bootstrapapplies Prisma migrations (unless you pass--skip-migrate), predictive HR seed, global L10n demo data, US/JP holiday import, and the Phase 3 snapshot slice (performance, compensation, LMS, workflow, engagement, webhooks, COBRA).- Set
ANALYTICS_DEMO_MODE=1andDEMO_TENANT_ID(must match your seeded tenant) in.envto enable read-only demo Postgres surfaces: predictive dashboards undersrc/app/analyticsand the capability hub (/demo/capabilities).
Open http://localhost:3000/employee for the employee portal (pay, time, PTO, benefits, profile). The marketing home at / links manager/HR paths; with ANALYTICS_DEMO_MODE=1, use Platform capabilities (Phase 3) at /demo/capabilities and Analytics & global labs for churn/skills/benchmarks/L10n.
Buyer demos: Use W1–W5 ESS paths only — do not list Track D, /mock, or /global-l10n as shipped product (docs/product/deferred-platform-track.md).
Deeper setup (multiple databases, Kafka, workers, sign-in): docs/DEVELOPMENT.md.
Full index: docs/README.md.
| Resource | Description |
|---|---|
CODEBASE.md |
Where code lives: lib/, src/, scripts/, tests/ |
docs/DEVELOPMENT.md |
Local dev, auth, scripts, layout, troubleshooting |
docs/QA.md |
Tests, fixtures, FAILURE_SUMMARY handoffs |
FRONTEND.md |
UI patterns, employee shell (022), a11y, API errors |
docker/README.md |
OCI image and Compose overlay |
| Resource | Description |
|---|---|
docs/meta/evergreen-open-source-positioning.md |
OSS scope — reference app vs certified vendor; harness + optional agent-security pairing |
docs/product/stakeholder-value-plan.md |
Active forward plan (Track A/B/C, W1–W7) |
docs/product/reference-customer-exit-runbook.md |
Reference customer exit |
AGENTS.md |
Cursor orchestration, skills, Definition of Done |
docs/meta/cursor-3-native-runtime.md |
Operator loop (governance:*, /multitask) |
| Resource | Description |
|---|---|
CONTRIBUTING.md |
Branches, PR bar, migrations, synthetic data |
SECURITY.md |
Vulnerability disclosure |
CODE_OF_CONDUCT.md |
Community norms |
CHANGELOG.md |
Release history (semantic-release) |
| Context | How |
|---|---|
| Local API | npm run jwt:dev (or jwt:dev:demo-employee, jwt:dev:demo-manager, jwt:dev:demo-hr) — signs with JWT_SECRET in .env; see .env.example. |
| Vercel production API | npm run jwt:dev:vercel uses deployment secrets; production mint requires ALLOW_PRODUCTION_JWT_MINT=1 (Human authorization). |
| Browser sign-in | Neon Auth (Google) or OIDC when configured — phase 1 production checklist. |
| Demo preview | Automatic on Vercel Preview and local dev; Production requires explicit flags — see checklist and AGENTS.md safety notes. |
/api/v1/* expects Authorization: Bearer <JWT> unless a route documents session/cookie auth.
- Runtime: Node 22+, Next.js 16, React 19, TypeScript
- Data: Prisma 7, PostgreSQL (pgvector image in Compose for the default DB)
- UI: Tailwind CSS 4, Radix primitives, TanStack Query / Table, Recharts
- Validation: Zod, React Hook Form
- Tests: Vitest, Playwright
- Tooling: ESLint (Next config), Prettier, Buf, Spectral
| Command | Use |
|---|---|
npm run dev / build / start |
Dev server, production build, serve |
npm run lint |
ESLint |
npm run test / test:e2e |
Vitest / Playwright |
npm run security:scan |
Repository security scan |
npm run contracts:openapi / contracts:buf |
Contract lint |
| Command | Use |
|---|---|
npm run db:up / db:up:arch |
Docker: default stack vs architecture profile |
npm run db:migrate:deploy / db:migrate |
Deploy vs author migrations |
npm run demo:bootstrap |
One-shot local demo data |
npm run db:studio |
Prisma Studio |
| Command | Use |
|---|---|
npm run jwt:dev / jwt:dev:demo-* |
Dev JWT — Authentication |
npm run governance:lint / governance:ci |
Agent harness tier + merge gates |
npm run check:lib-boundaries |
Forbidden cross-import check |
npm run verify:reference-exit |
Reference-customer exit artifact check |
npm run ops:smoke |
Staging smoke — phase 1 checklist |
npm run worker:integrations / worker:webhooks |
BullMQ workers |
See package.json for the full list.
- Docs:
docs/security/stack-decision.md,docs/security/policy-catalog.md,docs/security/rls-session-contract.md,docs/security/tls-and-data-at-rest.md - CI:
npm run security:scan; ESLint rules around unsafe raw SQL (eslint.config.mjs) - Dev JWT:
npm run jwt:dev(requiresJWT_SECRETin.env)
- Schema:
prisma/schema.prisma— e.g.Department,JobRole,ChurnScore,MarketBenchmark - Seed:
npm run demo:bootstrapornpm run db:seed:predictive— alignDEMO_TENANT_IDwithlib/l10n/demo-tenant.ts(defaultdefault-tenant) - APIs:
src/app/api/v1—analytics/churn,analytics/skills/match,analytics/benchmarks,ml/churn/score - Python:
services/pipelines/train_churn.py; serve withuvicorn churn_api:app --app-dir services/ml-serving --port 8090; ETLservices/pipelines/etl_features.py - Privacy:
docs/anonymization.md
- Versioning: Use Conventional Commits on PRs merged to
main/master..github/workflows/semantic-release.ymlruns semantic-release, updatespackage.json,package-lock.json, andCHANGELOG.md, pushes achore(release): … [skip ci]commit, createsv*tags, and publishes a GitHub Release (retry via workflow_dispatch if needed). - Docker: Root
Dockerfile— ADR0003(distroless runtime, multi-arch). Local Compose overlay:docker/README.md,docker/compose.app.yml. - GHCR: A published GitHub Release triggers
.github/workflows/publish-ghcr.yml: multi-archlinux/amd64andlinux/arm64, SBOM, provenance, push toghcr.io/<lowercased-owner>/<lowercased-repo>:<semver>and:latest, Cosign signature on the digest. Ad hoc builds: workflow manual dispatch with a scratch tag.
Verify a pulled image (replace OWNER, REPO, DIGEST):
cosign verify "ghcr.io/OWNER/REPO@sha256:DIGEST" \
--certificate-identity-regexp '^https://github.com/OWNER/REPO/\.github/workflows/publish-ghcr\.yml@.*' \
--certificate-oidc-issuer-regexp '^https://token.actions.githubusercontent.com$'Local image smoke:
docker build -t hr-erp:local .
docker run --rm -p 3000:3000 \
-e DATABASE_URL='postgresql://user:pass@host:5432/db?sslmode=require' \
-e JWT_SECRET='replace-with-production-secret-at-least-32-chars' \
hr-erp:localIssues and PRs are welcome. Read CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, and docs/community/README.md. Branch protection and CI expectations: docs/community/github-branch-protection.md.
By contributing, you agree your contributions are licensed under the Apache License 2.0, the same license as the project (see LICENSE), unless you state otherwise.
This application depends on many open-source packages. Each dependency has its own license. For an aggregate view, use your toolchain (for example npm ls and package metadata, or your organization’s SBOM process). Product and company names (e.g. Next.js, PostgreSQL, Redis) may be trademarks of their respective owners; this README does not imply affiliation.
Copyright 2026 HR ERP contributors.
Licensed under the Apache License, Version 2.0. See the full legal text in LICENSE and attribution notes in NOTICE.
SPDX-License-Identifier: Apache-2.0