Skip to main content

Recruitment Module

The recruitment module covers the full hiring pipeline — from identifying a staffing need to onboarding the hired employee. It is composed of six functional areas that must be worked through in order.


Overview of the Pipeline​

Job Requisition → Job Opening → Job Applicant → Interview Schedule → Job Offer → Hired

Each stage is a separate entity in the system. A completed stage unlocks the next, but records at each stage are independently manageable.


Stage 1 — Job Requisition​

Who creates it: HR or a department manager.

Purpose: Formally request a new hire before any public posting goes live. This ensures headcount and budget are approved before recruiting begins.

Fields​

FieldDescription
DepartmentWhich department is requesting the hire
PositionThe role being requested
Requested ByThe employee submitting the request
VacanciesNumber of seats to fill
Estimated CostExpected total compensation cost
DescriptionAdditional context or justification
StatusDraft → Open → Approved → Filled → Closed / Cancelled

Status Lifecycle​

Draft → Open → Approved → Filled
↘ Closed
↘ Cancelled
  • Draft — saved but not yet submitted for review
  • Open — submitted, awaiting approval
  • Approved — authorized; a Job Opening can now be created from it
  • Filled — all vacancies have been hired
  • Closed — ended without filling (budget cut, restructure, etc.)
  • Cancelled — withdrawn before approval

API​

MethodEndpointDescription
GET/api/job-requisitionsPaginated list with filters
GET/api/job-requisitions/{id}Single requisition
POST/api/job-requisitionsCreate
PUT/api/job-requisitions/{id}Update
PATCH/api/job-requisitions/{id}/statusUpdate status only
DELETE/api/job-requisitions/{id}Delete

Query filters: status, departmentId, positionId, departmentName, positionName, requestedByName, createdAtFrom, createdAtTo


Stage 2 — Job Opening​

Who creates it: HR, after a requisition is approved.

Purpose: The public-facing listing that job seekers can see and apply to. One requisition can result in one or more openings (e.g., for different shifts or locations).

Fields​

FieldDescription
TitleJob posting title visible to applicants
DescriptionRole details, responsibilities, qualifications
Salary Range From / ToCompensation range
Publish Salary RangeWhether to show the salary to applicants
Posted DateWhen the listing went live
Closing DateApplication deadline
Applications CountAuto-incremented when applicants are created
StatusOpen → Closed / Filled

Status Lifecycle​

Open → Filled
↘ Closed
  • Open — accepting applications
  • Filled — enough hires made; automatically suggested when all requisition vacancies are filled
  • Closed — no longer accepting applications without a hire

Public API​

The endpoint /api/public/job-openings is unauthenticated and returns only Open openings. This is used by external career pages or portals.

API​

MethodEndpointDescription
GET/api/job-openingsPaginated list with filters
GET/api/job-openings/{id}Single opening
POST/api/job-openingsCreate
PUT/api/job-openings/{id}Update
PATCH/api/job-openings/{id}/statusUpdate status only
DELETE/api/job-openings/{id}Delete

Query filters: status, requisitionId, title, postedDateFrom, postedDateTo, closingDateFrom, closingDateTo


Stage 3 — Job Applicant​

Who creates it: HR (manual entry) or the applicant themselves via the public application form.

Purpose: Tracks every person who applied. This is the central record that all subsequent stages (interview, offer) link back to.

Fields​

FieldDescription
OpeningThe job opening applied for
First / Last NameApplicant identity
EmailContact and unique identifier
PhoneOptional contact
Referred ByIf referred by an existing employee
Applied DateAuto-set to the date of record creation
NotesRecruiter notes
StatusApplied → Shortlisted → Interview → Offered → Hired / Rejected

Status Lifecycle​

Applied → Shortlisted → Interview → Offered → Hired
↘ Rejected
↘ Rejected at any stage
  • Applied — application received, not yet reviewed
  • Shortlisted — passed initial screening
  • Interview — at least one interview scheduled
  • Offered — a Job Offer has been extended (auto-set when an offer is created)
  • Hired — offer accepted (auto-set when the offer status moves to Accepted)
  • Rejected — eliminated at any stage

Public Application Form​

POST /api/public/job-applications accepts an unauthenticated submission. The payload maps to a JobApplicantCreateRequest with the opening ID, name, email, phone, and a cover letter (stored in notes).

API​

