Skip to content
JasDev
All projects
Enterprise2026Full-stack developer

Leave Tracker

Mini HRIS where employees file leave and managers approve it, built for correctness: a Go API with idempotent requests, row-level locking and an audit trail, a Next.js backend-for-frontend that keeps the JWT out of the browser, concurrency tests, and CI.

The problem

Leave tracking looks simple until two managers click approve at the same time, a flaky network retries a request, or a balance gets deducted twice. Most small HR tools ignore these races and leak tokens to the browser.

The solution

A Go API that treats every write as a transaction: idempotency keys de-duplicate retries, row locks serialize approvals, and an events table records who did what. A Next.js backend-for-frontend holds the session in an httpOnly cookie and proxies an allow-list of endpoints. Concurrency tests prove the guarantees, and CI checks them on every push.

Screenshots

  • Employee dashboard: balance ring, pending days and request history (local demo data)
    Employee dashboard: balance ring, pending days and request history (local demo data)
  • Manager approval queue, oldest first, with balance impact (local demo data)
    Manager approval queue, oldest first, with balance impact (local demo data)
  • Sign-in page (live site)
    Sign-in page (live site)
  • Account creation with employee or manager role (live site)
    Account creation with employee or manager role (live site)

Architecture

  1. FrontendNext.js 16React 19shadcn/uiTanStack QueryZod
  2. BFFNext.js route handlershttpOnly session cookie
  3. APIGochiJWTrate limiting
  4. DataPostgreSQLpgxgolang-migrate
  5. QualityGo race testsVitestPlaywrightGitHub Actionsgovulncheck
  6. HostingDockerRailway

Highlights

  • Backend-for-frontend: the JWT lives in an httpOnly cookie read only by the Next.js server; the browser never sees it and the Go API needs no CORS.
  • Allow-listed proxy route with an Origin check on top of SameSite=Lax, and revocable server-side sessions so logout really ends the token.
  • Idempotency keys on leave creation: ten concurrent retries create exactly one request and one event.
  • Approvals lock rows with FOR NO KEY UPDATE, so balances are never double-deducted and concurrent cross-approvals produce zero deadlocks.
  • Every change (created, cancelled, approved, rejected) is written to an events table in the same transaction.
  • Keyset pagination, weekday-only day counting, overlap detection and per-IP rate limiting.
  • CI runs go vet, govulncheck, race-detector unit and integration tests, npm audit, lint, typecheck and tests.
  • Deployed on Railway with Docker, private networking and pre-deploy migrations.