LeaveDesk
A working demonstration of a leave and approval portal — an escalation ladder derived from policy, a permission matrix the server actually enforces, and impersonation that names the human at the keyboard.
- Role
- Architect & sole engineer
The application
Screens, captured from the running app
Booted against its seeded database and walked route by route — these are the real pages, not mockups.






A demo, built to show the architecture behind a confidential internal HR system without exposing it. The firm and its people are invented. The approval ladder, access rules and audit behaviour are the real thing.
Why it exists
Leave portals look trivial from outside — a form, a calendar, an approve button. The parts that decide whether one gets used are all invisible in a screenshot, so here they are running: twelve employees across five departments, thirty-three requests, and a full audit trail.
The ladder is derived, never chosen
A requester never picks their approvers. The ladder falls out of the policy:
- Level 1 is always the line manager.
- Level 2 — a director — is added when the request exceeds 10 days, when reimbursable costs exceed €500, or when the leave is unpaid at any length.
Each rung stores why it exists as text, and that text is shown to everyone: "12 days exceeds the 10-day manager limit". Escalation is never a surprise to the person waiting, and nobody has to go and read the handbook to find out why their week off needs a director.
The queue distinguishes "yours" from "not yet yours"
The approvals screen splits pending rungs into two lists: those where every earlier rung is already approved, and those still waiting on someone else.
This sounds fussy and it is the difference between a queue people check and a queue people ignore. If a director's list is padded with second-rung reviews their managers haven't reached yet, the list stops meaning anything within a fortnight.
The permission matrix is one source of truth
Five roles — staff, manager, director, HR admin, super-admin — over a matrix of actions. The server consults it before touching the database, and the roles page renders the same matrix.
Hiding a control the server would refuse anyway is a courtesy to the user, not a security boundary. Deriving both from one declaration means the UI can't quietly drift out of step with what is actually enforced.
Impersonation that can't hide
A super-admin can act on someone's behalf — that capability exists for the phone call where a return date is wrong and the person is already on a plane. Support work genuinely needs it.
What it must not do is let the trail show the impersonated person taking an action they never took. So every event stores two fields: actor is the real human, onBehalfOf is the account. In the trail those rows are tinted and labelled "acting for —", and the seed contains nine of them.
An impersonation feature without that distinction is worse than no impersonation feature, because it manufactures false evidence about a colleague.
Also on screen
Entitlement and balances by department, with carry-over shown separately from the annual allowance because it expires on a different date. Working days are computed excluding weekends rather than taken as a raw date span.
Stack
Next.js 16 App Router with React Server Components, Prisma over SQLite, six routes, deterministic seed. In production this shape pairs with Azure AD SSO through MSAL and notifications over SendGrid and Teams; the demo leaves the integrations out, since they are configuration rather than architecture.