Employee Self-Service (ESS)

A personal portal where each employee sees and manages only their own data

What This Module Does (Plain Language)

ESS is the staff-facing side of HRM. It lives under the /me routes and the /api/v2/me/* endpoints. An employee logs in and sees a small, focused dashboard of their own information: today's attendance, this week's roster, leave balance, recent payslips, and company holidays. They can clock in/out, apply for leave, request a shift swap, and edit a few personal details — and nothing else.

ESS is a window, not a second HR system

ESS doesn't re-implement any business logic. When an employee applies for leave through ESS, it calls the exact same leave service HR uses — with the employee forced to "you". So the rules (balance, overlap, half-day) are identical no matter where the request comes from.

The Golden Security Rule: Self-Scope

Every /me/* endpoint resolves "who am I?" on the server from your login, and uses only that employee id. You cannot ask for someone else's data by putting an employeeId in the request — it's ignored. This is what stops one employee peeking at another's payslip.

SituationWhat happens
Your login is linked to an employeeNormal access to your own data.
Your login has no employee record (e.g. SUPER_ADMIN)Returns 409 NO_LINKED_EMPLOYEE — never a server crash.
You're terminated/resignedYou can still read your past payslips & attendance (your right to your records), but write actions (check-in, leave, swap) return 403 EMPLOYMENT_INACTIVE.
You send someone else's employeeId in the bodyIt's ignored; your own id is always used.
You request a payslipOnly your own, and only FINALIZED ones — never a draft, never another person's.

What an Employee Can Do

AreaPageEndpoint(s)
Dashboard/meGET /api/v2/me/dashboard
Profile (view + limited edit)/me/profileGET / PATCH /api/v2/me/profile
Attendance + clock in/out/me/attendanceGET /api/v2/me/attendance · /today · /summary · POST .../check-in · check-out · break-start · break-end · regularize
Shifts + swap/me/shiftsGET /api/v2/me/shifts · POST .../swap-request · swap-respond/:id
Leave + apply/me/leave, /me/leave/applyGET /api/v2/me/leave/types · /balance · /requests · POST .../requests · .../requests/:id/cancel
Payslips/me/payslips, /me/payslips/[id]GET /api/v2/me/payslips · /:id · /:id/pdf
Documents/me/documentsGET /api/v2/me/documents
Holidays/me/holidaysGET /api/v2/me/holidays?year=
Everyone gets ESS — not just the EMPLOYEE role

A manager is also a person who takes leave and gets paid. So all staff roles (CASHIER, MANAGER, HR_MANAGER, ACCOUNTANT, ADMIN) hold the ess.* permissions for their own data. The EMPLOYEE role is special in that it has only ess.* — no back-office access at all.

The Profile Edit Whitelist

PATCH /api/v2/me/profile accepts a strict, short list of fields. Anything outside it is rejected with a 400 — you cannot change your own salary, job title, department, or identity through ESS (those are HR's job).

✅ You can edit❌ You cannot edit (HR only)
phone, alternatePhonefirstName, lastName, employeeCode
address, city, state, postalCode, countrynationalId, passportNumber, taxId
emergencyContactdepartmentId, designationId, storeId, reportsToId
photoemploymentStatus
preferences (language, theme)anything under salary
http
json

Clocking In & Applying for Leave (the two most common actions)

1

Clock in

On /me or /me/attendance the check-in widget calls POST /api/v2/me/attendance/check-in. The same geofence/IP/QR rules from the Attendance module apply — ESS just forwards your punch; Attendance is the judge.

2

Apply for leave

On /me/leave/apply pick a type and dates. Your manager is notified instantly. Track the status on /me/leave and cancel a pending one if plans change.

Every ESS Page Handles These States

The portal is the most mobile-relevant surface (staff use it on their phones), so each page is built to gracefully show:

StateWhat the employee sees
LoadingA spinner inside a card.
EmptyA friendly message — e.g. "No payslips yet — check back after your first pay run."
ErrorA clear card mapped from the backend code (e.g. "Your account isn't linked to an employee profile" with an HR-contact prompt).
Permission deniedA standard "you don't have access" card.
MobileA top nav + fixed bottom tab bar for thumb-friendly navigation.
Friendly error mapping

ESS turns backend codes into human messages: NO_LINKED_EMPLOYEE → "ask HR to link your account"; EMPLOYMENT_INACTIVE → "your status no longer allows this"; INSUFFICIENT_BALANCE → shown right on the leave-apply form.

Next step

Approvals and confirmations reach people instantly through Real-Time Notifications.