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.

Version: 1.0.0
Last Updated: 2026-03-09
Spec: specs/hr/specs/HR-05-ENHANCEMENTS.md

Overview

HR-05 Enhancements extend Time & Attendance with geofencing (EN-03), real-time exception alerts (EN-08), and planned integrations with PTO (EN-05), Payroll (EN-06), and Scheduling (EN-04).

Integration Points

EN-03: Advanced Geofencing (✅ Implemented)

AspectDetail
Tablehr_site_geofence
PatternIntra-core (HR-05 ↔ HR punch validation)
DirectionHR Settings → Punch mutation reads geofence config
Cross-core?No — uses PF pf_sites via FK only

EN-08: Real-time Exception Alerts (✅ Implemented)

AspectDetail
PatternEvent (DB trigger → Edge Function → PF-10 notification)
Triggertrg_hr_time_exceptions_notify on hr_time_exceptions INSERT
Edge Functiontime-exception-notify
Channelhr_events (via PF-10 notification system)
Notification Typetimesheet_exception
RecipientEmployee’s manager (resolved via hr_employees.manager_id)

EN-05: PTO Integration (📝 Planned)

AspectDetail
PatternEvent-driven (HR-06 emits PTO-approved → HR-05 consumes)
DirectionHR-06 → HR-05
NoteHR-06 does not currently emit this event; producer side must be coordinated

EN-06: Automated Payroll Import (📝 Planned)

AspectDetail
PatternAPI (HR-07 pulls approved timesheets from HR-05 endpoint)
DirectionHR-05 → HR-07
NoteHR-07 consumer adoption is a separate coordination item

Event Contracts

EventPublisherSubscriberChannelStatus
hr_timesheet_exception_createdHR (DB trigger on hr_time_exceptions)time-exception-notify edge functionhr_events
pto.approvedHR-06HR-05 (planned consumer)domain_events📝

Payload Schema: hr_timesheet_exception_created

interface HrTimesheetExceptionCreatedPayload {
  event_type: 'hr_timesheet_exception_created';
  exception_id: string;       // UUID
  employee_id: string;        // UUID
  exception_type: string;     // e.g. 'missed_punch', 'overtime', 'geofence_violation'
  exception_date: string;     // ISO date
  organization_id: string;    // UUID — required for tenant isolation
  site_id?: string;           // UUID — optional site context
  timestamp: string;          // ISO 8601 timestamptz
  correlation_id?: string;    // UUID — optional for distributed tracing
}

SQL Trigger Implementation

The trigger trg_hr_time_exceptions_notify fires on INSERT to hr_time_exceptions and calls the hr_notify_time_exception() SECURITY DEFINER function, which:
  1. Retrieves supabase_functions_url and supabase_anon_key from the vault
  2. Skips notification if vault values are missing (fail-safe)
  3. POSTs to time-exception-notify edge function with the payload above

Testing

  • Unit: Verify time-exception-notify edge function handles valid/invalid payloads
  • Integration: Insert into hr_time_exceptions and verify notification created in pf_notifications
  • RLS: Confirm hr_time_exceptions policies enforce org isolation

Backward Compatibility

This event was introduced in the same PR as the trigger — no prior consumers exist. The rename from timesheet_exception_created to hr_timesheet_exception_created follows the canonical {core}_{entity}_{action} naming convention.

Security

  • All geofence operations scoped by organization_id via RLS + application-level filter
  • Exception notifications resolve recipients server-side (no client-side manager lookup)
  • Geofence CRUD gated by hr.geofence.view/create/update/delete permissions
  • Edge function time-exception-notify requires Authorization header