# RBAC to Module-Based Permission System Migration Guide

## Overview

This guide explains how to migrate your POS System Backend from **RBAC (Role-Based Access Control)** to a **Module-Based Permission System** where Super Admin can control exactly which modules and features each user can access.

---

## What is the New Permission System?

### Current RBAC (Role-Based Access Control)
- Access decisions are based on **user roles** (Admin, Manager, Cashier, etc.)
- Simple but limited
- All users with same role have same permissions
- **Limitation**: Cannot give custom permissions to individual users

### New Module-Based Permission System
- **Super Admin** has complete control over the entire POS system
- Super Admin can assign **specific modules** to each user when creating/editing them
- Super Admin can grant **granular permissions** within each module
- Examples:
  - User A: Can access **Cash Out** only (not Cash In)
  - User B: Can **view** Inventory but cannot **edit**
  - User C: Can create Orders but cannot delete them
- **Advantage**: Complete flexibility - each user gets exactly the permissions they need

---

## Current RBAC Implementation

Your system likely has:
- **User Models** with role fields (Admin, Manager, Cashier)
- **Middleware** checking user roles
- **Route Protection** based on roles

Example RBAC check:
```javascript
// Current approach
if (req.user.role === 'Admin' || req.user.role === 'Manager') {
  // Allow access
}
```

---

## Available Modules in POS System

Your POS system has these main modules:
1. **Users Management** - Create, edit, delete users
2. **Products/Inventory** - Manage products, categories, stock
3. **Orders** - Create, view, manage customer orders
4. **Bills** - Generate and manage bills
5. **Cash In** - Record incoming cash transactions
6. **Cash Out** - Record outgoing cash transactions/expenses
7. **Categories** - Manage product categories
8. **Company Details** - Manage company information
9. **Reports** - View sales reports, analytics

---

## Migration Steps to Module-Based Permission System

### Step 1: Update User Model

Add module-based permissions to the User model:

```javascript
// Modles/usersModel.js

const userSchema = new Schema({
  name: {
    type: String,
    required: true
  },
  email: {
    type: String,
    required: true,
    unique: true
  },Permission Checker Utility

Create a utility to check user permissions:

```javascript
// utils/PermissionChecker.js

class PermissionChecker {
  /**
   * Check if user has access to a specific module
   * @param {Object} user - User object with permissions
   * @param {String} module - Module name (e.g., 'products', 'cashIn')
   * @returns {Boolean}
   */
  static hasModuleAccess(user, module) {
    // SuperAdmin can access everything
    if (user.role === 'SuperAdmin') return true;
    
    // Check if module exists in user permissions
    if (!user.permissions || !user.permissions[module]) return false;
    
    // Check if user has access to this module
    return user.permissions[module].canAccess === true;
  }

  /**
   * Check if user can perform specific action on module
   * @param {Object} user - User object
   * @param {String} module - Module name
   * @param {String} action - Action to perform (canCreate, canEdit, canDelete, canView)
   * @returns {Boolean}
   */
  static canPerformAction(user, module, action) {
    // SuperAdmin can do everything
    if (user.role === 'SuperAdmin') return true;
    
    // Check module access first
    if (!this.hasModuleAccess(user, module)) return false;
    
    // Check specific action permission
    if (!user.permissions[module][action]) return false;
    
    return user.permissions[module][action] === true;
  }

  /**
   * Check multiple permissions at once
   * @param {Object} user - User object
   * @param {Array} requiredPermissions - Array of {module, action} objects
   * @param {String} logic - 'AND' (all required) or 'OR' (at least one)
   * @returns {Boolean}
   */
  static checkMultiple(user, requiredPermissions, logic = 'AND') {
    if (user.role === 'SuperAdmin') return true;
    
    if (logic === 'AND') {
      return requiredPermissions.every(perm =>
        this.canPerformAction(user, perm.module, perm.action)
      );
    } else {
      return requiredPermissions.some(perm =>
        this.canPerformAction(user, perm.module, perm.action)
      );
    }
  }

  /**
   * Get list of accessible modules for a user
   * @param {Object} user - User object
   * @returns {Array} - Array of module names user can access
   */
  static getAccessibleModules(user) {
    if (user.role === 'SuperAdmin') {
      return ['users', 'products', 'orders', 'bills', 'cashIn', 'cashOut', 'categories', 'company', 'reports'];
    }
    
    const modules = [];
    if (user.permissions) {
      Object.keys(user.permissions).forEach(module => {
        if (user.permissions[module].canAccess) {
          modules.push(module);
        }
      });
    }
    return modules;
  }
}

