RB · Access Control
RBAC & Organization Hierarchy
Who can do what (roles), and who can see/manage whom (hierarchy from Top Management to Users). Built on .NET + SQL Server with policy-based authorization and automatic data scoping.
R
Role
Determines what actions a user can perform — a set of fine-grained permissions.
H
Hierarchy / scope
Determines which records a user can see and act on — driven by their position in the tree.
1 · Organization hierarchy
TOP MANAGEMENTDirector / CEO · scope ALL · escalation L2
Sales MgrL1 · team
Purchase MgrL1 · team
Production MgrL1 · team
QA MgrL1 · team
Logistics MgrL1 · team
Team Leadoptional · single team
Sales Repsown + assigned
Purchase Staffassigned
Production Staffassigned
QA Staffassigned
Logistics Staffassigned
External · Client / Buyer → portal, own deals only
Technical · System Administrator → users/roles/settings
The tree is a self-referencing
manager_id on User. A person sees their own
subtree; the escalation chain walks the same links:
User → Manager (L1) → Top Management (L2).2 · Roles
| Role | Purpose | Data scope | Escalation |
|---|---|---|---|
| System Administrator | Manage users, roles, permissions, settings | ALL (admin) | — |
| Top Management | Org-wide oversight, high-value approvals, KPIs | ALL | L2 (final) |
| Manager | Approve leads/assignments, manage team, team KPIs | DEPARTMENT | L1 |
| Team Lead (optional) | Assign & coordinate within one team | TEAM | — |
| Sales Rep | Own leads → opportunities → quotes → deals | OWN + ASSIGNED | raises |
| Team Member | Act on items routed to their team (Purchase/Prod/QA/Logistics) | ASSIGNED | raises |
| Client (Buyer) | External self-service | PORTAL | — |
A user may hold more than one role (e.g. a Sales Manager is both Manager and Sales Rep).
3 · Permission matrix
| Capability | SysAdmin | Top Mgmt | Manager | Team Lead | Sales Rep | Team Member | Client |
|---|---|---|---|---|---|---|---|
| Manage users / roles | ✓ | — | — | — | — | — | — |
| System configuration | ✓ | — | — | — | — | — | — |
| Create / edit lead | — | ✓ | ✓ | ✓ | ✓ | — | — |
| Approve lead & assign | — | ✓ | ✓ | ✓* | — | — | — |
| Manage own deal (lead→contract) | — | ✓ | ✓ | ✓ | ✓ | — | — |
| Add pricing (quotation) | — | — | ✓ | ✓ | — | ✓ | — |
| Prepare / inspect / dispatch sample | — | — | ✓ | ✓ | — | ✓ | — |
| Create contract / send to sign | — | ✓ | ✓ | — | ✓ | — | — |
| Post-sales ops | — | ✓ | ✓ | ✓ | — | ✓ | — |
| Approve campaigns / templates | — | ✓ | ✓ | — | — | — | — |
| View reports | All | All | Team | Team | Own | Own | — |
| View deals | All | All | Subtree | Team | Own+asgn | Assigned | Own only |
| Buyer portal access | — | — | — | — | — | — | ✓ |
* Team Lead approval is optional / limited and configurable.
4 · Product / service based access (lead → team routing)
Beyond hierarchy, team access to a deal is driven by the products / services selected on the lead. When a lead is generated, every team responsible for those products/services automatically gains access.
Lead created → products / services selected → ProductTeamMap → responsible teams gain access
(+ appear in their work queue)
(+ appear in their work queue)
- Each Product / Service maps to one or more responsible teams (e.g. Product A → Production + QA + Purchase)
- The deal carries its selected products/services (
DealProduct) - A user sees a deal when their role/hierarchy scope allows it or a selected product/service maps to their team
- Routes the right Purchase / Production / QA / Logistics teams onto the deal from creation
Backing tables:
Product · ProductTeamMap · DealProduct.
An attribute-based layer on top of role + hierarchy; the widest applicable rule grants access, and every access is logged.5 · Implementation on .NET + SQL Server
- Authentication: ASP.NET Core Identity (hashing, lockout, optional 2FA)
- Authorization: policy-based —
[Authorize(Policy="Quote.AddPricing")]backed by permission claims in the JWT; a custom handler checks the permission code - Roles & permissions in DB:
Role·Permission·RolePermission·UserRole(seeded per module) - Hierarchy:
User.manager_idself-reference; subtree via SQL Server recursive CTE (or cached closure table) - Data scoping: EF Core global query filters apply scope automatically to every query
- Defense in depth: optional SQL Server Row-Level Security under the app filters
- Audit: permission-relevant actions land in
ActivityLog
| New entity | Key fields |
|---|---|
| Role | id · name · description · is_system |
| Permission | id · code (e.g. Quote.AddPricing) · module · description |
| RolePermission | role_id · permission_id |
| UserRole | user_id · role_id |
| User (additions) | manager_id (self-ref) · team_id · data_scope |
| Product / Service | name · type · category · raw_materials (BOM) · active |
| ProductTeamMap | product_id · owner_team (responsible team) |
| DealProduct | deal_id · product_id (selected on the lead → routes team access) |
Delivery: RBAC + hierarchy are foundational and land in Phase 1, before the workflow
modules, so every module inherits access control and data scoping from day one.