Skip to main content

Domain Modules

The BonardaHR backend is organised using a package-by-feature (domain-driven) layout. Each module under com.bonardahr.backend.domain is self-contained, owning its controllers, services, repositories, DTOs, and JPA entities.


1. Employee Management (domain/employee/)

Core Functionality

  • Full employee lifecycle: active, offboarding, and separated employees
  • Reporting hierarchy: self-referencing reports_to_id with circular reference prevention. The buildHierarchy method in EmployeeServiceImpl fetches the full employee list and builds the org tree in-memory
  • Role audit tracking: EmployeeRoleAudit records every role assignment and removal
  • Bulk CSV imports: BulkImportService validates and ingests employee records from CSV

Dynamic Sections

Admins can define custom sections and fields using EmployeeSection and SectionField entities. Values are stored as JSONB in employee_field_values. This avoids schema migrations when new custom fields are needed — see ADR-001.

Field Permissions

Section fields enforce granular edit access via the EditableBy enum:

ValueWho Can Edit
SYSTEMNo one (auto-generated values)
HR_ONLYHR Manager and Admin only
EMPLOYEEEmployee (own profile) or HR

2. Time Off & Leave Workflows (domain/timeoff/)

Leave Requests

  • Request lifecycle: PENDING → APPROVED / REJECTED / CANCELLED
  • Supports half-day requests (MORNING / AFTERNOON periods)
  • Attachment requirements per leave type: NEVER, ALWAYS, or CONDITIONAL

Balances & Accruals

  • Denormalized balance tracking (pending, used, allocated) for O(1) lookups
  • Automatic year-end backfill and accrual calculations
  • Pessimistic locking on balance rows prevents double-approval races

Outlook Calendar Sync

Synchronizes approved leave events to employee Microsoft Outlook calendars via the Graph API (optional — requires MS_* env vars).


3. Onboarding & Task Wizards (domain/onboarding/)

Templates & Tasks

  • Admin-configurable onboarding templates with field requirements, document upload requests, and key person assignments
  • KeyPersonType defines roles such as HR contact, IT contact, buddy, and manager
  • Tasks can be required or optional, with due-date offsets from the employee's start date

Wizard Engine

  • OnboardingInstance tracks per-employee wizard progress: task completion, document acknowledgments, and overdue status
  • OnboardingSchedulerService sends automated reminders for overdue tasks

4. HR Analytics & Bradford Factor (domain/reports/)

HR Dashboard

Aggregated metrics across the organization:

  • Headcount by department and site
  • Turnover rates (resignation, termination, layoff, retirement, contract end)
  • Time-off usage by leave type
  • Timesheet compliance rates

Bradford Factor Calculation

Evaluates short-term unplanned absenteeism impact using the formula:

B = S2 × D

  • S = total number of separate absence spells (unplanned leave approved within the rolling 52-week window)
  • D = total days absent in the same window

Only leave types with counts_towards_bradford = true (e.g. sick leave) are included. Planned leave (annual, maternity) is excluded.

Risk Categorisation

Scores are evaluated against configurable thresholds stored in BradfordSettings:

Score RangeRisk Level
0 – 49LOW
50 – 199MEDIUM
200 – 499HIGH
500+CRITICAL

Thresholds are admin-configurable in Admin → Bradford Factor. Implemented in ReportsServiceImpl.

Visibility Rules

  • HR Managers see Bradford scores for all employees
  • Managers see their direct team
  • Employees see their own score only

5. Attendance & Timesheets (domain/timesheet/)

  • Weekly timesheets with clock-in / clock-out tracking and manual hour adjustments
  • 2-week edit window: current week + 2 previous weeks; future timesheets cannot be created
  • Status lifecycle: DRAFT → SUBMITTED → APPROVED / REJECTED
  • Manager submission and approval workflows with reviewer validation (reviewer cannot be the submitter)
  • Email reminders for overdue timesheets

6. Automated Workflow Engine (domain/workflow/)

A flexible, event-driven task assignment engine for multi-step HR processes.

Key Abstractions

