> ## 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.

# ATS Integration Contracts

> 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) La…

**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

| Event                  | Publisher | Payload Schema | Subscribers              | Status        |
| ---------------------- | --------- | -------------- | ------------------------ | ------------- |
| `hr_employee_hired`    | HR-09 ATS | See below      | HR-03 Onboarding, IT-08  | ✅ Implemented |
| `offer_accepted`       | HR-09 ATS | See below      | HR-01 Employee Directory | ✅ Implemented |
| `interview_scheduled`  | HR-09 ATS | See below      | PF-10 Notifications      | 📝 Planned    |
| `application_received` | HR-09 ATS | See below      | PF-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`

```typescript theme={null}
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)

```typescript theme={null}
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.

```typescript theme={null}
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.

```typescript theme={null}
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

| Event                  | Source | Handler                | Purpose                                       | Status     |
| ---------------------- | ------ | ---------------------- | --------------------------------------------- | ---------- |
| `employee_created`     | HR-01  | Link to application    | Associates employee with original application | 📝 Planned |
| `onboarding_completed` | HR-03  | Update hire transition | Marks 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:**

```typescript theme={null}
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:**

```typescript theme={null}
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.*

| API                             | Source | Purpose                             | Status      |
| ------------------------------- | ------ | ----------------------------------- | ----------- |
| `GET /api/v1/hr/employees`      | HR-01  | Interviewer lookup                  | ✅ Available |
| `GET /api/v1/hr/positions`      | HR-01  | Position selection for job postings | ✅ Available |
| `GET /api/v1/hr/departments`    | HR-01  | Department selection                | ✅ Available |
| `POST /api/v1/pf/notifications` | PF-10  | Send notifications                  | ✅ Available |
| `POST /api/v1/pf/documents`     | PF-11  | Store resumes, offer letters        | ✅ Available |

***

## Platform Integration Layer Usage

### PF-08 (Forms) Integration

**Location:** `@/platform/forms`\
**Purpose:** Application forms, interview feedback forms

**Usage:**

```typescript theme={null}
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:**

```sql theme={null}
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:**

```sql theme={null}
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:

```text theme={null}
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`