MethodEndpointDescription
GET/api/job-applicantsPaginated list with filters
GET/api/job-applicants/{id}Single applicant
POST/api/job-applicantsCreate (also increments opening's applicationsCount)
PUT/api/job-applicants/{id}Update
PATCH/api/job-applicants/{id}/statusUpdate status only
DELETE/api/job-applicants/{id}Delete

Query filters: openingId, status, search, applicantName, email, openingTitle, appliedDateFrom, appliedDateTo


Stage 4 — Interview Schedule​

Who creates it: HR or the interviewer.

Purpose: Books a formal interview session between the applicant and an internal interviewer. Multiple rounds can be scheduled for the same applicant.

Fields​

FieldDescription
ApplicantLinks back to the Job Applicant record
InterviewerAn existing employee conducting the interview
Interview RoundFree text e.g. Technical Round 1, HR Final
Scheduled AtDate and time of the interview
LocationPhysical room or video link
NotesPreparation notes or agenda
StatusScheduled → Completed / Cancelled / No-Show

Status Lifecycle​

Scheduled → Completed
↘ Cancelled
↘ No-Show
  • Scheduled — confirmed, not yet conducted
  • Completed — interview took place; feedback can now be recorded
  • Cancelled — called off by either party
  • No-Show — applicant did not attend

Interview Feedback​

After an interview is completed, the interviewer can attach structured feedback via:

MethodEndpointDescription
GET/api/interview-schedules/{id}/feedbackList feedback for an interview
POST/api/interview-schedules/{id}/feedbackAdd feedback entry

Feedback records contain a rating, recommendation, and notes per interviewer per round.

API​

MethodEndpointDescription
GET/api/interview-schedulesPaginated list with filters
GET/api/interview-schedules/{id}Single schedule
POST/api/interview-schedulesCreate
PUT/api/interview-schedules/{id}Update
PATCH/api/interview-schedules/{id}/statusUpdate status only
DELETE/api/interview-schedules/{id}Delete

Query filters: applicantId, interviewerId, status, applicantName, interviewerName, scheduledAtFrom, scheduledAtTo


Stage 5 — Job Offer​

Who creates it: HR, after all interview rounds are satisfactorily completed.

Purpose: The formal offer of employment. Creating an offer automatically moves the linked applicant's status to Offered.

Fields​

FieldDescription
ApplicantThe applicant receiving the offer
PositionThe specific position being offered (may differ from opening title)
Offered SalaryAgreed compensation
Offer DateDate the offer was issued
Start DateProposed first day of work
Expiry DateDeadline for the applicant to respond
NotesTerms, conditions, or special arrangements
Created ByHR employee who issued the offer
StatusPending → Accepted / Declined / Withdrawn

Status Lifecycle​

Pending → Accepted (applicant status → Hired)
↘ Declined
↘ Withdrawn
  • Pending — offer sent, awaiting the applicant's decision
  • Accepted — applicant confirmed; the linked applicant record is auto-updated to Hired
  • Declined — applicant turned down the offer
  • Withdrawn — company retracted the offer before a decision was made

Side Effect on Acceptance​

When an offer transitions to Accepted, the system automatically sets the applicant's status to Hired. This is the final event in the recruitment pipeline. The employee record should then be created separately in the Employee module using the hiring details from this offer.

API​

MethodEndpointDescription
GET/api/job-offersPaginated list with filters
GET/api/job-offers/{id}Single offer
POST/api/job-offersCreate (also sets applicant → Offered)
PATCH/api/job-offers/{id}/statusUpdate status (Accepted sets applicant → Hired)
DELETE/api/job-offers/{id}Delete

Query filters: applicantId, status, applicantName, positionName, offerDateFrom, offerDateTo, startDateFrom, startDateTo


Supporting Entity — Staffing Plan​

Who creates it: HR leadership or department heads, typically at the start of a fiscal year.

Purpose: A top-down headcount and budget plan that can be used to pre-authorize a batch of requisitions. It is not a hard gate in the pipeline but provides the budgetary context for hiring decisions.

Fields​

FieldDescription
Plan NameDescriptive label e.g. FY2026 Engineering Growth
Fiscal YearThe year the plan covers
DepartmentScope (nullable means company-wide)
Total BudgetAggregate compensation budget for the plan
Created ByAuthor of the plan
StatusDraft → Active → Closed

Plan Items​

Each staffing plan contains line items:

FieldDescription
Role TitleThe role being planned for
VacanciesNumber of hires planned
Estimated CostBudget allocated to this role
RequisitionOptional link to the actual requisition created for this item

Items are managed via:

  • POST /api/staffing-plans/{id}/items — add an item
  • DELETE /api/staffing-plans/{id}/items/{itemId} — remove an item

API​

MethodEndpointDescription
GET/api/staffing-plansPaginated list with filters
GET/api/staffing-plans/{id}Single plan with items
POST/api/staffing-plansCreate
PUT/api/staffing-plans/{id}Update
DELETE/api/staffing-plans/{id}Delete

Query filters: planName, fiscalYear, departmentName, status, createdByName


End-to-End Example​

The following illustrates a typical hire from request to onboarding.

1. A department head raises a need.

HR creates a Job Requisition for the Engineering department, requesting 2 Senior Engineers. Status starts as Draft, then moved to Open once the justification is complete.

2. Finance and leadership approve.

An authorized user updates the requisition status to Approved.

3. HR posts the role.

A Job Opening titled "Senior Software Engineer" is created, linked to the approved requisition. Posted date is set and the status is Open.

4. Applications come in.

Three applicants apply via the public portal. Each creates a Job Applicant record with status Applied.

5. HR screens and shortlists.

Two applicants pass the resume screen. Their status is updated to Shortlisted.

6. Interviews are scheduled.

For each shortlisted applicant, an Interview Schedule is created for a technical round and then an HR round. Each applicant's status moves to Interview.

7. Feedback is recorded.

After each session is marked Completed, the interviewer adds an Interview Feedback entry with a rating and recommendation.

8. One candidate is selected.

HR creates a Job Offer for the chosen applicant, specifying salary, start date, and expiry. The applicant's status automatically moves to Offered. The rejected applicant's status is manually set to Rejected.

9. The candidate accepts.

The offer status is updated to Accepted. The system automatically sets the applicant's status to Hired.

10. Employee record is created.

HR creates a new Employee in the Employee module using the start date and position from the offer. The recruitment pipeline is complete.


Permissions​

PermissionCovers
HR_RECRUITMENT_VIEWRead access to all recruitment records
HR_RECRUITMENT_MANAGECreate, update, delete requisitions, openings, and applicants
HR_RECRUITMENT_INTERVIEW_MANAGECreate and manage interview schedules and feedback
HR_RECRUITMENT_OFFER_MANAGECreate and manage job offers
HR_RECRUITMENT_STAFFING_MANAGEFull access to staffing plans

Public endpoints (/api/public/*) require no authentication.