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.
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-123belongs to:unit-1as salesmanunit-3as managermanager-2is assigned to:unit-1,unit-2,unit-4as managermanager-1is superior tomanager-2and directly managesunit-4andunit-5- All three units (
unit-1,unit-3,unit-5) are grouped intoregion-XYZ, managed bymanager-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
@RolesGuardand@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

Dodaj komentarz