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

# Employee Directory & Org Structure — Integration

> Version: 1.0.0 Last Updated: 2026-03-20 Spec: HR-01 Employee Directory & Org Structure Constitution Reference: Section 1.2 (Core Independence), Section 1.3 (In…

**Version:** 1.0.0\
**Last Updated:** 2026-03-20\
**Spec:** [HR-01 Employee Directory & Org Structure](../../../specs/hr/specs/HR-01-employee-directory.md)\
**Constitution Reference:** Section 1.2 (Core Independence), Section 1.3 (Integration Patterns)

***

## Overview

HR-01 provides the foundational employee directory and organizational structure for the platform. It publishes lifecycle events for employee creation, site assignments, and terminations, and exposes read-only APIs for employee lookup and org chart data.

***

## Integration Points

### Platform Foundation (PF) Dependencies

**Required PF Features:**

* **PF-01 (Organizations & Sites)**: `organization_id`, `site_id` references for multi-tenancy
* **PF-02 (RBAC)**: `has_role()`, `has_org_access()` functions, `pf_user_roles` table for permission checks
* **PF-03 (App Launcher)**: HR module card in dashboard navigation
* **PF-04 (Audit Logging)**: Track employee record changes (create, update, terminate) via audit triggers
* **PF-06 (User Profile)**: Link `hr_employees.profile_id` to `pf_profiles`, avatar uploads via PF-11

**Integration Type:** Direct dependency (PF features are complete)

### Consumer Core Dependencies (Downstream)

**Internal HR Features:**

* **HR-02 (Credentialing)**: Links credentials to employees, filters by `is_clinical`
* **HR-03 (Onboarding)**: New hire workflow creates `hr_employees` record
* **HR-04 (Scheduling)**: Fetches employees for shift assignments, respects `primary_site_id`
* **HR-05 (Time Tracking)**: Clock in/out tied to `employee_id`
* **HR-06 (PTO)**: Leave requests reference `employee_id`
* **HR-07 (Payroll)**: Payroll processing uses `employment_type`, `is_exempt` fields

**External Cores:**

* **RH (Recovery Housing)**: Staff assignments for recovery housing sites (via event subscription)
* **FM (Facilities)**: Technician assignments for work orders (via employee lookup)
* **FA (Finance)**: Payroll processing (via employee lookup, future HR-07)

***

## Event Contracts

### Event: `hr_employee_created` (canonical)

**Publisher:** HR (HR-01)\
**Subscribers:** GR-01 (Policy Management)\
**Status:** 📝 Planned (Q2 2026)

**Purpose:** GR Core assigns default policies and training requirements to new employees

**Payload Schema:**

```typescript theme={null}
interface HrEmployeeCreatedPayload {
  event_type: 'hr_employee_created';
  employee_id: uuid;
  organization_id: uuid;
  department_id?: uuid;
  position_id?: uuid;
  hire_date: timestamp;
  is_clinical: boolean;
  timestamp: timestamptz;
}
```

**Note:** Event name follows canonical `{core}_{entity}_{action}` format. Legacy alias `employee_created` may be deprecated in favor of `hr_employee_created`.

### Event: `hr_employee_assigned_to_site`

**Publisher:** HR (HR-01)\
**Subscribers:** RH-01 (Recovery Housing)\
**Status:** 📝 Planned (Q1 2026)

**Purpose:** RH Core receives notifications when staff are assigned to recovery housing sites

**Payload Schema:**

```typescript theme={null}
interface HrEmployeeAssignedToSitePayload {
  event_type: 'hr_employee_assigned_to_site';
  employee_id: uuid;
  site_id: uuid;
  organization_id: uuid;
  assignment_date: timestamp;
  role: 'staff' | 'manager' | 'admin';
  department_id?: uuid;
  timestamp: timestamptz;
}
```

### Event: `hr_employee_terminated`

**Publisher:** HR (HR-01)\
**Subscribers:** HR-04 (Scheduling), HR-05 (Time Tracking), RH-01\
**Status:** 📝 Planned (Q2 2026)

**Purpose:** Remove employee from schedules, close time tracking, update site assignments

**Payload Schema:**

```typescript theme={null}
interface HrEmployeeTerminatedPayload {
  event_type: 'hr_employee_terminated';
  employee_id: uuid;
  organization_id: uuid;
  termination_date: timestamp;
  termination_reason?: string;
  timestamp: timestamptz;
}
```

***

## API Contracts

### API: Employee Lookup

**Endpoint:** RLS-enforced direct query to `hr_employees` table\
**Method:** Read-only via Supabase client\
**Provider:** HR (HR-01)\
**Consumers:** RH (staff assignments), FM (technician assignments), FA (payroll)\
**Status:** ✅ Available (RLS-enforced)

**Purpose:** Other cores can query employee data for assignments and payroll processing

**Access:** Read-only via RLS policies. All queries must include `organization_id` filter for defense-in-depth.

**Example:**

```typescript theme={null}
// Other cores query hr_employees (RLS enforces org isolation)
const employees = await supabase
  .from('hr_employees')
  .select('id, full_name, job_title, primary_site_id')
  .eq('organization_id', currentOrg.id)
  .eq('employment_status', 'active');
```

### API: Org Chart Data

**Endpoint:** RLS-enforced query to `hr_employees` with manager relationships\
**Method:** Read-only via Supabase client\
**Provider:** HR (HR-01)\
**Consumers:** PF-12 (Reports), Dashboards\
**Status:** ✅ Available

**Purpose:** Generate organizational charts and reporting structures

**Access:** Read-only via RLS policies. Manager relationships are stored in `hr_employees.manager_id`.

***

## Platform Integration Layer Usage

**Consumes:**

* **PF-11 (Document Management)**: Employee documents, credential storage (via HR-02)
* **PF-10 (Notifications)**: Employee-related notifications (via HR-02)
* **PF-12 (Reports)**: Employee directory reports, org charts

***

## Integration Examples

### Example 1: RH Core Subscribes to Employee Assignment Event

```typescript theme={null}
// In RH Core edge function or client
const channel = supabase
  .channel('employee-assignments')
  .on(
    'postgres_changes',
    {
      event: 'INSERT',
      schema: 'public',
      table: 'hr_employee_site_assignments',
    },
    async (payload) => {
      // Notify recovery housing site of new staff assignment
      await sendNotification({
        type: 'staff_assigned',
        site_id: payload.new.site_id,
        employee_id: payload.new.employee_id
      });
    }
  )
  .subscribe();
```

### Example 2: FA Core Queries Employee Data for Payroll

```typescript theme={null}
// In FA Core (payroll processing)
const employees = await supabase
  .from('hr_employees')
  .select('id, employment_type, is_exempt, primary_site_id')
  .eq('organization_id', currentOrg.id)
  .eq('employment_status', 'active');

// Process payroll for each employee
for (const employee of employees.data) {
  await processPayroll(employee.id, {
    employment_type: employee.employment_type,
    is_exempt: employee.is_exempt
  });
}
```

***

## Security Considerations

### Multi-Tenancy

* ✅ **RLS Enforcement**: All `hr_*` tables filtered by `organization_id` via RLS policies
* ✅ **Site Scoping**: Queries respect `site_id` for site-level admins
* ✅ **Cross-Org Isolation**: Platform admins can access all orgs, others cannot

### Role-Based Access Control

* ✅ **HR Admin**: Full access to all employee data (CRUD)
* ✅ **Manager**: View direct reports, limited update permissions
* ✅ **Staff**: View directory (active employees only), own profile

### Data Protection

* ✅ **PII Handling**: Employee contact information, emergency contacts protected by RLS
* ✅ **Audit Trail**: All employee record changes logged via PF-04

***

## Testing Requirements

* [ ] Event payload structure validation
* [ ] Event fires on trigger condition (employee creation, site assignment, termination)
* [ ] Correct `organization_id` included in all events
* [ ] Subscribers handle events correctly (GR-01, RH-01, HR-04, HR-05)
* [ ] RLS policies enforce org isolation on employee queries
* [ ] API consumers can query employee data with proper filters

***

## References

* [HR-01 Spec](../../../specs/hr/specs/HR-01-employee-directory.md)
* [EVENT\_CONTRACTS.md](./EVENT_CONTRACTS.md)
* [API\_CONTRACTS.md](./API_CONTRACTS.md)
* [CROSS\_CORE\_INTEGRATIONS.md](./CROSS_CORE_INTEGRATIONS.md)
