> For the complete documentation index, see [llms.txt](https://docs.flexbase.in/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flexbase.in/sample-references-domain/org-structure-and-hierarchy.md).

# Org Structure and Hierarchy

## Org Structure and Hierarchy

## Organizational Structure and Accountability Matrix Design

### 📌 Overview

This document provides comprehensive guidance on implementing organizational hierarchy, user account management, and accountability relationships in the SumeruSuite recruitment application using the Flexbase framework's `AccountableEntity` system.

***

### 🎯 Business Requirements

#### **Organizational Structure Needs:**

* **Hierarchical Organization Management** - Support for Company → Division → Department → Team structures
* **User Account Management** - Centralized personal information for all users
* **Accountability Relationships** - Flexible responsibility and reporting relationships
* **Multi-Role Support** - Users can have multiple roles (Employee, Candidate, Contractor, etc.)
* **Organizational Assignment** - Employees and entities belong to organizational units
* **Reporting Structures** - Manager-subordinate relationships
* **Approval Hierarchies** - Multi-level approval workflows based on org structure

***

### 🏗️ Core Architecture

#### **1. AccountableEntity Base Class**

The foundation of the organizational structure system is the `AccountableEntity` base class, which enables both individuals (`UserAccount`) and organizations (`OrgAccount`) to participate in accountability relationships.

```csharp
public partial class AccountableEntity : DomainModelBridge
{
    /// <summary>
    /// Accountability matrices where this entity is the commissioner (responsible party)
    /// </summary>
    public ICollection<AccountabilityMatrix> CommissionerMatrices { get; protected set; } = new List<AccountabilityMatrix>();
    
    /// <summary>
    /// Accountability matrices where this entity is the responsible party
    /// </summary>
    public ICollection<AccountabilityMatrix> ResponsibleMatrices { get; protected set; } = new List<AccountabilityMatrix>();
    
    /// <summary>
    /// Profile picture URL
    /// </summary>
    public string? ProfilePic { get; protected set; }
}
```

**Key Characteristics:**

* Both `UserAccount` and `OrgAccount` inherit from `AccountableEntity`
* Enables flexible many-to-many relationships through `AccountabilityMatrix`
* Supports role-based accountability (Employee, Candidate, Contractor, etc.)
* Provides foundation for organizational hierarchy and reporting structures

***

### 👤 UserAccount Domain Model

#### **Purpose:**

`UserAccount` represents the canonical person identity, holding all personal information that is shared across different roles (Employee, Candidate, Contractor, etc.).

#### **Domain Model Structure:**

```csharp
public partial class UserAccount : AccountableEntity
{
    protected readonly ILogger<UserAccount> _logger;

    protected UserAccount()
    {
    }

    public UserAccount(ILogger<UserAccount> logger)
    {
        _logger = logger;
    }

    #region "Attributes"

    #region "Public"
    #endregion

    #region "Protected"
    /// <summary>
    /// First name
    /// </summary>
    [Required(ErrorMessage = "First name is required")]
    [StringLength(50, ErrorMessage = "First name cannot exceed 50 characters")]
    public string FirstName { get; protected set; }
    
    /// <summary>
    /// Middle name
    /// </summary>
    [StringLength(50, ErrorMessage = "Middle name cannot exceed 50 characters")]
    public string? MiddleName { get; protected set; }
    
    /// <summary>
    /// Last name
    /// </summary>
    [Required(ErrorMessage = "Last name is required")]
    [StringLength(50, ErrorMessage = "Last name cannot exceed 50 characters")]
    public string LastName { get; protected set; }
    
    /// <summary>
    /// Email address
    /// </summary>
    [Required(ErrorMessage = "Email is required")]
    [StringLength(150, ErrorMessage = "Email cannot exceed 150 characters")]
    [EmailAddress(ErrorMessage = "Invalid email format")]
    public string Email { get; protected set; }
    
    /// <summary>
    /// User name
    /// </summary>
    [StringLength(50)]
    public string? UserName { get; protected set; }
    
    /// <summary>
    /// ISD Code ID (foreign key to ISDCode)
    /// </summary>
    [StringLength(32)]
    public string? ISDCodeId { get; protected set; }
    
    /// <summary>
    /// Phone number
    /// </summary>
    [StringLength(20, ErrorMessage = "Phone cannot exceed 20 characters")]
    public string? Phone { get; protected set; }
    
    /// <summary>
    /// Address
    /// </summary>
    [StringLength(200, ErrorMessage = "Address cannot exceed 200 characters")]
    public string? Address { get; protected set; }
    
    /// <summary>
    /// City
    /// </summary>
    [StringLength(100, ErrorMessage = "City cannot exceed 100 characters")]
    public string? City { get; protected set; }
    
    /// <summary>
    /// State/Province
    /// </summary>
    [StringLength(50, ErrorMessage = "State cannot exceed 50 characters")]
    public string? State { get; protected set; }
    
    /// <summary>
    /// Postal code
    /// </summary>
    [StringLength(20, ErrorMessage = "Postal code cannot exceed 20 characters")]
    public string? PostalCode { get; protected set; }
    
    /// <summary>
    /// Country
    /// </summary>
    [StringLength(50, ErrorMessage = "Country cannot exceed 50 characters")]
    public string? Country { get; protected set; }
    
    /// <summary>
    /// Date of birth
    /// </summary>
    public DateTimeOffset? DateOfBirth { get; protected set; }
    
    /// <summary>
    /// Gender
    /// </summary>
    [StringLength(20)]
    public string? Gender { get; protected set; }
    
    /// <summary>
    /// Nationality
    /// </summary>
    [StringLength(50)]
    public string? Nationality { get; protected set; }
    
    /// <summary>
    /// Location ID (foreign key to Location/GeoLocation)
    /// </summary>
    [StringLength(32)]
    public string? LocationId { get; protected set; }
    
    /// <summary>
    /// Is active
    /// </summary>
    public bool IsActive { get; protected set; } = true;
    
    /// <summary>
    /// Employees associated with this user account
    /// </summary>
    public ICollection<Employee> Employees { get; protected set; } = new List<Employee>();
    
    /// <summary>
    /// Candidates associated with this user account
    /// </summary>
    public ICollection<Candidate> Candidates { get; protected set; } = new List<Candidate>();
    #endregion

    #region "Private"
    #endregion

    #endregion
}
```

#### **Key Design Principles:**

1. **Composition Over Inheritance:**
   * `UserAccount` contains personal information
   * Role-specific entities (`Employee`, `Candidate`) compose `UserAccount` via `UserAccountId`
   * Each role entity retains only its specific fields
2. **Single Source of Truth:**
   * Personal information (name, email, phone, address) is stored once in `UserAccount`
   * Role entities reference `UserAccount` via foreign key
   * Eliminates data duplication and inconsistency
3. **Multi-Role Support:**
   * One `UserAccount` can have multiple role entities (Employee, Candidate, etc.)
   * Each role entity has its own specific properties
   * Roles are independent and can coexist

***

### 🏢 OrgAccount Domain Model

#### **Purpose:**

`OrgAccount` represents organizational units in the hierarchy (Company, Division, Department, Team, etc.). It enables organizational structure management and accountability relationships.

#### **Domain Model Structure:**

```csharp
public partial class OrgAccount : AccountableEntity
{
    protected readonly ILogger<OrgAccount> _logger;

    protected OrgAccount()
    {
    }

    public OrgAccount(ILogger<OrgAccount> logger)
    {
        _logger = logger;
    }

    #region "Attributes"

    #region "Public"
    #endregion

    #region "Protected"
    /// <summary>
    /// Organization account name
    /// </summary>
    [Required(ErrorMessage = "Name is required")]
    [StringLength(150, ErrorMessage = "Name cannot exceed 150 characters")]
    public string Name { get; protected set; }
    
    /// <summary>
    /// Organization account type ID (foreign key to OrgAccountType)
    /// </summary>
    [StringLength(32)]
    public string? OrgAccountTypeId { get; protected set; }
    
    /// <summary>
    /// Organization account type
    /// </summary>
    [ForeignKey(nameof(OrgAccountTypeId))]
    public OrgAccountType? OrgAccountType { get; protected set; }
    
    /// <summary>
    /// Active flag
    /// </summary>
    public bool IsActive { get; protected set; } = true;
    #endregion

    #region "Private"
    #endregion

    #endregion
}
```

#### **OrgAccountType Enum:**

```csharp
public class OrgAccountTypeEnum : FlexEnum
{
    private OrgAccountTypeEnum() { }
    private OrgAccountTypeEnum(string value, string displayName) : base(value, displayName) { }

    // Organization hierarchy core types
    public static readonly OrgAccountTypeEnum Company
        = new OrgAccountTypeEnum("Company", "Company");

    public static readonly OrgAccountTypeEnum Division
        = new OrgAccountTypeEnum("Division", "Division");

    public static readonly OrgAccountTypeEnum Department
        = new OrgAccountTypeEnum("Department", "Department");

    public static readonly OrgAccountTypeEnum Team
        = new OrgAccountTypeEnum("Team", "Team");

    // Work constructs
    public static readonly OrgAccountTypeEnum Project
        = new OrgAccountTypeEnum("Project", "Project");

    // Financial/administrative units
    public static readonly OrgAccountTypeEnum CostCenter
        = new OrgAccountTypeEnum("CostCenter", "Cost Center");

    // Location-oriented org units
    public static readonly OrgAccountTypeEnum Region
        = new OrgAccountTypeEnum("Region", "Region");

    public static readonly OrgAccountTypeEnum Location
        = new OrgAccountTypeEnum("Location", "Location");

    // Role/Title grouping
    public static readonly OrgAccountTypeEnum Designation
        = new OrgAccountTypeEnum("Designation", "Designation");
}
```

#### **Key Use Cases:**

1. **Vendor Organizations:**
   * Vendors have one `OrgAccount` representing the vendor company
   * Vendor name comes from `OrgAccount.Name`
   * Enables vendor lookup and management
2. **Department Hierarchy:**
   * Companies contain Divisions
   * Divisions contain Departments
   * Departments contain Teams
   * Supports flexible organizational structures
3. **Cost Centers:**
   * Financial tracking units
   * Can be associated with departments or projects
   * Enables budget and cost allocation

***

### 🔗 AccountabilityMatrix Domain Model

#### **Purpose:**

`AccountabilityMatrix` provides a flexible relationship system between any two `AccountableEntity` instances (UserAccount or OrgAccount), enabling complex organizational structures, reporting relationships, and responsibility assignments.

#### **Domain Model Structure:**

```csharp
public partial class AccountabilityMatrix : Accountability
{
    /// <summary>
    /// Commissioner (FK mapped via CommisionerId on base Accountability)
    /// The party who is responsible/accountable
    /// </summary>
    [ForeignKey(nameof(CommisionerId))]
    public AccountableEntity? Commissioner { get; protected set; }

    /// <summary>
    /// Commissioner role context (e.g., Employee, Candidate, Contractor)
    /// </summary>
    [StringLength(20)]
    public string? CommissionerRole { get; protected set; }

    /// <summary>
    /// Commissioner role profile ID (FK to the role table based on CommissionerRole)
    /// </summary>
    [StringLength(32)]
    public string? CommissionerRoleProfileId { get; protected set; }

    /// <summary>
    /// Responsible (FK mapped via ResponsibleId on base Accountability)
    /// The party for whom the commissioner is responsible
    /// </summary>
    [ForeignKey(nameof(ResponsibleId))]
    public AccountableEntity? Responsible { get; protected set; }

    /// <summary>
    /// Responsible role context (e.g., Employee, Candidate, Contractor)
    /// </summary>
    [StringLength(20)]
    public string? ResponsibleRole { get; protected set; }

    /// <summary>
    /// Responsible role profile ID (FK to the role table based on ResponsibleRole)
    /// </summary>
    [StringLength(32)]
    public string? ResponsibleRoleProfileId { get; protected set; }

    /// <summary>
    /// Accountability type ID (FK to AccountabilityMatrixType)
    /// Defines the type of relationship (ReportsTo, Manages, BelongsTo, etc.)
    /// </summary>
    [StringLength(32)]
    public string AccountabilityTypeId { get; protected set; }

    /// <summary>
    /// Accountability type
    /// </summary>
    [ForeignKey(nameof(AccountabilityTypeId))]
    public AccountabilityMatrixType? AccountabilityType { get; protected set; }

    /// <summary>
    /// Valid from date
    /// </summary>
    public DateTimeOffset? ValidFrom { get; protected set; }

    /// <summary>
    /// Valid to date
    /// </summary>
    public DateTimeOffset? ValidTo { get; protected set; }

    /// <summary>
    /// Last renewal date
    /// </summary>
    public DateTimeOffset? LastRenewalDate { get; protected set; }
}
```

#### **AccountabilityMatrixType Enum:**

```csharp
public class AccountabilityMatrixTypeEnum : FlexEnum
{
    private AccountabilityMatrixTypeEnum() { }
    private AccountabilityMatrixTypeEnum(string value, string displayName) : base(value, displayName) { }

    // Hierarchical Relationships
    public static readonly AccountabilityMatrixTypeEnum ReportsTo
        = new AccountabilityMatrixTypeEnum("ReportsTo", "Reports To");

    public static readonly AccountabilityMatrixTypeEnum Manages
        = new AccountabilityMatrixTypeEnum("Manages", "Manages");

    public static readonly AccountabilityMatrixTypeEnum BelongsTo
        = new AccountabilityMatrixTypeEnum("BelongsTo", "Belongs To");

    // Organizational Relationships
    public static readonly AccountabilityMatrixTypeEnum Owns
        = new AccountabilityMatrixTypeEnum("Owns", "Owns");

    public static readonly AccountabilityMatrixTypeEnum Approves
        = new AccountabilityMatrixTypeEnum("Approves", "Approves");

    public static readonly AccountabilityMatrixTypeEnum CollaboratesWith
        = new AccountabilityMatrixTypeEnum("CollaboratesWith", "Collaborates With");

    // Role-Specific Relationships
    public static readonly AccountabilityMatrixTypeEnum DepartmentHead
        = new AccountabilityMatrixTypeEnum("DepartmentHead", "Department Head");

    public static readonly AccountabilityMatrixTypeEnum TeamLead
        = new AccountabilityMatrixTypeEnum("TeamLead", "Team Lead");
}
```

#### **Key Relationship Patterns:**

**1. Reporting Relationships (Employee → Manager):**

```csharp
var reportingRelationship = new AccountabilityMatrix
{
    CommisionerId = managerUserAccount.Id,  // Manager
    ResponsibleId = employeeUserAccount.Id,  // Employee
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.ReportsTo.Value,
    CommissionerRole = "Employee",
    ResponsibleRole = "Employee",
    ValidFrom = DateTimeOffset.Now
};
```

**2. Organizational Assignment (Employee → Department):**

```csharp
var orgAssignment = new AccountabilityMatrix
{
    CommisionerId = employeeUserAccount.Id,  // Employee
    ResponsibleId = departmentOrgAccount.Id, // Department
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.BelongsTo.Value,
    CommissionerRole = "Employee",
    ValidFrom = DateTimeOffset.Now
};
```

**3. Management Relationships (Manager → Department):**

```csharp
var managementRelationship = new AccountabilityMatrix
{
    CommisionerId = managerUserAccount.Id,   // Manager
    ResponsibleId = departmentOrgAccount.Id, // Department
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.Manages.Value,
    CommissionerRole = "Employee",
    ValidFrom = DateTimeOffset.Now
};
```

**4. Approval Relationships (Director → Department):**

```csharp
var approvalRelationship = new AccountabilityMatrix
{
    CommisionerId = directorUserAccount.Id,  // Director
    ResponsibleId = departmentOrgAccount.Id, // Department
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.Approves.Value,
    CommissionerRole = "Employee",
    ValidFrom = DateTimeOffset.Now
};
```

***

### 🏗️ Organizational Hierarchy Implementation

#### **1. Hierarchical Structure Example:**

```
Company (OrgAccount)
├── IT Division (OrgAccount)
│   ├── Software Development Department (OrgAccount)
│   │   ├── Backend Team (OrgAccount)
│   │   └── Frontend Team (OrgAccount)
│   └── Infrastructure Department (OrgAccount)
└── HR Division (OrgAccount)
    ├── Recruitment Department (OrgAccount)
    └── Training Department (OrgAccount)
```

#### **2. Implementation Pattern:**

While `OrgAccount` doesn't have a direct `ParentOrgId` in the current implementation, hierarchical relationships can be managed through `AccountabilityMatrix`:

```csharp
// Department belongs to Division
var departmentToDivision = new AccountabilityMatrix
{
    CommisionerId = departmentOrgAccount.Id,
    ResponsibleId = divisionOrgAccount.Id,
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.BelongsTo.Value,
    ValidFrom = DateTimeOffset.Now
};

// Division belongs to Company
var divisionToCompany = new AccountabilityMatrix
{
    CommisionerId = divisionOrgAccount.Id,
    ResponsibleId = companyOrgAccount.Id,
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.BelongsTo.Value,
    ValidFrom = DateTimeOffset.Now
};
```

#### **3. Querying Organizational Hierarchy:**

```csharp
// Get all departments in a division
var departments = await db.AccountabilityMatrices
    .Where(m => m.ResponsibleId == divisionOrgAccount.Id &&
                m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.BelongsTo.Value)
    .Select(m => m.Commissioner)
    .OfType<OrgAccount>()
    .ToListAsync();

// Get parent organization for a department
var parentOrg = await db.AccountabilityMatrices
    .Where(m => m.CommisionerId == departmentOrgAccount.Id &&
                m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.BelongsTo.Value)
    .Select(m => m.Responsible)
    .OfType<OrgAccount>()
    .FirstOrDefaultAsync();
```

***

### 👥 User-Role-Organization Relationships

#### **1. Employee Assignment Pattern:**

```csharp
// Employee belongs to Department
var employeeToDepartment = new AccountabilityMatrix
{
    CommisionerId = employeeUserAccount.Id,
    ResponsibleId = departmentOrgAccount.Id,
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.BelongsTo.Value,
    CommissionerRole = "Employee",
    CommissionerRoleProfileId = employee.Id,
    ValidFrom = DateTimeOffset.Now
};

// Employee reports to Manager
var employeeToManager = new AccountabilityMatrix
{
    CommisionerId = managerUserAccount.Id,
    ResponsibleId = employeeUserAccount.Id,
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.ReportsTo.Value,
    CommissionerRole = "Employee",
    ResponsibleRole = "Employee",
    ValidFrom = DateTimeOffset.Now
};
```

#### **2. Manager-Department Relationship:**

```csharp
// Manager manages Department
var managerToDepartment = new AccountabilityMatrix
{
    CommisionerId = managerUserAccount.Id,
    ResponsibleId = departmentOrgAccount.Id,
    AccountabilityTypeId = AccountabilityMatrixTypeEnum.Manages.Value,
    CommissionerRole = "Employee",
    CommissionerRoleProfileId = manager.Id,
    ValidFrom = DateTimeOffset.Now
};
```

#### **3. Querying User Relationships:**

```csharp
// Get all employees in a department
var employees = await db.AccountabilityMatrices
    .Where(m => m.ResponsibleId == departmentOrgAccount.Id &&
                m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.BelongsTo.Value &&
                m.CommissionerRole == "Employee")
    .Select(m => m.Commissioner)
    .OfType<UserAccount>()
    .ToListAsync();

// Get manager for an employee
var manager = await db.AccountabilityMatrices
    .Where(m => m.ResponsibleId == employeeUserAccount.Id &&
                m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.ReportsTo.Value)
    .Select(m => m.Commissioner)
    .OfType<UserAccount>()
    .FirstOrDefaultAsync();

// Get all subordinates for a manager
var subordinates = await db.AccountabilityMatrices
    .Where(m => m.CommisionerId == managerUserAccount.Id &&
                m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.ReportsTo.Value)
    .Select(m => m.Responsible)
    .OfType<UserAccount>()
    .ToListAsync();
```

***

### 🎯 Use Cases and Examples

#### **1. Vendor-OrgAccount Relationship:**

```csharp
// Vendor has one OrgAccount
public partial class Vendor : DomainModelBridge
{
    /// <summary>
    /// Organization account ID (foreign key to OrgAccount)
    /// </summary>
    [Required(ErrorMessage = "Organization account ID is required")]
    [StringLength(32)]
    public string OrgAccountId { get; protected set; }
    
    /// <summary>
    /// Organization account for this vendor
    /// </summary>
    [ForeignKey(nameof(OrgAccountId))]
    public OrgAccount? OrgAccount { get; protected set; }
    
    // Vendor name comes from OrgAccount.Name
    // Vendor lookup displays OrgAccount.Name
}
```

#### **2. Candidate Creation with Vendor Referral:**

```csharp
// When creating a candidate with vendor referral
public virtual Candidate CreateCandidate(CreateCandidateCommand cmd)
{
    // Create candidate
    this.Convert(cmd.Dto);
    this.SetAdded(cmd.Dto.GetGeneratedId());
    
    // Handle VendorReferral if present
    if (cmd.Dto.VendorReferral != null)
    {
        var referral = _flexHost.GetDomainModel<VendorReferral>();
        referral.Convert(cmd.Dto.VendorReferral);
        referral.SetCandidateId(this.Id);
        referral.SetVendorId(cmd.Dto.VendorReferral.VendorId);
        referral.SetCreatedBy(cmd.Dto.GetAppContext()?.UserId);
        referral.SetLastModifiedBy(cmd.Dto.GetAppContext()?.UserId);
        referral.SetAdded(cmd.Dto.VendorReferral.GetGeneratedId());
        
        this.VendorReferrals.Add(referral);
    }
    
    return this;
}
```

#### **3. Organizational Approval Workflow:**

```csharp
// Get approval chain for a job posting based on department
public async Task<List<UserAccount>> GetApprovalChain(string departmentId)
{
    var department = await db.OrgAccounts.FindAsync(departmentId);
    
    // Get department manager
    var manager = await db.AccountabilityMatrices
        .Where(m => m.ResponsibleId == departmentId &&
                    m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.Manages.Value)
        .Select(m => m.Commissioner)
        .OfType<UserAccount>()
        .FirstOrDefaultAsync();
    
    // Get division director
    var division = await GetParentOrg(departmentId);
    var director = await db.AccountabilityMatrices
        .Where(m => m.ResponsibleId == division.Id &&
                    m.AccountabilityTypeId == AccountabilityMatrixTypeEnum.Approves.Value)
        .Select(m => m.Commissioner)
        .OfType<UserAccount>()
        .FirstOrDefaultAsync();
    
    return new List<UserAccount> { manager, director };
}
```

***

### 📊 Benefits of This Architecture

#### **1. Unified Accountability System:**

* Both `UserAccount` and `OrgAccount` participate in accountability matrices
* Clear relationships between individuals and organizations
* Flexible reporting structures

#### **2. Clean Separation of Concerns:**

* **UserAccount**: Personal information and authentication
* **OrgAccount**: Organizational structure and hierarchy
* **Role Entities**: Role-specific information (Employee, Candidate, etc.)
* **AccountabilityMatrix**: Relationship management

#### **3. Flexible Relationships:**

* Employees can belong to multiple organizations (matrix organizations)
* Clear manager-subordinate relationships
* Organizational hierarchy support
* Approval chain management

#### **4. Scalability:**

* Easy to add new role types (Contractor, Vendor, etc.)
* Support for complex organizational structures
* Future-proof for additional accountability types
* Extensible for new relationship types

#### **5. Data Consistency:**

* Single source of truth for personal information
* No data duplication across role entities
* Consistent organizational structure management

***

### 🔄 Integration with Recruitment Workflows

#### **1. Job Posting Department Assignment:**

* Job postings can be associated with departments via `OrgAccount`
* Enables filtering and reporting by organizational unit
* Supports department-specific approval workflows

#### **2. Candidate-Organization Relationships:**

* Candidates can be associated with vendors via `VendorReferral`
* Vendor information comes from `OrgAccount`
* Enables vendor performance tracking

#### **3. Employee Referral Tracking:**

* Employee referrals link employees (via `UserAccount`) to candidates
* Enables referral source tracking
* Supports referral bonus management

#### **4. Approval Workflows:**

* Multi-level approvals based on organizational hierarchy
* Manager → Director → VP → CEO approval chains
* Department-specific approval rules

***

### 🚀 Implementation Summary

This organizational structure and accountability matrix design provides:

* **Unified System**: All entities participate in accountability matrices
* **Clean Architecture**: Clear separation between personal, organizational, and role-specific data
* **Flexible Relationships**: Support for complex organizational structures and reporting hierarchies
* **Scalable Design**: Easy to add new user types, organizational entities, and relationship types
* **Enterprise-Grade**: Supports matrix organizations, multiple roles, and complex approval workflows

The `AccountableEntity` framework provides a robust foundation for managing both individual users and organizational structures while maintaining clear accountability relationships throughout the recruitment application.

***

*This design showcases how the Flexbase framework's accountability system enables flexible, scalable organizational structure management with minimal complexity while maintaining enterprise-grade quality and consistency.*
