Day#6: Building a Flexible Group Structure with NestJS and TypeORM

TL;DR: I introduced a generic group model into the backend to handle dynamic user-to-organization assignments and relationships. Users can now belong to multiple groups with typed roles, and groups themselves can be structured hierarchically.

mariusz
mariusz
20 posts
2 followers

I needed a model that supports:

  • assigning users to multiple units in different capacities,
  • building relationships between those units (e.g. team → department → region),
  • and doing all of this without hardcoding business logic into roles.

To achieve that, I introduced three core entities: Group, GroupMembership, and GroupRelation.


Group

Each logical unit is represented by a Group. This can be anything from a business entity to a regional container.

{
  "id": "unit-1",
  "name": "Unit One",
  "type": "office"
}
{
  "id": "region-XYZ",
  "name": "Region XYZ",
  "type": "region"
}

GroupMembership

Users can belong to many groups with different roles. Instead of using string-based roles, I linked each membership to a partnerTypeId, which maps to a normalized list of user types.

{
  "userId": "user-123",
  "groupId": "unit-1",
  "partnerTypeId": "manager"
}
{
  "userId": "user-123",
  "groupId": "region-XYZ",
  "partnerTypeId": "secret_agent"
}

This allows a single user to act as an „manager” in one group and an „secret_agent” in another — and nothing prevents them from being a „salesman” elsewhere.


GroupRelation

Groups can be connected to each other using GroupRelation. These relationships define which groups are composed of others — like regions composed of agencies.

{
  "parentGroupId": "region-XYZ",
  "childGroupId": "unit-1",
  "relationType": "contains"
}
{
  "parentGroupId": "region-XYZ",
  "childGroupId": "unit-3",
  "relationType": "contains"
}

This way, I can build both strict hierarchies (e.g. one region → many units) and overlapping supervision models (e.g. one manager oversees multiple non-adjacent units).


Example structure

Here’s how it might look in practice:

  • user-123 belongs to:
  • unit-1 as salesman
  • unit-3 as manager
  • manager-2 is assigned to:
  • unit-1, unit-2, unit-4 as manager
  • manager-1 is superior to manager-2 and directly manages unit-4 and unit-5
  • All three units (unit-1, unit-3, unit-5) are grouped into region-XYZ, managed by manager-4

This model is flexible enough to represent chains of command, delegated authority, and overlapping jurisdictions — all without rewriting access rules for every role.


Under the hood

  • Entities are modeled with TypeORM
  • Swagger documents every DTO and endpoint
  • All controllers are RBAC-protected with @RolesGuard and @ApiBearerAuth

This lays the foundation for scoped permission checks, UI filtering based on user position, and a consistent way to resolve access paths dynamically.

+ flexible group logic with nested structure
+ typed roles via reference table
+ ready for context-based access rules

📦 Released as @tin/api@0.3.0 on 📅 June 10, 2025


Opublikowano

w

,

przez

Komentarze

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *