Profile    Mohammed Shiroz Status   Loading  
Logo
Share This
Back to blog
Filter by:
Tags
//Article title

Building an HR and CRM System: Lessons From Kate HRM

23 Aug 2025Category : Blog

About Post

An HR system sounds like a boring project until you start building one. Then you realise it touches almost everyone in the company, holds some of the most sensitive data you'll ever store, and is expected to follow rules that exist mostly in people's heads and old spreadsheets.

Kate HRM is the internal system I work on at Kate that brings HR, CRM and project management into one place. It's not my first HR system either; before Kate I built a multi-tenant SaaS HRM platform as a freelancer. So this isn't a feature tour. It's the set of lessons I'd hand to anyone about to build an internal business system like this, because most of them only become obvious once you're in the middle of it.

Why one system instead of three tools

HR, CRM and project management are usually three separate products. The reason to combine them is that they keep referring to the same things: people, clients and work.

An employee is assigned to a project. The project is for a client. The client conversation is owned by an employee who might be on leave next week. When those live in three tools, every question that crosses them ("who's covering this client while she's away?") becomes a manual lookup or a spreadsheet export.

One system with shared core records makes those questions a query. That's the real value, and it's also the first lesson.

Lesson 1: get the shared core right first

The modules are the visible part, but the foundation is a handful of shared entities: employees, departments, clients, projects, and the links between them. Every module leans on them.

Get these wrong and every module inherits the problem. A few things worth deciding early:

  • A person is not a user account. Not every employee logs in, and an account can be disabled while the employee record must stay for history. Keep them separate and linked.
  • History is part of the data. People change department, title and manager. If you only store the current value, reports about last year quietly become wrong.
  • Each module owns its own tables and talks to the core through clear relationships, not by reaching into another module's internals. That keeps the CRM from breaking when HR changes.

Lesson 2: permissions are a design problem, not a checkbox

In most apps, roles are simple: admin and user. In an HR system, the question is never just "can this person see employee records?" It's "which employees, and which fields?"

A manager may see their team's leave requests but not their personal documents. HR may see everything for employees but nothing in the sales pipeline. A project lead may see project hours but not salaries. That's three dimensions at once: the action, the scope of records, and the sensitivity of fields.

What I'd recommend:

  • Use permissions, not role checks in code. Write can('approve-leave'), never if ($user->role === 'manager'). Roles are just bundles of permissions that the business can rearrange without a deploy.
  • Scope queries centrally. Put "which records may this user see" in one place, such as a query scope or policy, so a new report or export can't forget it.
  • Treat sensitive fields separately. Personal and financial details deserve their own permission and should be excluded from API responses by default, not hidden in the UI.
  • Test the denials. The test that matters most is "this manager can't see that department". Happy paths get tested naturally. Boundaries need deliberate tests.

The lesson I'd underline: design permissions before the second module, not after the fifth. Retrofitting record-level access onto screens and reports that assumed "everyone sees everything" is far more expensive than building it in.

Lesson 3: workflows are state machines

Leave requests, approvals, client deals and project tasks all move through states: draft, submitted, approved, rejected, cancelled. The temptation is a status column and a scattering of if statements.

The better approach is to be explicit about which transitions are allowed and who may perform them. "Approved can become cancelled, but not draft." "Only the employee's manager, or HR, can approve." Once that lives in one place, every screen and API endpoint follows the same rules, and each transition can record who did it and when. That record is what you'll need when someone asks why a request was rejected.

Lesson 4: reporting is a feature, not an afterthought

For many people, the reports are the system. Managers rarely browse records one by one. They want leave balances, headcount by department, client pipeline status and project progress, filtered by date range, and exported.

  • Design the data with reports in mind. If a report needs "status on a given date", you need history, not just the current state.
  • Apply the same permission scopes to reports and exports. An export is just a very efficient way to leak data if it skips them.
  • Queue heavy exports and notify when ready, rather than making someone watch a spinner.
  • Index for the filters people actually use, usually dates and department, and check the slow query log once real data arrives.

Lesson 5: adoption beats features

An internal system competes with the old way of doing things, and the old way is familiar. The features that drive adoption are rarely the clever ones. They're the small things: a leave request that takes seconds on a phone, sensible defaults, notifications that tell people what they need to do next, and data that's correct on the first day because someone carefully migrated the old records.

The fastest way to learn what's missing is to sit with the people who use it. No design document replaces watching someone fill in a form for the first time.

If you're about to build one

  1. Model the shared core (people, clients, projects) before the modules.
  2. Keep users and employees separate, and keep history.
  3. Design permissions on three axes: action, scope and sensitive fields.
  4. Make workflows explicit state machines with an audit trail.
  5. Treat reports and exports as first-class, permission-scoped features.
  6. Ship small, watch people use it, adjust.

Have you built an internal business system? What turned out to be harder than it looked: permissions, reporting, or getting people to actually use it?

Comments (0)
Leave your review

Thanks for your valuable comments. Your comments has been updated and appreciate your getting in touch...

01. About Shiroz

Mohammed Shiroz

Hi, I'm Mohammed Shiroz, a software engineer and AI enthusiast from Sri Lanka who turns ideas into intelligent, real-world solutions. With over 9 years of hands-on experience, I currently lead real estate ERP development at Kate Group, a...

03.My Projects

04. Categories

Ready To order Your Project ?

Get in Touch
Close