AbstractionRole
WorkflowEventGeneric event: eventType, category, targetEmployee, payload
WorkflowEventSourceInterface each domain implements to declare events and date fields
WorkflowEventCatalogAggregates all sources; serves REST API to frontend for dynamic dropdowns
WorkflowEventBusCentral dispatch — matches published events to task list / template triggers
TaskListExecutionServiceMaterialises a task list into a workflow instance with tasks
AssigneeResolverResolves task assignees by type: EMPLOYEE, MANAGER, ROLE, etc.
DateFieldSchedulerDaily cron (6:05 AM) that fires date-based events (e.g. "leave starts today")

Event Sources

SourceEventsDate Fields
EmployeeEventSourceEMPLOYEE_CREATED, EMPLOYEE_TERMINATED, EMPLOYEE_UPDATEDhireDate, birthday, exitDate
TimeOffEventSourceTIME_OFF_APPROVED, TIME_OFF_CANCELLED, TIME_OFF_STARTED, TIME_OFF_ENDEDrecentLeaveStartDate, recentLeaveEndDate
SectionDateFieldSource(none)Dynamically discovered from admin-configured DATE section fields

Trigger Types

TriggerMatching Logic
EVENTevent.eventType == config.eventType
DATE_FIELDEvent is DATE_MATCH and dateField matches
TIME_OFF_POLICYEvent is TIME_OFF_STARTED/ENDED and typeId matches
MANUALNever auto-triggered

Task Execution Flow

  1. Event bus matches a task list → calls TaskListExecutionService.executeTaskList()
  2. Creates a WorkflowInstance (root items become PENDING; child items become BLOCKED)
  3. Auto-executable types (EMAIL, CALENDAR, NOTIFICATION) execute immediately
  4. When a task completes → unblockDependentTasks() sets children to PENDING
  5. Parents with autoCompleteOnChildren auto-complete when all children finish
  6. When all tasks are done → instance status becomes COMPLETED

Extensibility

Adding a new event source requires one file:

@Component
public class PayrollEventSource implements WorkflowEventSource {
public List<EventDefinition> getEventDefinitions() { /* declare events */ }
public List<DateFieldDefinition> getDateFieldDefinitions() { /* declare date fields */ }
public LocalDate resolveDateField(String key, Employee e) { /* resolve */ }
}

Then call eventBus.publish(...) where the event occurs. The catalog auto-discovers the new source and the frontend dropdowns auto-populate — no other files need to change.


7. Document Management & E-Signatures (domain/document/ & domain/esign/)

Document Management

  • Hierarchical folder structures and policy repositories backed by Microsoft SharePoint
  • Local filesystem fallback for development when SP_MOCK_ENABLED=true
  • Supports document browsing, uploading, and preview via the SharePoint Graph API

E-Signature Flow

  • HR creates a signature request targeting one or more employees
  • Each employee gets a PENDING signature record
  • Employee signs (capturing signature data, timestamp, IP address, and user agent) → status becomes SIGNED
  • Employee can decline with a mandatory reason → status becomes DECLINED
  • All states are immutable once terminal

8. Role-Based Access Control Admin (domain/admin/)

Exposes REST endpoints for managing custom roles and dynamic permission matrices:

EndpointDescription
GET /api/v1/admin/rolesList all roles with permissions
POST /api/v1/admin/rolesCreate a new custom role
PUT /api/v1/admin/roles/{id}Update role name, description, and permissions
DELETE /api/v1/admin/roles/{id}Delete a custom role
GET /api/v1/admin/permissionsList all available permissions
PUT /api/v1/admin/employees/{id}/rolesSet an employee's roles
caution

The five default system roles — ADMIN, HR_MANAGER, MANAGER, IT_MANAGER, EMPLOYEE — are protected from deletion. Permissions are read-only in the UI; new permissions are introduced exclusively via Flyway migrations.


Supporting Modules

ModuleDescription
domain/organization/Departments, offices (sites), teams, and the org chart tree
domain/notification/In-app notification inbox and email dispatcher
domain/event/Company-wide calendar events and regional public holidays
domain/feedback/Employee surveys, performance cycles, and 1-on-1 tracking
domain/common/Shared base entity, audit fields, and utility classes