module.exports = PermissionChecker
    reports: {
      canAccess: { type: Boolean, default: false },
      canView: { type: Boolean, default: false },
      canExport: { type: Boolean, default: false }
    }
  },
  
  // Additional user info
  createdBy: {
    type: mongoose.Schema.ObjectId,
    ref: 'User'
  },
  createdAt: {
    type: Date,
    default: Date.now
  }
});

// Pre-save hook: SuperAdmin gets all permissions automatically
userSchema.pre('save', function(next) {
  if (this.role === 'SuperAdmin') {
    // Grant all permissions to SuperAdmin
    const modules = ['users', 'products', 'orders', 'bills', 'cashIn', 'cashOut', 'categories', 'company', 'reports'];
    
    modules.forEach(module => {
      if (this.permissions[module]) {
        Object.keys(this.permissions[module]).forEach(permission => {
          this.permissions[module][permission] = true;
        });
      }
    });
  }
  next();
});

module.exports = mongoose.model('User', userSchema);
```

### Step 2: Create ARBAC Policy Engine

Create a new utility file for ARBAC policy evaluation:

```javascript
// utils/ARBAC.js

class ABRACPolicyEngine {
  /**
   * Evaluate access based on attributes
   * @param {Object} userAttributes - User's attributes
   * @param {Object} requiredAttributes - Required attributes for access
   * @param {String} policy - Policy logic (AND, OR)
   * @returns {Boolean}
   */
  static evaluatePolicy(userAttributes, requiredAttributes, policy = 'AND') {
    if (policy === 'AND') {
      return Object.keys(requiredAttributes).every(
        key => userAttributes[key] === requiredAttributes[key] || 
               userAttributes[key] >= requiredAttributes[key]
      );
    }
    
    if (policy === 'OR') {
      return Object.keys(requiredAttributes).some(
        key => userAttributes[key] === requiredAttributes[key] ||
               userAttributes[key] >= requiredAttributes[key]
      );
    }
    
    return false;
  }

  /**
   * Check if user can perform action on resource
   * @param {Object} user - User object
   * @param {String} action - Action to perform (read, write, delete)
   * @param {Object} resource - Resource being accessed
   * @returns {Boolean}
   */
  static canAccess(user, action, resource) {
    const userAttrs = user.attributes;
    
    // Define policies for different actions
    const policies = {
      'createOrder': {
        required: { canApproveOrders: true, accessLevel: 2 },
        policy: 'AND'
      },
      'manageCash': {
        required: { canManageCash: true, department: 'Finance' },
        policy: 'AND'
      },
      'generateReport': {
        required: { canGenerateReports: true, accessLevel: 3 },
        policy: 'AND'
      },
      'viewInventory': {
        required: { canAccessInventory: true },
        policy: 'OR'
      }
    };

    const actionPolicy = policies[action];
    if (!actionPolicy) return false;

    return this.evaluatePolicy(
      userAttrs,
      actionPolicy.required,
      actionPolicy.policy
    );
  }

