Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Spec: specs/hr/HR-09-applicant-tracking-system.md (v1.0)
Plan: specs/hr/HR-09-applicant-tracking-system-PLAN.md (v1.0)
Status: ✅ Implemented (Core Features)
Last Updated: 2026-02-09

Overview

This document defines the integration contracts for the HR-09 Applicant Tracking System (ATS). The ATS integrates with multiple platform features and HR modules to provide a seamless hiring workflow from job posting to employee onboarding.

Implementation Status

Core Features (✅ Implemented):
  • ✅ Job postings and candidate management
  • ✅ Application tracking with multi-stage workflow
  • ✅ Offer creation, sending, and acceptance
  • ✅ Employee creation triggered on offer acceptance
  • ✅ Automatic onboarding initiation (candidate_hired event + createOnboardingForHire)
  • ✅ Multi-tenant RLS security
  • useHireWithOnboarding hook for manual triggering
In Progress (🟡):
  • 🟡 Notification integrations (interview reminders, status updates)
Planned (📝):
  • 📝 Job board integrations (Indeed, LinkedIn) - Phase 5.4
  • 📝 Background check provider integration - Phase 5.2
  • 📝 Reference checking workflow - Phase 5.1
  • 📝 Candidate communication templates - Phase 5.3

Event Contracts

Published Events

EventPublisherPayload SchemaSubscribersStatus
hr_employee_hiredHR-09 ATSSee belowHR-03 Onboarding, IT-08✅ Implemented
offer_acceptedHR-09 ATSSee belowHR-01 Employee Directory✅ Implemented
interview_scheduledHR-09 ATSSee belowPF-10 Notifications📝 Planned
application_receivedHR-09 ATSSee belowPF-10 Notifications📝 Planned

hr_employee_hired Event (formerly candidate_hired)

Purpose: Notifies HR-03 Onboarding to start onboarding workflow for new hire.
Status: ✅ Implemented in src/cores/hr/services/hiring/publishCandidateHiredEvent.ts
interface CandidateHiredEventPayload {
  event_type: 'candidate_hired';
  timestamp: string; // ISO 8601
  organization_id: string; // UUID
  application_id: string; // UUID
  candidate_id: string; // UUID
  employee_id: string; // UUID - newly created employee
  position_id?: string; // UUID (optional)
  department_id?: string; // UUID (optional)
  site_id?: string | null; // UUID
  hire_date: string; // ISO date
  offer_id: string; // UUID
  hired_by?: string; // UUID - user who accepted offer
}
Trigger Location: src/cores/hr/hooks/useOfferMutation.ts - acceptOffer mutation

offer_accepted Event

Purpose: Triggers employee record creation in HR-01.
Status: ✅ Implemented (via database trigger + event publishing)
interface OfferAcceptedEvent {
  event_type: 'offer_accepted';
  timestamp: string; // ISO 8601
  payload: {
    organization_id: string; // UUID
    offer_id: string; // UUID
    candidate_id: string; // UUID
    application_id: string; // UUID
    position_id: string; // UUID
    department_id: string; // UUID
    site_id: string | null; // UUID
    salary_amount: number;
    employment_type: string;
    start_date: string; // ISO date
  };
}

interview_scheduled Event

Purpose: Notifies interviewers and candidates of scheduled interviews.
interface InterviewScheduledEvent {
  event_type: 'interview_scheduled';
  timestamp: string; // ISO 8601
  payload: {
    organization_id: string; // UUID
    interview_id: string; // UUID
    application_id: string; // UUID
    candidate_id: string; // UUID
    interviewer_ids: string[]; // UUIDs
    interview_type: 'phone_screen' | 'video' | 'in_person' | 'panel';
    scheduled_at: string; // ISO 8601 datetime
    duration_minutes: number;
    location: string | null;
    video_link: string | null;
  };
}

application_received Event

Purpose: Notifies HR of new application and sends confirmation to candidate.
interface ApplicationReceivedEvent {
  event_type: 'application_received';
  timestamp: string; // ISO 8601
  payload: {
    organization_id: string; // UUID
    application_id: string; // UUID
    candidate_id: string; // UUID
    job_posting_id: string; // UUID
    candidate_email: string;
    candidate_name: string;
    source: 'internal' | 'indeed' | 'linkedin' | 'referral' | 'other';
  };
}

Consumed Events

EventSourceHandlerPurposeStatus
employee_createdHR-01Link to applicationAssociates employee with original application📝 Planned
onboarding_completedHR-03Update hire transitionMarks hiring workflow as complete📝 Planned

API Contracts

Exposed APIs

APIs exposed by HR-09 ATS for consumption by other modules.

Get Candidate by Employee

Endpoint: GET /api/v1/hr/candidates/by-employee/{employee_id}
Purpose: Retrieve candidate profile linked to an employee record.
Consumers: HR-01 (Employee Directory)
Status: 📝 Planned
Response:
interface CandidateByEmployeeResponse {
  candidate_id: string;
  candidate_name: string;
  application_history: {
    application_id: string;
    job_posting_id: string;
    position_title: string;
    applied_at: string;
    hired_at: string | null;
  }[];
}

Get Hiring Pipeline Metrics

