Skip to content
SKSuraj Kumar

Professional services

Professional Services Resource Planning — Reference Build

Tells a services business which projects are actually profitable, using effective-dated cost rates and allocation that accounts for who is already booked.

  • Business software
  • Services
  • Planning
  • Profitability
  • Next.js
Role
Sole engineer. Rate model, capacity and allocation logic, margin calculation and the planning interface.
Work type
Self-directed build — no client
Timeline
9 weeks build effort · 2025
Status
Case study published
Client
Independent build

Build effort, not elapsed calendar time. Engagements ran alongside study and employment, so this figure is the work itself rather than the span it sat in.

Interface built in code for this case study — not a client screen capture.

01Business problem

What was actually going wrong

Agencies and consultancies know their revenue and their payroll but not which projects made money, so they keep selling the work that loses it.

Who feels it

  • Agency and consultancy owners pricing work by feel
  • Delivery managers allocating people without capacity visibility
  • Finance reconstructing project margin in spreadsheets
  • Teams overcommitted with no way to demonstrate it

A services business bills either by time or by a fixed fee. Revenue is visible in invoices and cost is visible in payroll, but the join between them — which person spent how many hours on which project at what cost — usually does not exist in a usable form. Timesheets arrive late, at the end of the month, filled in from memory, and by then the project is finished and the number is only a post-mortem.

The result is a business that cannot tell a good client from a bad one. A fixed-fee project that ran forty percent over looks the same in the bank as one that came in under, and the same scope gets quoted at the same price again. Meanwhile the team feels overloaded and nobody can say by how much, because allocation lives in a spreadsheet showing who is on what project but not how many hours that leaves.

The technically interesting part is that cost rates change. A person gets a raise in April, and a project that ran from January to June has hours at two different cost rates. Systems that store a single current rate silently rewrite the history of every past project every time someone is promoted.

02Product overview

What got built

A project and workforce system with effective-dated cost and bill rates, allocation that computes real remaining capacity, timesheets locked by period after approval, and margin per project computed from the hours as they were actually costed.

Engineering notes

  • Effective-dated cost and bill rates with cost frozen at approval
  • Capacity derived from working patterns, leave and allocations
  • Conflict detection via a weekly allocation grid, not an interval search
  • Period locking enforced on the write path

Rates are effective-dated. Every person has a series of cost rates and bill rates with start dates, and an hour is costed at the rate in force on the date it was worked. A raise in April changes the cost of May’s hours and leaves March alone, so historical project margin stays comparable and no past number gets rewritten behind anyone’s back.

Allocation is computed against capacity, never declared. A person’s available hours in a period are their working hours less leave less existing allocations, so booking someone at fifty percent when they are already at eighty is a visible conflict with the specific overlapping assignments named. The planning view answers "who can take this" instead of "who is nominally free".

Timesheets are entered against project phases and tasks with a weekly cadence, and approval locks the period. A locked period cannot be edited without a reopening action that is recorded, because a margin figure that can change after the fact is not a figure anyone can plan against.

Margin is computed per project, phase and person from the costed hours plus recorded expenses, against either time-and-materials billing or fixed-fee revenue recognised on progress. Budget consumption is tracked against the phase budget with a projection based on the current burn rate, so an overrun is visible while there is still time to act.

03Key features

What the software does, feature by feature

10 capabilities. Every one of them is deterministic software — there is no model in this build, and nothing here is described as AI.

  • 01

    Effective-dated rates

    Cost and bill rates are held as dated series, so an hour is always costed at the rate in force on the day it was worked.

  • 02

    Project structure with budgets

    Projects break into phases and tasks, each with an hours or fee budget that consumption is tracked against.

  • 03

    Capacity-aware allocation

    Available hours are working hours less leave less existing allocations, so overbooking surfaces as a named conflict, not a surprise.

  • 04

    Allocation conflict detection

    Overlapping assignments are detected across date ranges and reported with the specific projects causing the overload.

  • 05

    Weekly timesheets

    Time entered against phases and tasks with a weekly rhythm, submitted for approval and never accumulated silently.

  • 06

    Period locking

    Approval locks the period; reopening is an explicit, recorded action, because margin figures must stop moving.

  • 07

    Project margin

    Revenue against costed hours and expenses per project, phase and person, computed from the rates actually applied.

  • 08

    Utilisation reporting

    Billable against non-billable against available hours per person and team, with the definition of billable stated.

  • 09

    Change requests

    Scope changes are recorded against the project with their hours and fee impact, so overruns separate from scope growth.

  • 10

    Expenses and pass-throughs

    Project expenses with billable flags and markup, included in margin and not parked separately in accounting.

