Recruitment
Overview
Recruitment handles the full candidate lifecycle — from pipeline configuration to applicant tracking, assessments, interviews, document verification, and automated hiring.
The module uses Eloquent Observers that react to model events to automate stage snapshots, pipeline configuration duplication, deposit initialization, notification dispatching, and hiring record creation.
Key Entities
| Entity | Description |
|---|---|
| Pipeline | Ordered collection of stages defining the recruitment flow |
| Stage | A single step in the pipeline (Screening, Interview, etc.) |
| Applicant | A candidate tracked through pipeline stages |
| Candidate | A person in the talent pool |
Flowchart
Pipeline Configuration Flow
The following flowchart illustrates how an admin configures pipelines and stages for recruitment:
Applicant Review Flow
The following flowchart shows how an admin reviews and processes applicants:
Assessment Scoring Flow
The following flowchart shows the assessment input and review process:
Observer Flows
ApplicantObserver — Full Lifecycle Automation
The ApplicantObserver is the most complex observer — it handles code generation, pipeline snapshotting, stage advancement, hiring logic, and vacancy state synchronization across 6 different Eloquent events.
Explanation by event:
creating — Before the applicant is first saved:
- Generates a unique applicant code (prefix
APP-) usingApplicant::generateUniqueCode(). - Snapshots the current pipeline stages into a
pipeline_stagesJSON column — this freezes the stage configuration at the time of application so changes to the pipeline don't affect existing applicants.
created — After the applicant is saved:
- Calls
InitializeApplicantDepositsto create any required deposit/fee records based on the pipeline configuration.
saving — Before every save (create and update):
- If linked to a candidate, syncs
name,email,phone, andsocial_mediafrom the candidate record. - If
stage_idchanged:- Updates the
pipeline_stagesJSON snapshot — marks completed stages, sets the current stage, and sets remaining stages as pending. - If the new stage is the final stage in the pipeline, triggers the Hiring Logic: creates a User account, Employee record, Teacher record (if the vacancy title contains "teacher"), assigns the default role, and sends a
HiringNotification. - Sets applicant
statustodone(final stage) orprogress(intermediate stage).
- Updates the
- Always calls
StageOrchestrator::enter()after handling stage logic.
saved — After every save:
- Calls
SyncVacancyStateto update the vacancy's recruitment state based on applicant progress.
updated — After an update:
- If
stage_idchanged, dispatchesSendStageChangedNotificationwith the from/to stage names.
deleted — After deletion:
- Calls
SyncVacancyStateto recalculate vacancy state.
ApplicantDocumentObserver — Document Versioning
The ApplicantDocumentObserver manages document deduplication by generating a deterministic hash key:
Explanation:
- Documents flagged as
is_current = trueget a deterministic SHA1 hash based onowner_type|owner_id|document_type_id. - This hash ensures that each owner can only have one "current" document of each type — uploading a new version replaces the previous one.
- Documents with
is_current = falsegetcurrent_key = null(archived/version history).
VacancyObserver — Pipeline Setup Automation
The VacancyObserver automates vacancy configuration when a vacancy is created or its pipeline changes:
Explanation:
created — When a new vacancy is created:
- Creates a
VacancyStaterecord with statuspending. - Calls
duplicatePipelineSettings()which copies all stages, required documents, and required deposits from the master pipeline into per-vacancyPipelineRequiredItemrecords. This allows each vacancy to customize its requirements independently.
updated — When a vacancy is updated:
- If
pipeline_idchanged, deletes all old vacancy-specific stages and required items, then re-duplicates from the new pipeline. - Logs a reminder to notify selected applicants.
DFD — Data Flow Diagram
Level 0 — Context Diagram
Level 1 — Applicant Processing
Activity Diagram — Applicant Lifecycle
Database
Key Tables
| Table | Description |
|---|---|
applicants | Tracks candidate through stages — stage_id, status, score, pipeline_stages (JSON snapshot) |
candidates | Talent pool — user_id, first_name, last_name, email |
talent_interviews | Interview scheduling — scheduled_at, interviewer_id, status |
talent_assessments | Test scores — type (WRITTEN/INTERVIEW/MICRO), score |
applicant_documents | File uploads per stage — asset_id, current_key, status |
applicant_deposits | Fee tracking per stage — amount, status |
vacancy_states | Vacancy status tracking — status, stage_id |
pipeline_required_items | Polymorphic requirements (docs, deposits) per stage/vacancy |
Key Files
| File | Purpose |
|---|---|
app/Observers/Recruitment/ApplicantObserver.php | Full lifecycle — code gen, stage snapshot, hiring logic, notifications |
app/Observers/Recruitment/ApplicantDocumentObserver.php | Document versioning — SHA1 hash deduplication |
app/Observers/Recruitment/VacancyObserver.php | Pipeline setup — auto-duplicate stages, docs, deposits to vacancy |
app/Jobs/Recruitment/SendStageChangedNotification.php | Job: notify on applicant stage change |
app/Services/Recruitment/Deposits/InitializeApplicantDeposits.php | Create deposit records on applicant creation |
app/Services/Recruitment/VacancyState/SyncVacancyState.php | Sync vacancy state based on applicants |
app/Services/Platform/Pipeline/StageOrchestrator.php | Stage entry triggers and contract auto-creation |
app/Models/Recruitment/Applicant/Applicant.php | Applicant model — stage tracking, status, scoring |
app/Models/Recruitment/Candidate/Candidate.php | Candidate talent pool |
app/Models/Recruitment/TalentAssessment/TalentAssessment.php | Assessment scoring |
app/Models/Recruitment/TalentInterview/TalentInterview.php | Interview scheduling |
app/Models/Platform/Pipeline/Pipeline.php | Pipeline definition |
app/Models/Platform/Stage/Stage.php | Stage definition with config |
app/Filament/Resources/Applicants/ | Applicant CRUD + actions (advance, approve) |