At a Glance
Owner: Sysadmin / Product Admin · Table:tb_department_user· Used by: PR and SR approval routing, RBAC scope, cost-centre reporting · User↔department membership pivot —is_hod = truemarks the Head of Department whose approval is required on departmental requisitions.
department-user is the user↔department membership pivot: it declares that a given access-control/user belongs to a given master-data/department. A user may belong to multiple departments; each membership row is independent. The boolean flag is_hod marks the Head of Department for that specific assignment — at most one HOD per department is enforced by the application.
The HOD flag drives downstream workflow logic: when a purchase-request or store-requisition is submitted by a user whose requesting department has an HOD, the approval pipeline routes a review step to that HOD. Without a row here a user is invisible to departmental approval routing and cost-centre reports.
Maintained by Sysadmin (user-to-department assignments, HOD flag). Read by PR/SR approval workflows, RBAC scope resolvers, and reporting.
| Task | Where | Notes |
|---|---|---|
| Assign a user to a department | User-admin screen → Department tab → Add | Pick department; is_hod defaults false |
| Designate as Head of Department | Same screen → toggle is_hod |
At most one HOD per department (app invariant) |
| Reassign HOD | Toggle off old, toggle on new | Historical approvals keep the original signer |
| Remove user from department | Soft-delete the row | Open PR/SR steps referencing this user are unaffected; future routing will find no HOD |
| List all HODs for a department | Query tb_department_user WHERE is_hod = true AND deleted_at IS NULL |
Use for audit or workflow-config verification |
| Symptom | Cause | Action |
|---|---|---|
| "Duplicate department assignment" | (department_id, user_id) unique constraint on non-deleted row |
Remove the existing row first, or soft-delete and re-add |
| Workflow cannot resolve HOD | No is_hod = true row for the department |
Set one user as HOD in the user-admin Department tab |
| Multiple HOD rows for same department | Application invariant violated | Run a maintenance check; clear extra is_hod = true rows |
| Approved step shows removed user | Past approval steps capture the signer at time of action | Expected — HOD change is not retroactive |
is_hod = true), but each department should have at most one HOD.tb_department_user rows can still log in and hold application roles, but PR/SR approval routing will find no HOD resolution path through them.Source: tenant schema (packages/prisma-shared-schema-tenant/prisma/schema.prisma).
tb_department_user| Field | Prisma Type | Nullable | Description |
|---|---|---|---|
id |
String @db.Uuid |
No | Primary key. |
user_id |
String @db.Uuid |
No | FK to platform tb_user. |
department_id |
String @db.Uuid |
No | FK to tb_department. |
is_hod |
Boolean? |
Yes | Default false. true = Head of Department for this assignment. |
note |
String? @db.VarChar |
Yes | Free-text annotation. |
info |
Json? |
Yes | Unstructured metadata. |
dimension |
Json? |
Yes | Dimensional metadata. |
doc_version |
Decimal |
No | Default 0. Optimistic concurrency token. |
| Audit columns | — | Yes | created_at, created_by_id, updated_at, updated_by_id, deleted_at, deleted_by_id. |
Constraints: @@unique([department_id, user_id]) map department_user_u. FK tb_department_user.department_id → tb_department.id onDelete: NoAction, onUpdate: NoAction. Indexes on user_id, department_id, and a partial index on (department_id, is_hod) WHERE deleted_at IS NULL AND is_hod = true.
(department_id, user_id) row per combination — the unique constraint prevents duplicate assignments.is_hod = true row per department — application-enforced; toggling a new HOD should clear the previous HOD flag.is_hod = true grants automatic approval authority within that department for PR and SR workflow steps routed to the HOD role type.is_hod.deleted_at) to preserve audit. Active membership filter requires deleted_at IS NULL.onDelete: NoAction — deleting a department with active user rows is blocked at the DB level; deactivate or reassign users first.tb_department_user in its Data Model section.tb_department_user for departmental review steps.tb_user_tb_business_unit); BU membership gates entry; department membership scopes approval routing inside the BU.../carmen-turborepo-backend-v2/packages/prisma-shared-schema-tenant/prisma/schema.prisma — tb_department_user (lines ~2345-2366).../carmen/docs/app/system-administration/user-management/DD-user-management.md — tb_department_user entity detail and HOD index definitions.../carmen/docs/app/system-administration/user-management/BR-user-management.md — BR-002: HOD Designation business rule.../carmen-turborepo-frontend/apps/web/app/(app)/configuration/department/.