04User flow

How a person moves through it

The path from the trigger to the finished record, with each step attributed to whoever performs it — a person or the system.

  1. 01OwnerSets up the project with phases, budgets and the billing model — time and materials or fixed fee.
  2. 02Delivery managerChecks who has real capacity in the period and allocates people to phases.
  3. 03SystemComputes remaining capacity and flags any conflict with the overlapping allocations named.
  4. 04Team memberEnters weekly time against phases and tasks and submits it.
  5. 05Delivery managerApproves the timesheet, which locks the period against silent edits.
  6. 06SystemCosts each hour at the rate effective on the date worked and updates project margin.
  7. 07OwnerReviews margin by project and client, budget burn with projection, and utilisation by person.

05Architecture

How it is put together

The processing path first, then the layers it runs on, then the constraints that shaped both.

Path through the system

6 stages

  1. 01

    Plan

    Project, phases and budgets defined with a billing model.

  2. 02

    Allocate

    Capacity computed; assignments checked for overlapping conflicts.

  3. 03

    Record

    Weekly time entered against phase and task.

  4. 04

    Approve

    Submission approved and the period locked.

  5. 05

    Cost

    Hours costed at effective-dated rates; expenses included.

  6. 06

    Report

    Margin, burn projection and utilisation derived from costed hours.

Layers

Interface
Capacity planning grid by person and weekWeekly timesheet entryProject margin and burn viewAllocation conflict panelUtilisation report
Application
Effective-dated rate resolutionCapacity and conflict computation over date rangesPeriod locking rulesMargin and progress recognition
Services
Leave calendar integrationInvoice export for billingExpense captureNotification for unsubmitted time
Data
Rate series per personProjects, phases, budgets and change requestsTime entries with lock stateAllocations with date ranges

Why it is shaped this way

  • Cost is stored on the time entry at approval, resolved from the rate series and never joined at report time. That fixes the number against the rate that was actually in force and keeps historical margin stable.
  • Capacity is computed rather than stored, because leave, allocations and working patterns all change. A stored availability figure is wrong within a day.
  • Period locking is enforced on the write path, not just hidden in the interface, so an approved period cannot be modified by any route without a recorded reopening.

06Technical decisions

The choices that mattered, and what each one cost

Every decision here was contested by a reasonable alternative. The trade-off column is the part usually left out.

01

Model cost and bill rates as effective-dated series, not current values.

Why

A single current rate rewrites the cost of every past hour whenever someone is promoted. Dated series mean an hour worked in March keeps March’s cost. Without that, comparing project margin across time is meaningless.

Trade-off

Every cost calculation needs a date-aware lookup in place of a simple join, and rate changes need careful handling around already-approved periods.

02

Freeze the resolved cost onto the time entry at approval.

Why

Recomputing cost at report time makes yesterday’s margin figure change today if a rate is backdated. Freezing at approval makes reported margin stable, and a genuine correction becomes an explicit recost action with an audit entry.

Trade-off

A backdated rate correction requires deliberately recosting affected entries, which is more work than a silent recalculation and considerably safer.

03

Compute capacity from working patterns, leave and allocations instead of storing availability.

Why

Availability is a function of several things that all change independently. Deriving it means the planning grid is right the moment leave is booked, without a synchronisation step that can fail.

Trade-off

The planning grid runs a real computation per person per period, so the interval arithmetic is kept efficient and the grid is paginated by team.

04

Lock periods on approval and enforce the lock on the write path.

Why

Margin that can move retroactively cannot be acted on. Enforcing the lock server-side means no route — interface, import, or job — can edit an approved period without the recorded reopening.

Trade-off

Legitimate corrections need a reopening request, which adds friction. The friction is the feature.

05

Recognise fixed-fee revenue on measured progress, not on invoicing.

Why

Invoicing milestones rarely align with delivered effort, so margin computed against invoices swings wildly month to month and says nothing about the project. Progress-based recognition produces a margin figure that tracks reality.

Trade-off

Progress needs a defensible measure — hours against budget, or a stated percent complete — and both need review to avoid optimistic reporting.

07Challenges

What was genuinely difficult

Not the setup work. These are the problems where the first implementation was wrong and had to be reconsidered.

01

A promotion silently changed the reported margin of every completed project.

Approach

Rates became effective-dated series with a resolver that takes a work date, and the resolved cost is written onto the time entry when the period is approved. A backdated rate change no longer touches approved entries; it requires an explicit recost that records what changed and why.

Outcome

