Skip to content

One HR platform for a fast-growing team

An internal HR platform where onboarding, time-off, and people data live in one place, built for daily use by growing teams.

WrenfoldCalder & VossSearch peoplePRPriya RamanManager · Delivery
Good morning, Priya
Head of Delivery · 8 direct reports
Thu 17 Sep 2026Request time off

Waiting on you 6 requests

Routed to you from the reporting line
MLMei Lin TanAnnual leave · Mon 26 – Fri 30 Oct · 5 daysNo one else offSent 11 SepDeclineApprove
OPOwen PryceAnnual leave · Thu 1 – Fri 2 Oct · 2 daysNo one else offSent 14 SepDeclineApprove
AOAisha OkaforAnnual leave · Mon 12 – Fri 16 Oct · 5 daysCallum already off 13 – 14 OctSent 15 SepDeclineApprove
IDInes DuarteAnnual leave · Mon 5 – Wed 7 Oct · 3 daysSofia already off 5 – 6 OctSent 16 SepDeclineApprove
CRCallum ReidAnnual leave · Fri 25 Sep · 1 dayNo one else offSent 17 SepDeclineApprove
BHBen HartleyAnnual leave · Fri 2 Oct, afternoon · 0.5 daysNo one else offSent 17 SepDeclineApprove

Your team, next two weeks

Approved Pending
M 21
T 22
W 23
T 24
F 25
M 28
T 29
W 30
T 1
F 2

Off today

2 of 8
MLMei Lin TanTue 15 – Fri 18 SepBack Mon 21 Sep
SMSofia MarchettiThu 17 SepBack Fri 18 Sep

Your balance

Computed from policy just now
13days left of 27
Allowance · UK standard25Carried over2Taken · booked11 · 3

Time to a decision

Request to decision, median
With Wrenfold1.4 days
Spreadsheets and inbox4.0 days
16 of 17 managers approved in Wrenfold this month

How the work was scoped

Industry
Professional Services
Duration
15 weeks
Cooperation model
Time & materials
Services
Internal platformApproval workflowsOngoing support
Integrations
HubSpotDocuSignXeroGoogle Workspace
Technologies
Next.jsTypeScriptPostgreSQLPrismaTailwind CSSAuth.js
Team
1 Project lead1 Product designer2 Frontend engineers1 Backend engineer1 QA engineer

Client name withheld under NDA. Engagement details are shown to the extent our agreement permits.

The problem

What went wrong, and when

HR data was spread across disconnected sheets, so requests slipped, people data went stale, and managers had no clear view of their team.

The same person existed in a payroll sheet, a directory sheet and an inbox thread, and none of the three agreed about their manager. Requests slipped because approval was a message someone had to notice, and the directory went stale because updating it was nobody's specific job. So managers had stopped using it and were asking in Slack instead.

We modeled the core HR workflows, designed role-based views for staff and managers, and built approval flows and a directory that stay accurate as the team grows.

Process

Phase by phase

  1. Phase 1: Audit

    What the spreadsheets were actually holding

    Cataloged every sheet, form, and shared doc in use, and which of them was authoritative when two disagreed.

    • Source inventory
    • Field mapping
    • Authority list
  2. Phase 2: Model

    One employee record

    Modeled the employee, the team, and the leave ledger as related records so a change in one place propagated instead of being retyped.

    • Data model
    • Migration plan
  3. Phase 3: Build

    Self-service flows

    Built onboarding, time-off, and review flows against the shared model, with role-scoped access from the first commit, never bolted on.

    • Onboarding flow
    • Time-off module
    • Permission model
  4. Phase 4: Cut over

    Migration and handover

    Migrated live records, ran both systems in parallel for one cycle, then retired the sheets.

    • Migrated dataset
    • Parallel-run report
    • Admin runbook
WrenfoldCalder & VossSearch peoplePRPriya RamanManager · Delivery
Onboarding
4 starters · every task has an owner and a due date
Thu 17 Sep 2026Add starter

Starters

By start date
RGRory GallagherFinance · Mon 21 Sep10/11
JIJamal IdrisDelivery · Mon 28 Sep7/11
HSHana SatoTechnology · Mon 5 Oct4/11
LWLeah WhitcombeMarketing · Mon 12 Oct2/11

Onboarding time

Offer accepted → documents complete
−50%medianHires in the two quarters after launch against the two before, measured from offer acceptance to all documents complete. Tracked per new hire, not per spreadsheet

