Skip to content
Projects
2 min read

HR Management System (Implementation)

Working Next.js + NextAuth + Prisma implementation of the HR specification, with role-based access, audit trails, and enterprise authentication.

Role
Full-stack engineer
Year
2025
Status
beta
full-stackenterprise

Overview

The implementation track of the HR Specification project. A Next.js 16 + NextAuth + Prisma application that turns the operating-model spec into a deployable system: strict role-based access, audit trails on every mutation, clean module separation, and an opinionated form pipeline.

Problem

Translating a 300-page operating model into a deployable system requires more than picking a stack. Every persona's permission boundary, every workflow's approver chain, and every audit requirement has to be enforced at the data layer, not just the UI.

Approach

Use NextAuth for session management with strict role checks. Encode RBAC at the Prisma query layer so a UI bug can't accidentally expose data outside a user's scope. Use react-hook-form + zod for input validation aligned to the spec's field-level rules. Log every mutation through a unified audit pipeline.

Architecture

  • Auth: NextAuth 5 (beta) with role-aware sessions and middleware-enforced route guards.
  • Data: Prisma 6 over PostgreSQL with migrations driving the data model.
  • Server state: TanStack Query.
  • Client state: Zustand for cross-page state.
  • Forms: react-hook-form + zod, validation aligned to the spec.
  • UI: shadcn/ui primitives over Tailwind CSS 4.
  • Logging: Pino for structured logs across server boundaries.

Tech stack

  • Frontend / backend: Next.js 16, React 19, TypeScript
  • Auth: NextAuth 5 (beta)
  • ORM and DB: Prisma 6, PostgreSQL
  • State: Zustand, TanStack Query, TanStack Table
  • Forms: react-hook-form, zod
  • UI: shadcn/ui, Tailwind CSS 4
  • Observability: Pino

Engineering highlights

  • RBAC at the data layer: every Prisma query goes through scope-aware helpers; a developer can't accidentally bypass access rules.
  • Audit-everything pipeline: every mutation produces an audit row with actor, target, before/after, and reason.
  • Spec-aligned forms: input validators map directly to the spec's field rules, so changes to the spec propagate as code changes, not Slack messages.
  • Beta-by-design: NextAuth 5 was still beta during implementation, so adapters and migrations were chosen for forward-compatibility.

Outcome

Production-ready foundation, in beta with a controlled rollout. Building on the specification means there's no ambiguity about what "done" looks like for each module.

Lessons

  • Implementing a spec written by the same author is unusually fast: the engineering decisions slot directly into the operating-model decisions.
  • Auth at the data layer beats auth at the route layer every time.
  • Audit logs only matter if they're queryable. Schema them like first-class data, not stringly-typed events.

Want to dig deeper?

Ask my AI agent anything about how this was built, what tradeoffs I made, or how it could fit your team.

Ask my AI →