Historical project margin became stable and comparable — a precondition for using it to price the next piece of work.

02

Detecting allocation conflicts across arbitrary overlapping date ranges without a slow query per person.

Approach

Allocations are decomposed onto a weekly grid at write time, so conflict detection becomes a sum per person per week and no interval overlap search is needed. The grid stores allocated hours, and the planning view compares it against computed capacity in one pass per team.

Outcome

The planning grid renders quickly and conflicts name the specific overlapping projects — the detail a delivery manager needs in order to resolve one.

03

Timesheet compliance — the system was accurate and empty.

Approach

Entry was rebuilt around a weekly grid pre-populated from allocations, so a person confirms and adjusts instead of recalling. Submission reminders are tied to the person’s own unsubmitted weeks, and the approval queue shows managers what is missing, not only what has arrived.

Outcome

Time got entered close to when it was worked. None of the downstream numbers are worth computing without that.

08Business value

What it changes for the business

Stated qualitatively on purpose. Invented percentages are the easiest thing to put on a portfolio and the easiest thing to see through.

Operational effect

  • Answers which projects and clients are actually profitable, from hours costed at the rates that were genuinely in force.
  • Keeps historical margin stable, so past projects can be used to price new ones.
  • Makes overallocation visible before people are committed, with the conflicting assignments named.
  • Separates scope growth from overrun by recording change requests against the project.
  • Gives utilisation figures with a stated definition of billable — not a number nobody can reproduce.
  • Shows budget burn with a projection while a project can still be steered.

What would change at scale

  • Add multi-currency projects with rates and revenue held in the project currency and translation reported separately from margin.
  • Introduce scenario planning on the capacity grid, so a prospective project can be modelled against current commitments before it is won.
  • Support subcontractor cost as a distinct rate type with its own margin treatment, since pass-through resourcing behaves differently from payroll.
  • Add revenue recognition policy configuration and a period-close checklist — the point at which a services business has to satisfy its accountant.
  • Track estimate against actual at the task level to build an evidence base for future estimating instead of relying on recall.

09Interface

The screens where the work happens

Dense operational views rather than dashboards. These are used for hours at a time, so the priorities are legibility, keyboard flow and state that is never ambiguous.

Capacity grid

People by week with allocated against available hours, and overallocated cells naming the conflicting projects.

Weekly timesheet

Rows pre-populated from allocations, entered against phase and task, with the submission state visible.

Project margin

Revenue, costed hours, expenses and margin by phase, with budget burn and a projection to completion.

Utilisation

Billable, non-billable and available hours per person with the billable definition stated on the report.

The screen above is built in HTML and CSS for this case study. It reproduces the layout, states and vocabulary of the real build without exposing client data, which is why it exists rather than a screenshot. It is evidence of design and of the decisions behind it. It is not a photograph of a deployed system, and no part of it is a capture of anyone else’s product.

10Technologies

What it is built with

Chosen for the shape of the problem, not for novelty. Anything unusual is justified in the decisions section above.

Frontend
  • Next.js App Router
  • TypeScript
  • Tailwind CSS
  • Server Components
Application
  • Effective-dated rate resolution
  • Weekly allocation grid
  • Period locking
  • Progress-based recognition
Data
  • PostgreSQL
  • Rate series with date ranges
  • Time entries with frozen cost
Reporting
  • Margin by project and phase
  • Utilisation
  • Burn projection

11Technical preview

Structure, models and annotated excerpts

There is no repository link on this site. What is available instead is the module structure, the data model, the interface contracts and annotated excerpts written for this case study — enough for a technical reviewer to judge the engineering.

Technical preview

Implementation detail for this build

Selected implementation details are available for technical review: component structure, data models, architecture notes and sanitized code excerpts. Some client-specific source material stays private because of confidentiality. Enter the project access keyword if you have been given one — the same one works across every case study.

A presentation convenience, not authentication. This is a static site, so the keyword ships to your browser with the page and anyone reading the bundle can find it — worth saying plainly rather than dressing it up. Nothing confidential is stored behind it.

Inside this section

  • Module and folder structure for the build
  • Data models and the interface contracts between layers
  • 2 annotated implementation excerpts
  • Design notes covering the decisions the excerpts imply
  • The same keyword opens every case study on the site

For private client work, contact me for a walkthrough.

Next step

Need something along these lines?

Send the process, the constraints and the deadline. You will get an honest scope, an architecture sketch and a timeline before any commitment.

Email
surajk86808@gmail.com
Based in
Bengaluru, India
Working hours
IST (UTC+5:30)
Availability
Taking new engagements