JI Jamal Idris · checklist

Delivery · starts Mon 28 Sep · buddy Ines Duarte
7 of 111 overdue3 open
TaskOwnerDueStatus
Offer accepted and record createdElaine Firth2 SepDone
Contract signedJamal Idris4 SepDone
Bank and tax details returnedJamal Idris9 SepDone
Right-to-work documents checkedElaine Firth11 SepDone
Laptop orderedTobi Adeyemi11 SepDone
Reference two receivedElaine Firth14 SepOverdue3 days over
Buddy assignedPriya Raman15 SepDone
Accounts and email createdTobi Adeyemi16 SepDone
First-week plan writtenPriya Raman23 SepOpen
Desk and building passElaine Firth25 SepOpen
Day-one welcome bookedInes Duarte25 SepOpen
On screen

Onboarding as a tracked checklist per new hire, with an owner and a due date on every task and the overdue one visible, beside onboarding time halved from offer acceptance to documents complete.

The numbers, before and after

−50%

Onboarding time

−65%

Approval turnaround

94%

Manager adoption

Onboarding time is offer acceptance to all documents complete, median across hires in the two quarters after launch against the two before. Approval turnaround is request to decision. Manager adoption is the share of managers who approved at least one request in the platform in a given month, not the share with accounts.

Client name withheld under NDA. Figures are approximate, drawn from the engagement’s own reporting.

Introduction

The engagement

HR ran from scattered sheets and inboxes. We consolidated onboarding, leave, and people data into one platform managers use daily.

Forty people at the start of the engagement and a stated plan to reach a hundred and twenty inside a year. HR was one operations lead, three spreadsheets and a shared inbox: an arrangement that had worked at fifteen people and was audibly failing at forty. The trigger was two leave requests approved twice and one not at all, in the same two weeks.

Design & Build

How it was handled

  • Mapped the core HR workflows and role permissions

    Workflows were mapped against who actually decides, whatever the org chart said, which is how four people reporting to two came to light before the permission model was built.

  • Built approval flows for onboarding and leave

    Building this surfaced an org chart nobody had checked: four people reported to two, and the approval routes couldn't be drawn until that was settled.

  • Shipped a directory that stays current automatically

    The directory reads the same employee record everything else does, so it can't go stale: there's no separate copy for anyone to forget to update.

  • Kept it running with a managed-support retainer

    One full leave cycle ran in parallel with the spreadsheets before they were retired, instead of cutting over on a passing test suite.

01

One record per employee

A single profile that onboarding, time off, and reviews all read from, so nothing is entered twice.

The employee is one row in Postgres with everything else pointing at it through Prisma relations, so a change of surname or manager propagates on its own, with nothing to repeat in three tools. Onboarding, time off and reviews are separate flows reading one profile, which removed the class of bug where the directory and the org chart disagreed about who reported to whom.

What shipped
  • One employee row; every flow reads it through relations
  • A name or manager change propagates everywhere at once
  • Directory and org chart can't disagree, by construction
WrenfoldCalder & VossSearch peoplePRPriya RamanManager · Delivery
Ines Duarte
Senior consultant · Delivery · one record, E-0417
Thu 17 Sep 2026View time off
IDInes DuarteSenior consultant
TeamDeliveryReports toPriya RamanStarted3 Mar 2025LocationLondon officeLeave policyUK standard · 25 days a yearEmployee idE-0417

Changes to this record

Made once, read everywhere
Manager: Harry Lowe → Priya RamanOrg chart, approvals and reviews follow at once1 Jul 2026
Surname: Duarte Silva → DuarteDirectory, calendar and onboarding read the new name12 May 2026
Title: Consultant → Senior consultantDirectory and review form updated1 Apr 2026
Onboarding complete · 11 of 11Checklist closed on the start date3 Mar 2025
Record created at offer acceptanceEvery later flow points at this row17 Feb 2025

Flows reading this record

None of them keeps a copy
Onboarding11 of 11Completed 3 Mar 2025
Time off12 days left1 request with Priya · computed from policy
ReviewsNov 2026Reviewer from manager_id: Priya Raman

The employee row

PostgreSQL · related through Prisma
FieldValueRead by
employee_idE-0417Every flow · the key the rest point at
nameInes DuarteDirectory · Org chart · Reviews
manager_idPriya Raman (E-0212)Approvals · Org chart · Reviews
team_idDeliveryDirectory · Team calendar
job_titleSenior consultantDirectory · Reviews
start_date3 Mar 2025Leave balance · Onboarding
leave_policyUK standard · 25 days a yearTime-off balance, computed on read
locationLondon officeDirectory
review_cycleNovemberReviews
On screen

