Skip to content
/ EMS Public

Employee Management System (NestJS)

kashyap3/EMS

Repository files navigation

Employee Management System (NestJS)

Features

  • Login for Admins & Employees (/auth/login → JWT)
  • Create/Update/Delete Employees (ADMIN/SUPER_ADMIN)
  • Create/Update/Delete Admins (SUPER_ADMIN, with “self” exceptions)
  • Attendance: punch-in & punch-out (employees self; admins can act for others)
  • Reports: download attendance CSV with optional filters
  • Redis caching for quick list views

Quickstart

2) Start MongoDB & Redis (Docker)

docker run -d --name mongo -p 27017:27017 -v mongo_data:/data/db mongo:6
docker run -d --name redis -p 6379:6379 redis:7

3) Configure environment

Create .env in the project root:

PORT=3010
MONGODB_URI=mongodb://localhost:27017/ems
REDIS_URL=redis://localhost:6379
JWT_SECRET=supersecret_change_me
JWT_EXPIRES=1d

4) Install & run

npm install
npm run start:dev

Swagger Documentation - http://localhost:3010/docs for Swagger UI.

API quick tour

Auth

  • POST /auth/login → returns { access_token }

Employees (ADMIN/SUPER_ADMIN)

  • POST /employees
  • GET /employees
  • GET /employees/:id (admin or self)
  • PATCH /employees/:id (admin or self)
  • DELETE /employees/:id

Admins (SUPER_ADMIN; self rules applied on GET/PATCH by id)

  • POST /admins
  • GET /admins
  • GET /admins/:id
  • PATCH /admins/:id
  • DELETE /admins/:id (SUPER_ADMIN)

Attendance (JWT required)

  • POST /attendance/punch-in
  • POST /attendance/punch-out
  • GET /attendance?employee=&from=&to=&date= → filter by employee and date/range

Reports

  • GET /reports/attendance?employee=&from=&to= → CSV download (headers when empty)

Curl examples

# 1) Login (get token)
curl -X POST http://localhost:3010/auth/login   -H "Content-Type: application/json"   --data '{"email":"[email protected]","password":"Password@123"}'

# 2) Punch in (as employee)
curl -X POST http://localhost:3010/attendance/punch-in   -H "Authorization: Bearer <TOKEN>"

# 3) Download CSV (admin)
curl -G http://localhost:3010/reports/attendance   -H "Authorization: Bearer <TOKEN>"   --data-urlencode "employee=<EMPLOYEE_ID>"   --data-urlencode "from=2025-08-01"   --data-urlencode "to=2025-08-31" -o attendance.csv

Exceptins

  • Duplicate email → API returns 409 Conflict: email already exists on create/update.
  • No active punch-in on punch-out → make sure there’s an open attendance record (punchOut missing or null) for that employee.
  • Connected to wrong DB (e.g., test) → check .env MONGODB_URI and restart.
  • Unauthorized → click Authorize in Swagger and paste Bearer <token>.

Approach:

  • Modular NestJS design (Auth, Admin, Employee, Attendance, Reports), MongoDB via Mongoose, Redis cache for “list” endpoints, JWT + role guards, DTO validation, Swagger at /docs.
  • Pragmatic error handling: pre-check + try/catch around writes (409 on duplicate email), clean CSV responses (fields defined; header-only on empty).

Design decisions:

  • Separate Admin and Employee entities: different lifecycles/permissions; Admin carries a Role enum (SUPER_ADMIN/ADMIN), Employee is simpler. Reduces over-fetching and keeps RBAC explicit.
  • RBAC model: token embeds { sub, kind: 'ADMIN'|'EMP', role? }; @Roles() + RolesGuard enforce route access. Employees act on self; Admin/Super Admin can act “on behalf” (e.g., attendance).
  • Attendance storage: one document per session with punchIn and optional punchOut. “Open session” = punchOut missing or null; punch-out uses atomic findOneAndUpdate to avoid races.
  • Reports: server-side CSV with json2csv; fields defined explicitly; when no data, return header-only CSV (or 204). Report rows map employee to email for readability.
  • Caching: Redis-backed CacheModule TTL ~60s for list endpoints; invalidation on create/update/delete to keep UX snappy without stale data.
  • Config: env-first (process.env/ConfigModule), sensible defaults, easy Docker-friendly local dev.

About

Employee Management System (NestJS)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published