Endpoint: GET /api/v1/hr/ats/pipeline-metrics
Purpose: Retrieve pipeline metrics for dashboard widgets.
Consumers: HR Dashboard, LO Dashboard
Status: 📝 Planned
Query Parameters:
  • organization_id (required)
  • date_from (optional)
  • date_to (optional)
  • department_id (optional)
Response:
interface PipelineMetricsResponse {
  total_open_positions: number;
  total_applications: number;
  applications_by_stage: {
    stage: string;
    count: number;
  }[];
  average_time_to_fill_days: number;
  hire_rate_percentage: number;
}

Consumed APIs

APIs consumed by HR-09 ATS from other modules.
APISourcePurposeStatus
GET /api/v1/hr/employeesHR-01Interviewer lookup✅ Available
GET /api/v1/hr/positionsHR-01Position selection for job postings✅ Available
GET /api/v1/hr/departmentsHR-01Department selection✅ Available
POST /api/v1/pf/notificationsPF-10Send notifications✅ Available
POST /api/v1/pf/documentsPF-11Store resumes, offer letters✅ Available

Platform Integration Layer Usage

PF-08 (Forms) Integration

Location: @/platform/forms
Purpose: Application forms, interview feedback forms
Usage:
import { FormEmbed, useFormSubmission } from '@/platform/forms';

// Application form
<FormEmbed 
  formId="hr-ats-application-form"
  onSubmit={handleApplicationSubmit}
  context={{ job_posting_id, organization_id }}
/>

// Interview feedback form
<FormEmbed 
  formId="hr-ats-interview-feedback"
  onSubmit={handleFeedbackSubmit}
  context={{ interview_id, interviewer_id }}
/>

PF-10 (Notifications) Integration

Location: @/platform/notifications
Purpose: Application confirmations, interview reminders, status updates
Notification Templates:
  • hr-ats-application-received - Candidate confirmation
  • hr-ats-interview-reminder - 24h and 1h reminders
  • hr-ats-offer-sent - Offer letter notification
  • hr-ats-status-update - Application status change

PF-11 (Documents) Integration

Location: @/platform/documents
Purpose: Resume/CV storage, offer letter PDFs
Storage Buckets:
  • hr-ats-resumes - Candidate resume uploads
  • hr-ats-offer-letters - Generated offer letter PDFs

PF-12 (Reports) Integration

Location: @/platform/reports
Purpose: Recruiting reports, EEO reports
Report Templates:
  • hr-ats-pipeline-report - Pipeline metrics
  • hr-ats-time-to-fill-report - Time-to-fill analytics
  • hr-ats-source-effectiveness-report - Source ROI
  • hr-ats-eeo-report - EEO-1 data export

Database Function Contracts

hr_create_employee_from_offer()

Purpose: Automatically create employee record when offer is accepted. Signature:
CREATE OR REPLACE FUNCTION hr_create_employee_from_offer(
  p_offer_id UUID
)
RETURNS UUID -- Returns new employee_id
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
Behavior:
  1. Validates offer exists and is in ‘accepted’ status
  2. Creates hr_employees record with mapped fields
  3. Creates hr_hire_transitions record
  4. Returns new employee_id

create_onboarding_from_template()

Purpose: Create an onboarding instance from a template for a new hire.
Status: ✅ Implemented
Signature:
CREATE OR REPLACE FUNCTION create_onboarding_from_template(
  _employee_id UUID,
  _template_id UUID,
  _start_date DATE,
  _created_by UUID
)
RETURNS UUID -- Returns new onboarding_instance_id
Called By: src/cores/hr/services/hiring/createOnboardingForHire.ts

Auto-Onboarding Flow

When an offer is accepted, the following sequence occurs:
1. acceptOffer() mutation called

2. hr_offers.offer_status updated to 'accepted'

3. Database trigger creates hr_employees record (via hr_create_employee_from_offer)

4. Frontend publishes hr_employee_hired event (publishCandidateHiredEvent)

5. Frontend calls createOnboardingForHire()

6. If auto_create_onboarding=true in hr_module_settings:
   - Fetches default_onboarding_template_id
   - Calls create_onboarding_from_template RPC
   - Creates hr_onboarding_instances + hr_onboarding_task_instances

7. Query caches invalidated, UI updated
Configuration:
  • hr_module_settings.auto_create_onboarding - Enable/disable automatic onboarding
  • hr_module_settings.default_onboarding_template_id - Template to use

Security Considerations

RLS Policy Requirements

All ATS tables use hr_has_org_access() SECURITY DEFINER function to prevent RLS recursion. Access Levels:
  • HR Admin: Full access to all ATS data within organization
  • Hiring Manager: Read/write for positions in their department
  • Interviewer: Read for assigned interviews, write for feedback
  • Candidate: Read-only for own applications and offer details

EEO Data Protection

EEO data in hr_candidates table requires additional access restrictions:
  • Encrypted at rest
  • Accessible only to HR Admin and Compliance Officer roles
  • Audit logging for all EEO data access
  • Excluded from standard data exports

References

  • Spec: specs/hr/HR-09-applicant-tracking-system.md
  • Plan: specs/hr/HR-09-applicant-tracking-system-PLAN.md
  • Constitution: constitution.md §5.7 (RLS patterns)
  • Integration Overview: docs/architecture/integrations/index.md