  /**
   * Check transaction limit
   */
  static isWithinTransactionLimit(user, amount) {
    return amount <Permission Middleware

Create middleware to protect routes based on module permissions:

```javascript
// Controllers/permissionMiddleware.js

const CatchAsync = require('../utils/CatchAsync');
const AppError = require('../utils/AppError');
const PermissionChecker = require('../utils/PermissionChecker');

/**
 * Check if user has access to a module
 * @param {String} module - Module name (products, cashIn, cashOut, etc.)
 */
exports.checkModuleAccess = (module) => {
  return CatchAsync(async (req, res, next) => {
    const user = req.user;

    if (!user) {
      return next(new AppError('You are not logged in', 401));
    }

    // Check module access
    if (!PermissionChecker.hasModuleAccess(user, module)) {
      return next(
        new AppError(
          `You do not have access to the ${module} module`,
          403
        )
      );
    }

    next();
  });
};

/**
 * Check if user can perform specific action
 * @param {String} module - Module name
 * @param {String} action - Action (canCreate, canEdit, canDelete, canView)
 */
exports.checkPermission = (module, action) => {
  return CatchAsync(async (req, res, next) => {
    const user = req.user;

    if (!user) {
      return next(new AppError('You are not logged in', 401));
    }

    // Check if user can perform this action
    if (!PermissionChecker.canPerformAction(user, module, action)) {
      return next(
        new AppError(
          `You do not have permission to ${action} in ${module} module`,
          403
        )
      );
    }

    next();
  });
};

/**
 * Restrict to SuperAdmin only
 */
exports.restrictToSuperAdmin = CatchAsync(async (req, res, next) => {
  if (req.user.role !== 'SuperAdmin') {
    return next(permission checks:

```javascript
// Routers/ordersRouter.js (Example)

const express = require('express');
const router = express.Router();
const { protect } = require('../Controllers/authController');
const { checkModuleAccess, checkPermission } = require('../Controllers/permissionMiddleware');
const ordersController = require('../Controllers/ordersController');

// OLD RBAC approach:
// router.post('/', protect, restrictTo('Admin', 'Manager'), ordersController.createOrder);

// NEW Permission-Based approach:
router.post(
  '/',
  protect,
  checkModuleAccess('orders'),     // Check if user can access orders module
  checkPermission('orders', 'canCreate'),  // Check if user can create orders
  ordersController.createOrder
);

router.get(
  '/',
  protect,
  checkModuleAccess('orders'),
  checkPermission('orders', 'canView'),
  ordersController.getAllOrders
);

router.patch(
  '/:id',
  protect,
  checkModuleAccess('orders'),
  checkPermission('orders', 'canEdit'),
  ordersController.updateOrder
);

router.delete(
  '/:id',
  protect,
  checkModuleAccess('orders'),
  checkPermission('Auth Controller for User Management

Super Admin should be able to create users and assign permissions:

```javascript
// Controllers/authController.js

const User = require('../Modles/usersModel');
const CatchAsync = require('../utils/CatchAsync');
const AppError = require('../utils/AppError');
const PermissionChecker = require('../utils/PermissionChecker');

/**
 * Create new user (Only SuperAdmin)
 * Super Admin assigns permissions when creating user
 */
exports.createUser = CatchAsync(async (req, res, next) => {
  const { name, email, password, permissions } = req.body;

  // Only SuperAdmin can create users
  if (req.user.role !== 'SuperAdmin') {
    return next(new AppError('Only Super Admin can create users', 403));
  }

  // Create new user with specified permissions
  const newUser = await User.create({
    name,
    email,
    password,
    role: 'User',
    permissions: permissions || {}, // Super Admin provides permissions
    createdBy: req.user._id
  });

  res.status(2s with Permissions

### Example 1: Super Admin
```javascript
{
  _id: "admin001",
  name: "Super Admin",
  email: "admin@possystem.com",
  role: "SuperAdmin",
  permissions: {
    // SuperAdmin has ALL permissions automatically
    // (handled by pre-save hook in model)
  }
}
```

### Example 2: Cashier (Can only do Cash Out, View Products)
```javascript
{
  _id: "user001",
  name: "John Doe",
  email: "john@store.com",
  role: "User",
  pHow Super Admin Assigns Permissions

### Creating a User with Specific Permissions

When Super Admin creates a user, they send a request like this:

```javascript
// POST /api/users/create
{
  "name": "New Employee",
  "email": "employee@store.com",
  "password": "SecurePass123",
  "permissions": {
    "cashOut": {
      "canAccess": true,
      "canCreate": true,
      "canView": true,
      "canDelete": false
    },
    "products": {
      "canAccess": true,
      "canCreate": false,
      "canEdit": false,
      "canDelete": false,
      "canView": true
    }
    // Other modules default to false
  }
}
```

### Frontend Permission Selection (Example UI)

```javascript
// Frontend component for Super Admin to assign permissions

function UserPermissionForm() {
  const [permissions, setPermissions] = useState({
    cashIn: { canAccess: false, canCreate: false, canView: false },
    cashOut: { canAccess: false, canCreate: false, canView: false },
    products: { canAccess: false, canCreate: false, canEdit: false, canDelete: false, canView: false },
    orders: { canAccess: false, canCreate: false, canEdit: false, canDelete: false, canView: false },
    // ... other modules
  }Complete Route Setup Example

```javascript
// Routers/usersRouter.js

const express = require('express');
const router = express.Router();
const { protect, createUser, updateUserPermissions, getMyPermissions } = require('../Controllers/authController');
const { restrictToSuperAdmin } = require('../Controllers/permissionMiddleware');

// User login/signup (public)
router.post('/login', authController.login);

// Get my permissions (authenticated users)
router.get('/me/permissions', protect, getMyPermissions);
Permission System

```javascript
// __tests__/PermissionChecker.test.js

const PermissionChecker = require('../utils/PermissionChecker');

describe('Permission Checker', () => {
  const mockUser = {
    role: 'User',
    permissions: {
      cashOut: {
        canAccess: true,
        canCreate: true,
        canView: true,
        canDelete: false
      },
      cashIn: {
        canAccess: false,
        canCreate: false,
        canView: false
      },
      products: {
        canAccess: true,
        canCreate: false,
        canEdit: false,
        canDelete: false,
        canView: true
      }
    }
  };

  const superAdmin = {
    role: 'SuperAdmin',
    permissions: {}
  };

  test('Should allow user to access cashOut module', () => {
    const hasAccess = PermissionChecker.hasModuleAccess(mockUser, 'cashOut');
    expect(hasAccess).toBe(true);
  });

  test('Should deny user access to cashIn module', () => {
    const hasAccess = PermissionChecker.hasModuleAccess(mockUser, 'cashIn');
    expect(hasAccess).toBe(false);
  });

  test('Should allow user to create cash out', () => {
    const canCreate = PermissionChecker.canPerformAction(mockUser, 'cashOut', 'canCreate');
    expect(canCreate).toBe(true);
  });

  test('Should deny user to delete cash out', () => {
    const canDelete = PermissionChecker.canPerformAction(mockUser, 'cashOut', 'canDelete');
    expect(canDelete).toBe(false);
  });

  test('Should allow user to view products but not edit', () => {
    const canView = PermissionChecker.canPerformAction(mockUser, 'products', 'canView');
    const canEdit = PermissionChecker.canPerformAction(mockUser, 'products', 'canEdit');
    
    expect(canView).toBe(true);
    expect(canEdit).toBe(false);
  });

  test('SuperAdmin should have access to everything', () => {
    const hasAccessCashIn = PermissionChecker.hasModuleAccess(superAdmin, 'cashIn');
    const hasAccessCashOut = PermissionChecker.hasModuleAccess(superAdmin, 'cashOut');
    const canCreate = PermissionChecker.canPerformAction(superAdmin, 'products', 'canCreate');
    
    expect(hasAccessCashIn).toBe(true);
    expect(hasAccessCashOut).toBe(true);
    expect(canCreate).toBe(true);
  });

  test('Should get accessible modules for user', () => {
    const modules = PermissionChecker.getAccessibleModules(mockUser);
    expect(modules).toContain('cashOut');
    expect(modules).toContain('products');
    expect(modules).not.toContain('cashIn'
        </label>
        <label>
          <input type="checkbox" onChange={(e) => updatePermission('cashOut', 'canView', e.target.checked)} />
          Can View Cash Out Records
        </label>
      </div>

      {/* Products Module */}
      <div>
        <h4>Products/Inventory</h4>
        <label>
          <input type="checkbox" onChange={(e) => updatePermission('products', 'canAccess', e.target.checked)} />
          Can Access Module
        </label>
        <label>
          <input type="checkbox" onChange={(e) => updatePermission('products', 'canView', e.target.checked)} />
          Can View Products
        </label>
        <label>
          <input type="checkbox" onChange={(e) => updatePermission('products', 'canEdit', e.target.checked)} />
          Can Edit Inventory
        </label>
      </div>
      
      {/* Repeat for all modules */}
    </div>
  email: "jane@store.com",
  role: "User",
  permissions: {
    products: {
      canAccess: true,
      canCreate: true,
      canEdit: true,   // Can edit inventory
      canDelete: true,
      canView: true
    },
    categories: {
      canAccess: true,
      canCreate: true,
      canEdit: true,
      canDelete: true,
      canView: true
    },
    cashIn: {
      canAccess: false,  // NO cash operations
      canCreate: false,
      canView: false
    },
    cashOut: {
      canAccess: false,
      canCreate: false,
      canView: false
    },
    reports: {
      canAccess: true,
      canView: true,
      canExport: false
    }
  }
}
```

### Example 4: Accountant (Can view everything, Cash In/Out, Reports)
```javascript
{
  _id: "user003",
  name: "Mike Johnson",
  email: "mike@store.com",
  role: "User",
  permissions: {
    cashIn: {
      canAccess: true,
      canCreateModule-Based Permission System Over RBAC

| Feature | RBAC | Module-Based Permissions |
|---------|------|--------------------------|
| Simplicity | ✅ Simple | ⚠️ Requires setup |
| Flexibility | ❌ Limited | ✅ Highly Flexible |
| Granularity | ❌ Coarse (role-level) | ✅ Fine-Grained (module + action level) |
| Custom per User | ❌ No | ✅ Yes - Each user gets custom permissions |
| Separate Cash In/Out | ❌ No | ✅ Yes - Can grant one without the other |
| View-only Access | ❌ Difficult | ✅ Easy - canView without canEdit |
| Super Admin Control | ⚠️ Limited | ✅ Full control over every user |

---

## Real-World Usage Examples

### Scenario 1: Cashier who only handles cash out (expenses)
- ✅ Can access Cash Out module
- ✅ Can create cash out records
- ✅ Can view cash out history
- ❌ CANNOT access Cash In module
- ❌ CANNOT edit inventory

### Scenario 2: Inventory Manager
- ✅ Can view, create, edit, delete products
- ✅ Can manage categories
- ✅ Can view reports
- ❌ CANNOT access cash in/out
- ❌ CANNOT manage users

### Scenario 3: Accountant
- ✅ Can access both Cash In and Cash Out
- ✅ Can create and view all financial records
- ✅ Can view all reports and export them
- ✅ Can VIEW inventory (read-only)
- ❌ CANNOT edit products
- ❌ CANNOT create users

---

## Conclusion

This Module-Based Permission System gives Super Admin complete control over user access. Each user can be assigned exactly the permissions they need - no more, no less. This is perfect for POS systems where different employees have different responsibilities.

**Key Advantages:**
- Super Admin controls everything
- Users get only what they need
- Cash In and Cash Out can be separated
- View-only access is easy to implement
- Highly scalable as your team grows
    },
    reports: {
      canAccess: true,
      canView: true,
      canExport: true
    },
    products: {
      canAccess: true,
      canView: true,   // Can only VIEW products
      canCreate: false,
      canEdit: false,
      canDelete: false
    }Admin') {
    return next(new AppError('Only Super Admin can update permissions', 403));
  }

  const user = await User.findByIdAndUpdate(
    userId,
    { permissions },
    { new: true, runValidators: true }
  );

  if (!user) {
    return next(new AppError('User not found', 404));
  }

  res.status(200).json({
    status: 'success',
    data: { user }
  });
});

/**
 * Get user's own permissions
 */
exports.getMyPermissions = CatchAsync(async (req, res, next) => {
  const user = req.user;

  const accessibleModules = PermissionChecker.getAccessibleModules(user);

  res.status(200).json({
    status: 'success',
    data: {
      role: user.role,
      permissions: user.permissions,
      accessibleModules
   
  checkModuleAccess('cashIn'),
  checkPermission('cashIn', 'canView'),
  cashController.getAllCashIn
);

// CASH OUT Routes
router.post(
  '/cash-out',
  protect,
  checkModuleAccess('cashOut'),    // User must have cashOut access
  checkPermission('cashOut', 'canCreate'),  // User must have create permission
  cashController.createCashOut
);

router.get(
  '/cash-out',
  protect,
  checkModuleAccess('cashOut'),
  checkPermission('cashOut', 'canView'),
  cashController.getAllCashOut
);

module.exports = router;
```

```javascript
// Routers/productsRouter.js (Products/Inventory Example)

const express = require('express');
const router = express.Router();
const { protect } = require('../Controllers/authController');
const { checkModuleAccess, checkPermission } = require('../Controllers/permissionMiddleware');
const productController = require('../Controllers/productControllers');

router.get(
  '/',
  protect,
  checkModuleAccess('products'),
  checkPermission('products', 'canView'),
  productController.getAllProducts
);

router.post(
  '/',
  protect,
  checkModuleAccess('products'),
  checkPermission('products', 'canCreate'),
  productController.createProduct
);

router.patch(
  '/:id',
  protect,
  checkModuleAccess('products'),
  checkPermission('products', 'canEdit'),  // Only users with edit permission
  productController.updateProduct
);

router.delete(
  '/:id',
  protect,
  checkModuleAccess('products'),
  checkPermission('products', 'canDelete'),
  productController.deleteProduct

const express = require('express');
const router = express.Router();
const { checkAccess } = require('../Controllers/ARBAC-middleware');
const ordersController = require('../Controllers/ordersController');

// OLD RBAC approach:
// router.post('/', protect, restrictTo('Admin', 'Manager'), ordersController.createOrder);

// NEW ARBAC approach:
router.post(
  '/',
  protect,
  checkAccess('createOrder'),
  ordersController.createOrder
);

router.get('/', protect, ordersController.getAllOrders);

module.exports = router;
```

### Step 5: Update Controllers

Update your controllers to use ARBAC:

```javascript
// Controllers/ordersController.js (Example)

const ABRACPolicyEngine = require('../utils/ARBAC');

exports.createOrder = CatchAsync(async (req, res, next) => {
  const user = req.user;
  const orderData = req.body;

  // Additional ARBAC check
  if (!ABRACPolicyEngine.isWithinTransactionLimit(user, orderData.totalAmount)) {
    return next(new AppError('Transaction amount exceeds your limit', 400));
  }

  // Create order
  const order = await Order.create({
    ...orderData,
    createdBy: user.id,
    location: user.attributes.location // Track where order was created
  });

  res.status(201).json({
    status: 'success',
    data: { order }
  });
});
```

---

## Sample User with ARBAC Attributes

```javascript
{
  _id: "user123",
  name: "John Doe",
  email: "john@example.com",
  role: "Manager",
  attributes: {
    department: "Sales",
    location: "Store-A",
    accessLevel: 3,
    canApproveOrders: true,
    canManageCash: true,
    canGenerateReports: true,
    canAccessInventory: true,
    maxTransactionAmount: 5000
  }
}
```

---

## Advanced ARBAC Patterns

### 1. Time-Based Access Control
```javascript
// Allow access only during business hours
static canAccessByTime(user, currentTime) {
  const businessStart = 9;  // 9 AM
  const businessEnd = 17;   // 5 PM
  const hour = currentTime.getHours();
  
  if (user.attributes.accessLevel >= 4) {
    return true; // Managers can access anytime
  }
  
  return hour >= businessStart && hour < businessEnd;
}
```

### 2. Location-Based Access Control
```javascript
// Only access resources in your location
static canAccessByLocation(user, resource) {
  return user.attributes.location === resource.location ||
         user.attributes.accessLevel >= 4; // Admins can access anywhere
}
```

### 3. Multi-Attribute Policies
```javascript
static evaluateComplexPolicy(user, requiredPolicy) {
  // Example policy:
  // (department === 'Sales' AND accessLevel >= 2) OR (role === 'Admin')
  
  return (
    (user.attributes.department === requiredPolicy.department &&
     user.attributes.accessLevel >= requiredPolicy.minLevel) ||
    user.role === 'Admin'
  );
}
```

---

## Migration Checklist

- [ ] Update User Model with attributes schema
- [ ] Create ARBAC Policy Engine utility
- [ ] Create ARBAC middleware functions
- [ ] Update all routes to use ARBAC checks
- [ ] Update all controllers for ARBAC logic
- [ ] Migrate existing users with appropriate attributes
- [ ] Update tests for new ARBAC logic
- [ ] Document new attribute permissions
- [ ] Test all access control scenarios
- [ ] Deploy and monitor in production

---

## Testing ARBAC

```javascript
// __tests__/ARBAC.test.js

const ABRACPolicyEngine = require('../utils/ARBAC');

describe('ARBAC Policy Engine', () => {
  const mockUser = {
    role: 'Manager',
    attributes: {
      department: 'Sales',
      accessLevel: 3,
      canApproveOrders: true,
      canManageCash: false,
      maxTransactionAmount: 5000
    }
  };

  test('Should allow user to create order', () => {
    const canAccess = ABRACPolicyEngine.canAccess(mockUser, 'createOrder', {});
    expect(canAccess).toBe(true);
  });

  test('Should deny user to manage cash', () => {
    const canAccess = ABRACPolicyEngine.canAccess(mockUser, 'manageCash', {});
    expect(canAccess).toBe(false);
  });

  test('Should check transaction limit', () => {
    const isValid = ABRACPolicyEngine.isWithinTransactionLimit(mockUser, 3000);
    expect(isValid).toBe(true);
  });
});
```

---

## Benefits of ARBAC Over RBAC

| Feature | RBAC | ARBAC |
|---------|------|-------|
| Simplicity | ✅ Simple | ⚠️ More Complex |
| Flexibility | ❌ Limited | ✅ Highly Flexible |
| Granularity | ❌ Coarse | ✅ Fine-Grained |
| Scalability | ⚠️ Limited | ✅ Excellent |
| Complex Rules | ❌ Difficult | ✅ Easy |
| Conditional Access | ❌ No | ✅ Yes |

---

## Conclusion

ARBAC provides significantly more flexibility and scalability than RBAC. Follow this guide to gradually migrate your system from role-based to attribute-based access control.

For questions or issues, refer to the [TESTING.md](TESTING.md) and [PERFORMANCE.md](PERFORMANCE.md) guides.