One record per employee: the single profile that onboarding, time off and reviews all read from, a manager change made once on 1 Jul, and the row's fields with every flow that reads each one.

WrenfoldCalder & VossSearch peoplePRPriya RamanManager · Delivery
Delivery team calendar
Four weeks from Mon 21 Sep · pending requests hatched, approved leave solid
Thu 17 Sep 2026My reports

21 Sep – 16 Oct 2026

8 people · 5 pending in view
w/c 21 Sepw/c 28 Sepw/c 5 Octw/c 12 Oct
PersonM21T22W23T24F25M28T29W30T1F2M5T6W7T8F9M12T13W14T15F16
IDInes DuarteSenior consultant3d
SMSofia MarchettiSenior consultant2d
CRCallum ReidConsultant2d
AOAisha OkaforConsultant5d
OPOwen PryceConsultant2d
BHBen HartleyAnalyst2d
MLMei Lin TanAnalyst
JIJamal IdrisStarts 28 Sep▾ first day
Approved Pending a decisionBalances computed from each person’s policy when read, never stored

ID Ines Duarte

Pending
Mon 5 – Wed 7 Oct3 working days
ApproverPriya Raman · from Ines’s reporting line
Balance · computed from policy12 days 9 daysif approved
Already offSofia Marchetti · Mon 5 – Tue 6 Oct
DeclineApprove

Also waiting on you

5 more
MLMei Lin TanMon 26 – Fri 30 Oct5d
OPOwen PryceThu 1 – Fri 2 Oct2d
AOAisha OkaforMon 12 – Fri 16 Oct5d
CRCallum ReidFri 25 Sep1d
BHBen HartleyFri 2 Oct, afternoon0.5d
02

Self-service time off

On screen

Time off as a team calendar instead of an inbox thread: pending requests hatched, approved leave solid, and the selected request showing its derived approver, its balance computed from policy and who is already off those days.

Requests, approvals, and balances handled by the people involved, with no admin in the middle.

Requests route to the approver derived from the org chart instead of a hard-coded admin, so the flow keeps working as the team doubles. Balances are computed from the accrual policy on demand, never stored and left to drift, and the calendar shows a manager who else on the team is already off before they approve. That context used to be a Slack message.

What shipped
  • Approver derived from the org chart, not hard-coded
  • Balances computed from policy, never stored and drifted
  • Team coverage shown at the point of approval
03

Role-scoped visibility

Managers see their own reports; everything else stays closed by default, not by convention.

Visibility is closed by default and opened by relationship: a manager sees their own reports because the query walks the reporting line, not because a role flag was ticked. Every scoped read resolves server-side in the same place, so there's one thing to audit instead of a permission check in each page. Sensitive fields are excluded from the query itself, never just hidden in the response.

What shipped
  • Closed by default; access derived from the reporting line
  • One server-side place resolving every scoped read
  • Sensitive fields excluded from the query, not the render
WrenfoldCalder & VossSearch peoplePRPriya RamanManager · Delivery
People
62 people across 9 teams · starters listed with everyone else
Thu 17 Sep 2026All teams

Directory

Showing 12 of 62
All 62Teams 9Starters 4My reports 8Sorted by name
PersonTeamManagerStatusProfile & leave
AOAisha OkaforConsultantDeliveryPriya RamanIn postYour report · open
BHBen HartleyAnalystDeliveryPriya RamanIn postYour report · open
CRCallum ReidConsultantDeliveryPriya RamanIn postYour report · open
EFElaine FirthOperations leadOperationsGareth VossIn postNot in your line
HLHarry LoweHead of AdvisoryAdvisoryGareth VossIn postNot in your line
IDInes DuarteSenior consultantDeliveryPriya RamanIn postYour report · open
JIJamal IdrisAnalystDeliveryPriya RamanStarts 28 SepYour report · open
MLMei Lin TanAnalystDeliveryPriya RamanIn postYour report · open
OPOwen PryceConsultantDeliveryPriya RamanIn postYour report · open
RGRory GallagherFinance assistantFinanceElaine FirthStarts 21 SepNot in your line
SMSofia MarchettiSenior consultantDeliveryPriya RamanIn postYour report · open
TATobi AdeyemiEngineerTechnologyMarcus HaleIn postNot in your line

