Blog

I built the system a massage practice runs on

11 August 20266 min readcase-studyvanilla-jsmongodb

Studio Management System

A family massage practice runs on details.

Who worked which hour. Which session was paid in cash, card, or Twint. What each location actually earned. How many hours each employee worked so their salary can be calculated quickly. Which clients need a receipt for their complementary insurance, and which ones don't.

For years, all of that lived on paper day sheets.

Then in a spreadsheet that grew until nobody really trusted it.

I replaced it with a staff management system that the whole business now runs on: two locations, seven masseuses, and roughly a hundred sessions a week.

Here it is. Click around; it's the real application with invented data.

Studio management system β€” interactive demoOpen full screen
Loading the demo…
Sample data only β€” every customer, figure and staff name is invented.

Every name, customer and figure in the demo is generated. The production instance contains real client records, so nothing from it appears here or anywhere else public.

What it actually does

The system started with one simple goal: replace the paper day sheet.

It ended up becoming the place where the staff records the information needed to run the business.

Day sheet

Every session is recorded with its time, service, location, employee, payment method and earnings.

Cash, card and Twint are tracked separately, so the owner can see what was actually earned and where the money came from.

The system also keeps track of money that is still owed, instead of forcing everything into a payment method that hasn't happened yet.

At the end of the day, the numbers are already there.

There is no need to collect a pile of paper sheets, add everything up manually, and hope nothing was missed.

Employee hours and salary calculation

The system records how long each employee worked.

That means the owner can see their hours without going through every day's paper records again.

Previously, getting everything together for salary calculations meant going through the individual sheets and reconstructing who worked when.

Now the information is already recorded in the system and can be used directly.

The goal isn't to make payroll complicated.

It's to make the boring part disappear.

Insurance receipts

Swiss complementary insurance adds another layer of paperwork.

Some clients want a receipt for their insurance. Some don't.

There are different reasons for that. Sometimes the client doesn't need one, sometimes they want to handle it differently, and sometimes the receipt is simply not relevant to them.

The important thing is that the practice needs to know who actually needs one.

The system keeps that information with the session instead of relying on someone remembering it later.

Insurance sessions can also be tracked separately, including the insurer information needed for the paperwork.

Two locations

The practice operates from two locations.

The same system keeps the records separated by location, so the owner can see where sessions and revenue belong without maintaining separate spreadsheets.

Clients

There are around 900 client records.

They can be searched quickly, with the relevant insurance information available when needed.

Staff

The system keeps staff information, working hours, holidays, absences and one off shifts in one place.

There is also an NFC clock in that works from a phone tap, so working time doesn't have to be reconstructed afterward.

Gift vouchers

Gift vouchers have their own sequential register.

That sounds like a small thing until you've used a paper register and realise that missing or duplicated numbers become surprisingly annoying to track.

Reports

Monthly and yearly figures can be generated without manually rebuilding them from the day sheets.

The reports can also be emailed automatically.

The biggest difference is what happens at the end of the day

Before this system, finishing the day's paperwork could take a whole day of its own.

Someone had to gather the paper sheets, check that every session was recorded, work out the cash total, compare it with what was actually in the register, check the other payment methods, work out everyone's hours, and figure out which clients needed insurance receipts.

It wasn't difficult work.

It was just a lot of small checks that all had to be done correctly.

And because the information was spread across pieces of paper, mistakes were difficult to find.

A missing session meant finding the right sheet.

A cash total that didn't match meant going back through the individual payments.

Figuring out an employee's hours meant adding up their working days.

Finding out who needed an insurance receipt meant remembering what had happened when the appointment was made.

Now most of that information is recorded as the work happens.

The system doesn't eliminate the work the practice actually needs to do.

It eliminates the work of reconstructing what already happened.

The month view

One of the screens that came out of this was the monthly overview.

The owner often needs a simple answer to a simple question:

"How much did each person earn this month?"

Instead of opening every individual day sheet, the month view puts the days down the left and the employees across the top.

Each cell can show earnings, sessions worked, or hours.

Monthly totals are shown at the bottom, and individual days can be opened directly.

It is deliberately simple.

The point isn't to build an impressive analytics dashboard.

The point is to answer the questions that used to require going through thirty or more pieces of paper.

Why I built it this way

The staff tracker is deliberately simple: vanilla JavaScript, no framework, no build step.

The data is stored in MongoDB Atlas, with serverless functions handling authentication and persistence.

Everything else happens in the browser.

That was a deliberate choice.

This is business software for a small practice, not a product that needs a large engineering team.

It needs to be understandable, dependable, and maintainable when I'm not around.

There is value in being able to open the code, find the relevant file, and change something without first understanding a framework, a build pipeline, or a complicated deployment setup.

The system is only in its second month, so it is still early.

But the important part is already working: information that used to be scattered across paper is now recorded once and available wherever the practice needs it.

What I learned building it

The most useful thing I learned wasn't technical.

It was how much time disappears into administrative work that nobody thinks of as a real task.

The practice didn't need a complicated business platform.

They needed to know:

Who worked?

How long did they work?

What did we earn?

Where did the money come from?

Which clients need insurance receipts?

What happened at each location?

And can we get those answers without spending a day going through paper?

Those are simple questions.

The hard part was making sure the answers were recorded once, consistently, and available when someone needed them.

That is what this system is for.