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
| Field | Description |
|---|---|
| Department | Which department is requesting the hire |
| Position | The role being requested |
| Requested By | The employee submitting the request |
| Vacancies | Number of seats to fill |
| Estimated Cost | Expected total compensation cost |
| Description | Additional context or justification |
| Status | Draft → 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
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/job-requisitions | Paginated list with filters |
| GET | /api/job-requisitions/{id} | Single requisition |
| POST | /api/job-requisitions | Create |
| PUT | /api/job-requisitions/{id} | Update |
| PATCH | /api/job-requisitions/{id}/status | Update 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
| Field | Description |
|---|---|
| Title | Job posting title visible to applicants |
| Description | Role details, responsibilities, qualifications |
| Salary Range From / To | Compensation range |
| Publish Salary Range | Whether to show the salary to applicants |
| Posted Date | When the listing went live |
| Closing Date | Application deadline |
| Applications Count | Auto-incremented when applicants are created |
| Status | Open → 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
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/job-openings | Paginated list with filters |
| GET | /api/job-openings/{id} | Single opening |
| POST | /api/job-openings | Create |
| PUT | /api/job-openings/{id} | Update |
| PATCH | /api/job-openings/{id}/status | Update 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
| Field | Description |
|---|---|
| Opening | The job opening applied for |
| First / Last Name | Applicant identity |
| Contact and unique identifier | |
| Phone | Optional contact |
| Referred By | If referred by an existing employee |
| Applied Date | Auto-set to the date of record creation |
| Notes | Recruiter notes |
| Status | Applied → 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
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/job-applicants | Paginated list with filters |
| GET | /api/job-applicants/{id} | Single applicant |
| POST | /api/job-applicants | Create (also increments opening's applicationsCount) |
| PUT | /api/job-applicants/{id} | Update |
| PATCH | /api/job-applicants/{id}/status | Update 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
| Field | Description |
|---|---|
| Applicant | Links back to the Job Applicant record |
| Interviewer | An existing employee conducting the interview |
| Interview Round | Free text e.g. Technical Round 1, HR Final |
| Scheduled At | Date and time of the interview |
| Location | Physical room or video link |
| Notes | Preparation notes or agenda |
| Status | Scheduled → 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:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/interview-schedules/{id}/feedback | List feedback for an interview |
| POST | /api/interview-schedules/{id}/feedback | Add feedback entry |
Feedback records contain a rating, recommendation, and notes per interviewer per round.
API
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/interview-schedules | Paginated list with filters |
| GET | /api/interview-schedules/{id} | Single schedule |
| POST | /api/interview-schedules | Create |
| PUT | /api/interview-schedules/{id} | Update |
| PATCH | /api/interview-schedules/{id}/status | Update 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
| Field | Description |
|---|---|
| Applicant | The applicant receiving the offer |
| Position | The specific position being offered (may differ from opening title) |
| Offered Salary | Agreed compensation |
| Offer Date | Date the offer was issued |
| Start Date | Proposed first day of work |
| Expiry Date | Deadline for the applicant to respond |
| Notes | Terms, conditions, or special arrangements |
| Created By | HR employee who issued the offer |
| Status | Pending → 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
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/job-offers | Paginated list with filters |
| GET | /api/job-offers/{id} | Single offer |
| POST | /api/job-offers | Create (also sets applicant → Offered) |
| PATCH | /api/job-offers/{id}/status | Update 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
| Field | Description |
|---|---|
| Plan Name | Descriptive label e.g. FY2026 Engineering Growth |
| Fiscal Year | The year the plan covers |
| Department | Scope (nullable means company-wide) |
| Total Budget | Aggregate compensation budget for the plan |
| Created By | Author of the plan |
| Status | Draft → Active → Closed |
Plan Items
Each staffing plan contains line items:
| Field | Description |
|---|---|
| Role Title | The role being planned for |
| Vacancies | Number of hires planned |
| Estimated Cost | Budget allocated to this role |
| Requisition | Optional link to the actual requisition created for this item |
Items are managed via:
POST /api/staffing-plans/{id}/items— add an itemDELETE /api/staffing-plans/{id}/items/{itemId}— remove an item
API
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/staffing-plans | Paginated list with filters |
| GET | /api/staffing-plans/{id} | Single plan with items |
| POST | /api/staffing-plans | Create |
| 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 toOpenonce 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 toRejected.
9. The candidate accepts.
The offer status is updated to
Accepted. The system automatically sets the applicant's status toHired.
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
| Permission | Covers |
|---|---|
HR_RECRUITMENT_VIEW | Read access to all recruitment records |
HR_RECRUITMENT_MANAGE | Create, update, delete requisitions, openings, and applicants |
HR_RECRUITMENT_INTERVIEW_MANAGE | Create and manage interview schedules and feedback |
HR_RECRUITMENT_OFFER_MANAGE | Create and manage job offers |
HR_RECRUITMENT_STAFFING_MANAGE | Full access to staffing plans |
Public endpoints (/api/public/*) require no authentication.