Your reporting line

Walked on every read
PRPriya Ramanyou
IDInesSMSofiaCRCallumAOAishaOPOwenBHBenMLMeiJIJamal
Access follows manager_id, not a role flag. 8 people are open to you; the other 53 stay closed by default.

Outside your line

What the query selects
Returned Name and title Team Manager Office locationNot in the query Home address Salary Date of birth Leave balance and history
On screen

The directory as a manager sees it: 62 people across 9 teams with new hires in the same list, her eight reports open, everyone else closed, and the fields the query never selects for people outside her line.

Working inside their operation

  1. 01

    A cross-functional team of 5 worked on a time & materials basis over 15 weeks, covering Internal platform, Approval workflows, Ongoing support. We ran two-week increments, each one shippable, reviewed live before it merged. Decisions were recorded as they were made, so the reasoning survived the people who made it.

    One full leave cycle ran with the new platform and the spreadsheets side by side before the sheets were retired, which is where three accrual edge cases surfaced that no test had covered. Time and materials suited it because the permission model genuinely changed once managers started using it: the org chart turned out to have four people reporting to two.

What changed in the runbook

The bottleneck was never the forms. It was that no one could say which copy of a record was true.

Every version of the request form worked. What didn't work was three records disagreeing about who should approve it, which no form design can resolve.

Scoping permissions on day one cost less than retrofitting them after the first accidental disclosure.

The permission model was cheap to build against an empty database and would have been expensive against a populated one with a disclosure already in it.

Running one full leave cycle in parallel caught three edge cases no test had.

Tests assert what someone thought of; a real cycle asserts what actually happens, and the three cases it caught were all accrual arithmetic at year boundaries.

One request, five steps

Nobody forwards it. The record already knows who decides.

Three days of leave, followed from the moment they're asked for to the moment the team calendar changes: who holds the request at each step, and exactly what the approving manager sees. Switch steps, or use the arrow keys once a tab is focused.

Ines picks three days. The form shows her balance computed from her leave policy at that moment, never a number someone last typed into a sheet. Nothing has gone to an admin.

Who holds itPending
  1. Ines DuarteAsks, from her own account
  2. Her employee recordmanager_id → Priya Raman
  3. Priya RamanApprover, derived, not assigned
  4. Team calendar & balanceRead from the same ledger

Wed 16 Sep · 09:14 · illustrative time

What Priya Raman sees
Waiting on you5 requests · Ines’s is still being written
Ines’s draft, as she sees itMon 5 – Wed 7 Oct · 3 days · balance 12 9 if approved

Why it keeps working as the team doubles: no step names an approver. Each one reads the employee record, so a new hire, a new manager or a reorganized team changes the route by changing one row.

Architecture

From one change to every view that depends on it

Onboarding, time off and reviews are separate flows reading one profile, with role-scoped access from the first commit.

  1. 01 · Trigger
    A request or a record changeStaff and managers act for themselves, signed in through Auth.js. Nothing is routed through an admin to be retyped.
  2. 02 · Scope
    One server-side resolverEvery scoped read resolves in the same place by walking the reporting line, so there is one thing to audit, not a check per page.
  3. 03 · Engine
    Approval routes and accrual policyThe approver is derived from the org chart, never hard-coded, and balances are computed from the accrual policy on demand.
  4. 04 · State
    One employee row in PostgreSQLTeam and leave ledger relate to it through Prisma, so a surname or manager change propagates instead of being repeated.
  5. 05 · Delivery
    Role-based views in Next.jsA manager's home, the directory and the team calendar read the same record, so they can't disagree about who reports to whom.
Who can see whose record

People data, scoped before it's fetched

Closed by default, opened by relationship

A manager sees their own reports because the query walks the reporting line, not because a role flag was ticked. Everyone else stays closed by default.

One place resolves every scoped read

Scoping runs server-side in a single place instead of as a check in each page, so there's one thing to audit. It was modeled on day one, against an empty database.

Sensitive fields are never selected

Fields a viewer may not see are excluded from the query itself, so they're never in the payload for a browser to reveal.

Still running HR from spreadsheets and a shared inbox? Scope your build in 3 minutes.

Scope your build
Have a project?

Let's talk

Running a large platform, shaping a first MVP, or getting a product ready for a funding round? Tell us where you are. We'll shape the process around it, and stay with you after launch.