Case study · Al-Raddawi ERP

A permission model built around a real company

Al-Raddawi Contracting & Oil Services is a Syrian contractor working since 1997 across oil and gas, power and infrastructure. I designed and built the internal management system for its teams.

Role
Design and full-stack development, as the company's IT Manager
Client
Al-Raddawi Contracting & Oil Services
Type
Internal management system
The organizational unit workspace of the Al-Raddawi ERP in dark mode
The organizational workspace: every unit with its employees, child units, manager and the services it offers.

The problem

The company runs many departments and advisory units side by side: accounting and budgeting, human resources, general services, cost control, tax advisory, payroll and social insurance, and more. Each has its own manager, its own people and its own services.

A plain role system answers one question: what can this person do? A company like this needs a second answer as well: where can they do it? An HR clerk may view employee records, but only for the units they actually serve. And nobody should ever end up with company-wide access by accident.

Architecture

A Vue 3 single-page app talks to an ASP.NET Core API on .NET 8. Every request passes through authentication, then the permission and scope engine, before it reaches the business logic and SQL Server through Entity Framework Core.

Architecture: Vue 3 single-page app calls an ASP.NET Core API on .NET 8, which checks permissions and scope, then reads and writes SQL Server through Entity Framework Core. Browser Vue 3 SPAPinia · PrimeVueTailwind · ViteAR / EN · RTL ASP.NET Core · .NET 8 Auth + roles Permission + scope engine Org units · services Data EF CoreSQL Servermigrations Axios · JSON LINQ

Two layers of permission

Access is decided in two layers that never mix their jobs:

  1. Action permissions come from roles and answer what: view employees, approve an advance, send a general message.
  2. Scope assignments answer where. They attach to one specific account or to everyone in a role group, and limit an existing permission to chosen units.

Three rules the engine never breaks. A scope assignment never grants a new action, it only narrows one that already exists. An explicit deny always wins over any allow. And company-wide access is never implicit: it has to be granted on purpose.

In simplified form, every check reads like this:

bool CanAccess(User user, string action, Unit target)
{
    if (Denies(user, action, target))      return false; // explicit deny wins
    if (!HasAction(user, action))          return false; // what
    if (!ScopeCovers(user, action, target)) return false; // where
    return true;
}
The scope assignments screen of the Al-Raddawi ERP
Scope assignments: pick an account or a role group, then choose which of its existing permissions to scope.

The organization as data

Departments, advisory units and units live in one tree. Each node knows its employees, its child units and its manager, and publishes the services other people can request from it, such as employee advances, general messages, or direct and indirect cost entries. The same tree drives the scope engine, so permissions follow the real structure of the company.

The system also supports an acting general manager, so authority can be delegated cleanly when the general manager is away.

Details that matter to the people using it

The Al-Raddawi ERP sign-in screen
Secure sign-in for Al-Raddawi teams.

Stack

C# / .NET 8ASP.NET CoreEntity Framework CoreSQL ServerVue.js 3PiniaPrimeVueTailwind CSSViteAxios

Need a system shaped around how your company actually works? I build them, and I can run the servers they live on.

Talk to me on LinkedIn