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.2.0 Last Updated: 2026-03-23 Total Functions: 294 (deployable folders under supabase/functions/, excluding _shared. Refresh count: npm run docs:edge-functions-count from repo root.) Reference for Supabase Edge Functions in this repo: deployment, shared code, env/secrets, and patterns. Functions cover integrations, async work, and backend processing.

Table of Contents

  1. Overview
  2. Architecture
  3. Shared Code
  4. Deployment
  5. Environment Variables & Secrets
  6. Error Handling
  7. Testing
  8. Monitoring & Logging
  9. Function Reference

Overview

Edge functions are Deno-based serverless functions deployed to Supabase that handle:
  • Complex business logic processing
  • External API integrations (email, SMS, AI)
  • Async workflows and automation
  • Scheduled task execution
  • Data transformation and aggregation
  • Testing and development utilities
Key Characteristics:
  • Deno runtime (not Node.js)
  • Serverless execution
  • Automatic scaling
  • CORS support
  • JWT verification (configurable per function)

Architecture

Function Structure

supabase/functions/
├── _shared/                    # Shared utilities
│   ├── cors.ts                 # CORS headers
│   ├── errors.ts               # Error response utilities
│   ├── logger.ts               # Structured logging
│   ├── expressionEvaluator.ts  # Expression evaluation
│   └── executionHelpers.ts     # Execution utilities
├── {function-name}/
│   └── index.ts                # Function entry point

Calling Patterns

1. Direct HTTP Invocation:
const response = await fetch(
  `${supabaseUrl}/functions/v1/{function-name}`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${anonKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(payload),
  }
);
2. Database Trigger → Edge Function:
-- Trigger calls edge function via pg_net
CREATE OR REPLACE FUNCTION {core}_trigger_edge_function()
RETURNS TRIGGER LANGUAGE plpgsql SECURITY DEFINER AS $$
BEGIN
  PERFORM net.http_post(
    url := '{supabase_url}/functions/v1/{function-name}',
    headers := jsonb_build_object(
      'Authorization', 'Bearer ' || service_key,
      'Content-Type', 'application/json'
    ),
    body := jsonb_build_object(
      'record_id', NEW.id,
      'organization_id', NEW.organization_id,
      'action', TG_OP
    )
  );
  RETURN NEW;
END;
$$;
3. Scheduled Task (pg_cron):
SELECT cron.schedule(
  '{core}-{task-name}',
  '0 6 * * *',  -- 6 AM daily
  $$SELECT net.http_post(
    url:='{supabase_url}/functions/v1/{function-name}',
    headers:='{"Authorization": "Bearer {service_key}"}'::jsonb,
    body:='{"task": "{task-name}"}'::jsonb
  )$$
);

Shared Code

Shared utilities are located in supabase/functions/_shared/ to avoid code duplication.

CORS Headers (_shared/cors.ts)

Standard CORS headers for all functions:
import { corsHeaders } from '../_shared/cors.ts';

// Use in responses
return new Response(JSON.stringify(data), {
  headers: { ...corsHeaders, 'Content-Type': 'application/json' }
});

Error Handling (_shared/errors.ts)

Standardized error responses with correlation IDs:
import { createErrorResponse, ErrorCategory, createValidationError } from '../_shared/errors.ts';

// Standard error
return createErrorResponse(
  'Configuration error',
  ErrorCategory.CONFIG,
  correlationId,
  400
);

// Validation error (400)
return createValidationError('Invalid input', correlationId, { field: 'email' });
Error Categories:
  • CONFIG - Configuration errors
  • VALIDATION - Input validation errors
  • AUTHORIZATION - Permission errors
  • NOT_FOUND - Resource not found
  • RUNTIME - Runtime errors
  • TIMEOUT - Operation timeout
  • EXTERNAL_SERVICE - External API errors

Logging (_shared/logger.ts)

Structured logging with PHI protection:
import { createLogger } from '../_shared/logger.ts';

const logger = createLogger('function-name');
const correlationId = crypto.randomUUID();

logger.info('Request received', { correlationId, userId: 'uuid' });
logger.error('Operation failed', { correlationId, error: err.message });
Never logs PHI/PII - only stable IDs (user_id, org_id, etc.)

Expression Evaluator (_shared/expressionEvaluator.ts)

Expression evaluation for workflow automation:
import { evaluateExpression, resolveTemplate } from '../_shared/expressionEvaluator.ts';

// Evaluate condition
const result = evaluateExpression('{{field1}} > 100', context);

// Resolve template
const message = resolveTemplate('Hello {{name}}', context);

Deployment

Local Development

# Start Supabase locally
supabase start

# Serve all functions locally (omit function name to serve all; hot-reload is default)
supabase functions serve

# Or serve a single function
supabase functions serve {function-name}

# Test function (anon key from npx supabase status when using local)
curl -i --location --request POST 'http://localhost:54321/functions/v1/{function-name}' \
  --header 'Authorization: Bearer {anon-key}' \
  --header 'Content-Type: application/json' \
  --data '{"test": "data"}'
Full workflow, debugging with breakpoints (inspect mode), and Deno unit tests: See EDGE_AND_API_TESTING.md.

Production Deployment

# Deploy single function
supabase functions deploy {function-name}

# Deploy all functions
supabase functions deploy

# Deploy with secrets
supabase secrets set GMAIL_SERVICE_ACCOUNT_JSON='...'
supabase functions deploy send-email-notification

JWT Verification

Configure JWT verification in supabase/config.toml:
[functions.{function-name}]
verify_jwt = true  # Require valid JWT
# or
verify_jwt = false  # No JWT required (for scheduled tasks, webhooks)
Functions with verify_jwt = true:
  • execute-report
  • process-entity-mapping
  • ai-assistant
  • workflow-debug-control
  • sandbox-execute
  • test-* functions
  • ai-document-analyze
  • workflow-metrics-aggregate
  • workflow-path-aggregate
  • workflow-version-compare
Functions with verify_jwt = false:
  • Scheduled tasks (cron jobs)
  • Database trigger invocations
  • Batch processing functions

Environment Variables & Secrets

Required Secrets

Supabase (Auto-provided):
  • SUPABASE_URL - Project URL
  • SUPABASE_SERVICE_ROLE_KEY - Service role key
Email (Entra ID or Gmail):
  • ENTRA_CLIENT_SECRET - For Entra/Graph API email (optional)
  • GMAIL_SERVICE_ACCOUNT_JSON - For Gmail API org-level email (optional)
  • Per-org config in Settings → Integrations; send-email-notification and others use shared email-provider
SMS (Twilio):
  • TWILIO_ACCOUNT_SID - Twilio account SID (for send-sms-notification)
  • TWILIO_AUTH_TOKEN - Twilio auth token
  • TWILIO_PHONE_NUMBER - Twilio phone number
AI (OpenRouter) - PF-59:
  • OPENROUTER_API_KEY - OpenRouter API key (for ai-assistant, ai-document-analyze, generate-report-narrative)
  • APP_URL - Application URL for OpenRouter HTTP-Referer attribution (defaults to https://encoreos.io)

Setting Secrets

# Set secrets (email: Entra and/or Gmail)
supabase secrets set ENTRA_CLIENT_SECRET=xxxxx
supabase secrets set GMAIL_SERVICE_ACCOUNT_JSON='{"type":"service_account",...}'

# List secrets
supabase secrets list

# Unset secret
supabase secrets unset GMAIL_SERVICE_ACCOUNT_JSON
Never commit secrets to version control!

Error Handling

All functions should:
  1. Handle CORS preflight requests
  2. Use standardized error responses
  3. Include correlation IDs for tracing
  4. Never expose PHI/PII in errors
  5. Return appropriate HTTP status codes
Standard Error Response:
{
  "success": false,
  "error": "User-friendly error message",
  "category": "validation",
  "correlationId": "uuid",
  "details": {
    "field": "email",
    "expected": "valid email"
  }
}
Success Response:
{
  "success": true,
  "data": { ... },
  "correlationId": "uuid"
}

Testing

Unit Testing Edge Functions

Tests are co-located with functions, e.g. supabase/functions/<name>/index.test.ts or <name>_test.ts. Examples: generate-templated-pdf/index.test.ts, hr-encrypt-bank-account/index_test.ts. Environment: Set VITE_SUPABASE_URL or SUPABASE_URL to http://localhost:54321 and the anon key (from npx supabase status) when testing against local. Some tests also use VITE_SUPABASE_PUBLISHABLE_KEY or TEST_AUTH_TOKEN. Run from repo root: npm run test:functions (runs deno test for all Edge Function tests). Or run deno test --allow-all from a function directory.
// test_edge_function.ts
import { assertEquals } from 'https://deno.land/std@0.168.0/testing/asserts.ts';

Deno.test('function handles valid input', async () => {
  const response = await fetch('http://localhost:54321/functions/v1/{function-name}', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${Deno.env.get('VITE_SUPABASE_PUBLISHABLE_KEY')}` },
    body: JSON.stringify({ test: 'data' }),
  });

  const data = await response.json();
  assertEquals(data.success, true);
});
Debugging: Run npm run supabase:functions:serve:inspect, then open Chrome → chrome://inspect → Configure 127.0.0.1:8083 → Open dedicated DevTools for Node. Trigger a function to pause on first line and use breakpoints. See EDGE_AND_API_TESTING.md.

Integration Testing

Test functions with real database:
  • Use test database with seed data
  • Verify RLS policies are enforced
  • Test error scenarios
  • Verify logging output

Troubleshooting (Edge Functions)

  • 401/403 locally: Missing or invalid Authorization header; confirm anon key or user JWT; check verify_jwt if used.
  • Import errors: Use npm: or jsr: specifiers and pin versions.
  • File writes: Only under /tmp.
  • Hanging requests: Unawaited Promises; offload background work with EdgeRuntime.waitUntil(promise).
Full checklist: EDGE_AND_API_TESTING.md.

Monitoring & Logging

Logging Best Practices

  1. Use structured logging:
    logger.info('Processing request', { correlationId, userId, orgId });
    
  2. Never log PHI/PII:
    • logger.info('Processing user', { name: 'John Doe', ssn: '123-45-6789' });
    • logger.info('Processing user', { userId: 'uuid', orgId: 'uuid' });
  3. Include correlation IDs:
    • Generate UUID for each request
    • Include in all log entries
    • Return in response headers
  4. Log levels:
    • debug - Development debugging
    • info - Normal operations
    • warn - Warning conditions
    • error - Error conditions

Monitoring

  • Supabase Dashboard: View function logs and metrics
  • Error Tracking: Integrate with Sentry/LogRocket
  • Performance: Monitor execution time and memory usage
  • Alerts: Set up alerts for error rates > 1%

Function Reference

Platform Foundation Functions

admin-reset-password

Purpose: Admin-initiated password reset for users Input:
{
  "userId": "uuid",
  "newPassword": "string",
  "resetBy": "uuid"
}
Output:
{
  "success": true,
  "message": "Password reset successfully"
}
Environment Variables: None (uses Supabase Auth) JWT Verification: true (admin only) Related Tables: auth.users, pf_profiles Error Codes:
  • 400 - Invalid input
  • 403 - Insufficient permissions
  • 404 - User not found
  • 500 - Reset failed

ai-assistant

Purpose: AI chat integration via OpenRouter (PF-59) Model Selection: Automatic based on moduleContext.module:
  • gr, hranthropic/claude-3.5-sonnet (compliance/policy reasoning)
  • fa, fw, rh, pf, ceopenai/gpt-4o (general analysis)
  • lo, fmopenai/gpt-4o-mini (fast summaries)
Input:
{
  "messages": [
    { "role": "user", "content": "..." }
  ],
  "moduleContext": {
    "module": "hr",
    "feature": "credentialing"
  },
  "stream": true
}
Output (Streaming): SSE stream with Content-Type: text/event-stream Output (Non-Streaming):
{
  "content": "AI response text",
  "usage": {
    "prompt_tokens": 100,
    "completion_tokens": 200,
    "total_tokens": 300,
    "cost": 0.003
  },
  "model": "openai/gpt-4o"
}
Environment Variables:
  • OPENROUTER_API_KEY (required)
  • APP_URL (optional, defaults to https://encoreos.io)
JWT Verification: true PHI Protection: Automatically detects and logs PHI patterns in prompts Rate Limiting: Exponential backoff retry on 429 (1s, 2s, 4s, max 30s) Error Codes:
  • 401 - Authentication required
  • 402 - AI credits depleted
  • 403 - User not in organization
  • 429 - Rate limited (auto-retry)
  • 500 - Service error
Shared Utilities: supabase/functions/_shared/ai-utils.ts Related Documentation:
  • specs/pf/PF-27-platform-ai.md
  • specs/pf/PF-59-ai-provider-migration.md
  • src/platform/ai/README.md

ai-document-analyze

Purpose: Analyze documents using AI via OpenRouter (PF-59) Model: openai/gpt-4o (optimized for structured output with tool calling) Input:
{
  "fileBase64": "base64-encoded-content",
  "fileName": "document.pdf",
  "fileType": "application/pdf",
  "analysisPrompt": "Extract key information from this document",
  "toolSchema": {
    "name": "extract_document_info",
    "description": "Extract key information",
    "parameters": {
      "type": "object",
      "properties": { ... },
      "required": [ ... ],
      "additionalProperties": false
    }
  },
  "moduleContext": {
    "module": "hr",
    "entityType": "credential",
    "entityId": "uuid"
  }
}
Output:
{
  "result": { ... },
  "model": "openai/gpt-4o"
}
Environment Variables:
  • OPENROUTER_API_KEY (required)
  • APP_URL (optional)
JWT Verification: true Multimodal Support: Images (base64), PDFs, text documents Rate Limiting: Exponential backoff retry on 429 Error Codes:
  • 400 - Missing required fields
  • 402 - AI credits exhausted
  • 429 - Rate limited
  • 500 - Service error
Related Tables: pf_documents, pf_ai_usage_logs Related Documentation: specs/pf/PF-59-ai-provider-migration.md

event-consumer

Purpose: Route domain events to appropriate handlers Input:
{
  "event_type": "leave_approved" | "credential_expired" | ...,
  "payload": {
    "organizationId": "uuid",
    "entityId": "uuid",
    "timestamp": "ISO8601",
    ...
  }
}
Output:
{
  "success": true,
  "handled": true,
  "handler": "leave_approved_handler"
}
JWT Verification: false (called by database triggers) Event Handlers:
  • leave_approved → Updates leave balances
  • leave_cancelled → Reverses leave balance changes
  • Future: credential_expired, onboarding_completed
Related Documentation: docs/architecture/integrations/EVENT_CONTRACTS.md

execute-report

Purpose: Execute report definitions and return results Input:
{
  "reportId": "uuid",
  "organizationId": "uuid",
  "parameters": {
    "startDate": "2025-01-01",
    "endDate": "2025-01-31",
    ...
  }
}
Output:
{
  "success": true,
  "data": [ ... ],
  "metadata": {
    "rowCount": 100,
    "executionTime": 1.23
  }
}
JWT Verification: true Related Tables: pf_report_definitions, pf_report_history

send-email-notification

Purpose: Send email notifications via org-configured provider (Entra or Gmail) Input:
{
  "notificationId": "uuid",
  "recipientEmail": "user@example.com",
  "recipientName": "John Doe",
  "subject": "Notification Subject",
  "body": "Email body with {{variables}}",
  "variables": {
    "name": "John",
    "action": "approved"
  }
}
Output:
{
  "success": true,
  "messageId": "entra-|gmail-<id>",
  "sentAt": "2025-01-07T10:00:00Z"
}
Environment Variables:
  • ENTRA_CLIENT_SECRET or GMAIL_SERVICE_ACCOUNT_JSON (per org config; see EMAIL_SMS_SETUP.md)
JWT Verification: false (called by notification system) Error Codes:
  • 400 - Invalid email or template
  • 500 - Email provider (Entra/Gmail) API error
Related Tables: pf_notifications

send-sms-notification (deprecated)

Status: Deprecated. Forwards to sms-send. Use sms-send directly with body { organizationId, toNumber, body, mergeData? }. Purpose: Legacy SMS notifications (Twilio-only). Now a thin wrapper that invokes sms-send and updates pf_notifications delivery status. Input: notificationId, phoneNumber, message, variables?, organizationId? (optional; if omitted, looked up from pf_notifications by notificationId). Output: Same shape as before: { success, messageId, notificationId, status } for backward compatibility. Migration: Call sms-send with organizationId (from notification or context), toNumber = phoneNumber, body = message after variable substitution, mergeData = variables. After 30 days with no callers, this function will be removed.

send-pending-notifications

Purpose: Batch process pending notifications (email and SMS) Input:
{
  "organizationId": "uuid",
  "limit": 100
}
Output:
{
  "success": true,
  "processed": 50,
  "succeeded": 48,
  "failed": 2,
  "results": [ ... ]
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Related Tables: pf_notifications

Forms & Workflow Functions

aggregate-form-analytics

Purpose: Aggregate form submission analytics Input:
{
  "formId": "uuid",
  "organizationId": "uuid",
  "dateRange": {
    "start": "2025-01-01",
    "end": "2025-01-31"
  }
}
Output:
{
  "success": true,
  "analytics": {
    "totalSubmissions": 100,
    "completionRate": 0.85,
    "averageTime": 120,
    "fieldAnalytics": { ... }
  }
}
JWT Verification: false Related Tables: fw_form_submissions, fw_form_analytics

automation-executor

Purpose: Execute automation rules and workflows (FW-03, FW-06, FW-18) Input:
{
  "trigger_type": "form_submitted" | "form_updated" | "schedule" | "webhook",
  "submission_id": "uuid",
  "form_id": "uuid",
  "organization_id": "uuid",
  "submission_data": { ... }
}
Output:
{
  "success": true,
  "executed": true,
  "rulesExecuted": 3,
  "actionsExecuted": 5
}
JWT Verification: false (called by database triggers) Features:
  • Condition evaluation
  • Action execution (email, notification, update, webhook)
  • Workflow graph execution (FW-06)
  • Variable management (FW-18)
  • Retry logic
  • Circuit breaker
Idempotency (R7): When invoked with execution_id or event_id, the executor MUST check if that id has already been processed (e.g. in fw_workflow_executions or a processed-events store) and skip duplicate execution. Use exponential backoff (1s, 2s, 4s) on transient failures; handlers must be safe when invoked more than once. Related Tables: fw_automation_rules, fw_workflows, fw_automation_logs Related Documentation: specs/fw/specs/FW-03-automation-engine.md, specs/fw/specs/FW-06-visual-workflows.md

process-entity-mapping

Purpose: Create/update entity records from form submissions (FW-03/PF-16) Input:
{
  "submissionData": {
    "field1": "value1",
    "field2": "value2"
  },
  "actionConfig": {
    "targetEntity": "hr_employees",
    "operation": "create" | "update" | "upsert",
    "lookupField": "email",
    "fieldMappings": [
      {
        "formField": "email",
        "entityField": "email",
        "isCustomField": false
      },
      {
        "formField": "badge_number",
        "entityField": "custom_fields.badge_number",
        "isCustomField": true
      }
    ]
  },
  "organizationId": "uuid",
  "userId": "uuid"
}
Output:
{
  "success": true,
  "entityId": "uuid",
  "operation": "created",
  "mappedFields": 5
}
JWT Verification: true Features:
  • Maps form fields to entity columns
  • Supports custom_fields JSONB mapping
  • Handles create/update/upsert operations
  • Template variable resolution
Related Tables: All entity tables with custom_fields Related Documentation: specs/fw/specs/FW-03-automation-engine.md

validate-form-submission

Purpose: Validate form submissions before processing Input:
{
  "formId": "uuid",
  "submissionData": { ... },
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "valid": true,
  "errors": []
}
JWT Verification: false Related Tables: fw_forms, fw_form_submissions

workflow-debug-control

Purpose: Debug workflow execution (enable/disable, step through) Input:
{
  "action": "enable" | "disable" | "step",
  "workflowId": "uuid",
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "debugMode": "enabled",
  "currentStep": "node-123"
}
JWT Verification: true (admin only) Related Tables: fw_workflows, fw_workflow_runs

workflow-metrics-aggregate

Purpose: Aggregate workflow performance metrics Input:
{
  "workflowId": "uuid",
  "organizationId": "uuid",
  "dateRange": {
    "start": "2025-01-01",
    "end": "2025-01-31"
  }
}
Output:
{
  "success": true,
  "metrics": {
    "totalRuns": 100,
    "averageDuration": 2.5,
    "successRate": 0.95,
    "errorRate": 0.05
  }
}
JWT Verification: true Related Tables: fw_workflow_runs, fw_workflow_metrics

workflow-notification-trigger

Purpose: Trigger notifications from workflow nodes Input:
{
  "workflowRunId": "uuid",
  "nodeId": "uuid",
  "notificationConfig": {
    "type": "email" | "sms" | "in_app",
    "recipient": "uuid",
    "template": "..."
  }
}
Output:
{
  "success": true,
  "notificationId": "uuid"
}
JWT Verification: false (called by workflow executor) Related Tables: fw_workflow_runs, pf_notifications

workflow-path-aggregate

Purpose: Aggregate workflow execution paths for analytics Input:
{
  "workflowId": "uuid",
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "paths": [
    {
      "path": ["start", "condition", "action"],
      "count": 50,
      "averageDuration": 2.3
    }
  ]
}
JWT Verification: true Related Tables: fw_workflow_runs

workflow-version-compare

Purpose: Compare workflow versions for changes Input:
{
  "workflowId": "uuid",
  "version1": 1,
  "version2": 2,
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "changes": {
    "nodesAdded": 2,
    "nodesRemoved": 1,
    "nodesModified": 3,
    "edgesChanged": 5
  }
}
JWT Verification: true Related Tables: fw_workflows, fw_workflow_versions

HR Functions

export-employee-list

Purpose: Export employee list to CSV/Excel Input:
{
  "organizationId": "uuid",
  "filters": {
    "departmentId": "uuid",
    "status": "active"
  },
  "format": "csv" | "xlsx"
}
Output:
{
  "success": true,
  "fileUrl": "https://storage.supabase.co/...",
  "fileName": "employees_2025-01-07.csv",
  "rowCount": 150
}
JWT Verification: true Related Tables: hr_employees, pf_departments

export-payroll-data

Purpose: Export payroll data for external payroll systems Input:
{
  "organizationId": "uuid",
  "payPeriod": {
    "start": "2025-01-01",
    "end": "2025-01-15"
  },
  "format": "csv" | "adp" | "paychex"
}
Output:
{
  "success": true,
  "fileUrl": "https://storage.supabase.co/...",
  "fileName": "payroll_2025-01-07.csv",
  "employeeCount": 50
}
JWT Verification: true (admin only) Related Tables: hr_timesheets, hr_employees, hr_payroll_exports

generate-schedule

Purpose: Generate shift schedules based on templates and availability Input:
{
  "organizationId": "uuid",
  "siteId": "uuid",
  "startDate": "2025-01-07",
  "endDate": "2025-01-21",
  "templateId": "uuid"
}
Output:
{
  "success": true,
  "shiftsCreated": 84,
  "coverage": {
    "totalHours": 672,
    "requiredHours": 700,
    "coveragePercent": 96
  }
}
JWT Verification: false (scheduled task) Related Tables: hr_shift_templates, hr_shifts, hr_employee_availability

generate-timesheets

Purpose: Generate timesheets for pay period Input:
{
  "organizationId": "uuid",
  "payPeriod": {
    "start": "2025-01-01",
    "end": "2025-01-15"
  },
  "employeeIds": ["uuid"] // Optional: specific employees
}
Output:
{
  "success": true,
  "timesheetsCreated": 50,
  "totalHours": 3200,
  "overtimeHours": 150
}
JWT Verification: false (scheduled task) Scheduled: Weekly (Sunday) via pg_cron Related Tables: hr_timesheets, hr_time_entries, hr_employees Database Function: calculate_timesheet_hours()

process-leave-accruals

Purpose: Process leave accruals for all employees Input:
{
  "organizationId": "uuid",
  "accrualDate": "2025-01-01"
}
Output:
{
  "success": true,
  "employeesProcessed": 100,
  "accrualsApplied": 150,
  "totalHoursAccrued": 300
}
JWT Verification: false (scheduled task) Scheduled: Monthly (1st of month) via pg_cron Related Tables: hr_leave_balances, hr_leave_policies, hr_employees

process-swap-request

Purpose: Process shift swap requests and approvals Input:
{
  "swapRequestId": "uuid",
  "action": "approve" | "reject" | "auto_approve",
  "approvedBy": "uuid"
}
Output:
{
  "success": true,
  "status": "approved",
  "shiftsSwapped": 2
}
JWT Verification: false (called by application) Related Tables: hr_shift_swaps, hr_shifts

send-credential-alerts

Purpose: Send alerts for expiring credentials Input:
{
  "organizationId": "uuid",
  "alertDays": [90, 60, 30, 14, 7]
}
Output:
{
  "success": true,
  "alertsSent": 25,
  "expiringCredentials": [
    {
      "credentialId": "uuid",
      "employeeId": "uuid",
      "daysUntilExpiry": 30
    }
  ]
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Related Tables: hr_employee_credentials, hr_employees, pf_notifications

validate-shift-assignment

Purpose: Validate shift assignments (credentials, availability, conflicts) Input:
{
  "shiftId": "uuid",
  "employeeId": "uuid",
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "valid": true,
  "warnings": [],
  "errors": []
}
JWT Verification: false (called by application) Validation Checks:
  • Employee has required credentials
  • Employee is available (no conflicts)
  • Shift doesn’t exceed max hours
  • Site access permissions
Related Tables: hr_shifts, hr_employees, hr_employee_credentials

Finance Functions

check-budget-alerts

Purpose: Check budgets and create alerts for threshold breaches Input:
{
  "organizationId": "uuid",
  "thresholdPercent": 10.0
}
Output:
{
  "success": true,
  "totalAlerts": 5,
  "organizationsChecked": 10,
  "results": [
    {
      "org_id": "uuid",
      "success": true,
      "alerts_created": 2
    }
  ]
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Database Function: fa_check_budget_alerts() Related Tables: fa_budgets, fa_budget_alerts, pf_organizations

FA scheduled reports (via execute-scheduled-reports)

Purpose: Execute scheduled Finance & Accounting reports. Use the unified execute-scheduled-reports function with body { module: 'fa' }. Input: Same as execute-scheduled-reports with module: 'fa' in the request body. Cron callers should invoke execute-scheduled-reports with { "module": "fa" }. Related Tables: fa_report_schedules, fa_report_runs, fa_get_due_scheduled_reports (RPC)

generate-fa-report-export

Purpose: Generate Finance report exports (PDF, Excel, CSV) Input:
{
  "reportId": "uuid",
  "format": "pdf" | "xlsx" | "csv",
  "organizationId": "uuid"
}
Output:
{
  "success": true,
  "fileUrl": "https://storage.supabase.co/...",
  "fileName": "trial_balance_2025-01-07.pdf"
}
JWT Verification: false Related Tables: fa_reports, pf_documents

parse-bank-statement

Purpose: Parse bank statement files (CSV, OFX, QIF) and extract transactions Input:
{
  "fileUrl": "https://storage.supabase.co/...",
  "organizationId": "uuid",
  "accountId": "uuid",
  "format": "csv" | "ofx" | "qif"
}
Output:
{
  "success": true,
  "transactionsParsed": 150,
  "transactionsCreated": 145,
  "duplicatesSkipped": 5,
  "transactions": [ ... ]
}
JWT Verification: false Related Tables: fa_bank_accounts, fa_transactions

query-payment-status

Purpose: Query payment status from payment processors Input:
{
  "paymentId": "uuid",
  "organizationId": "uuid",
  "processor": "stripe" | "paypal" | "ach"
}
Output:
{
  "success": true,
  "status": "completed" | "pending" | "failed",
  "processorResponse": { ... }
}
JWT Verification: false Related Tables: fa_payments, fa_invoices

trigger-invoice-creation

Purpose: Trigger invoice creation from resident charges or other events Input:
{
  "chargeId": "uuid",
  "organizationId": "uuid",
  "residentId": "uuid"
}
Output:
{
  "success": true,
  "invoiceId": "uuid",
  "invoiceNumber": "INV-2025-001"
}
JWT Verification: false (called by database triggers) Related Tables: fa_invoices, rh_resident_charges, rh_residents

Recovery Housing Functions

rh-charge-invoice

Purpose: Create invoices from resident charges Input:
{
  "residentId": "uuid",
  "organizationId": "uuid",
  "chargeIds": ["uuid"],
  "invoiceDate": "2025-01-07"
}
Output:
{
  "success": true,
  "invoiceId": "uuid",
  "invoiceNumber": "INV-2025-001",
  "totalAmount": 1500.00
}
JWT Verification: false Related Tables: fa_invoices, rh_resident_charges, rh_residents

Facilities Functions

check-overdue-pms

Purpose: Check for overdue preventive maintenance tasks Input:
{
  "organizationId": "uuid",
  "siteId": "uuid" // Optional
}
Output:
{
  "success": true,
  "overdueCount": 5,
  "overdueTasks": [
    {
      "pmScheduleId": "uuid",
      "dueDate": "2025-01-01",
      "daysOverdue": 6
    }
  ]
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Related Tables: fm_pm_schedules, fm_work_orders

check-vendor-certifications

Purpose: Check vendor certifications for expiration Input:
{
  "organizationId": "uuid",
  "alertDays": [90, 60, 30]
}
Output:
{
  "success": true,
  "expiringCertifications": [
    {
      "vendorId": "uuid",
      "certificationId": "uuid",
      "daysUntilExpiry": 30
    }
  ],
  "alertsCreated": 3
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Related Tables: fm_vendors, fm_vendor_certifications, pf_notifications

generate-pm-work-orders

Purpose: Generate work orders from PM schedules Input:
{
  "organizationId": "uuid",
  "pmScheduleId": "uuid", // Optional: specific schedule
  "dueDate": "2025-01-07"
}
Output:
{
  "success": true,
  "workOrdersCreated": 10,
  "workOrderIds": ["uuid"]
}
JWT Verification: false (scheduled task) Scheduled: Daily via pg_cron Related Tables: fm_pm_schedules, fm_work_orders

Testing Functions

calculate-test-coverage

Purpose: Calculate test coverage metrics Input:
{
  "organizationId": "uuid",
  "testSuite": "unit" | "integration" | "rls" | "all"
}
Output:
{
  "success": true,
  "coverage": {
    "unit": 0.85,
    "integration": 0.72,
    "rls": 0.95,
    "overall": 0.84
  }
}
JWT Verification: true (admin only) Related Tables: Test results database

sandbox-execute

Purpose: Execute code in sandboxed environment for testing Input:
{
  "code": "function test() { return 1 + 1; }",
  "language": "typescript" | "javascript"
}
Output:
{
  "success": true,
  "result": 2,
  "executionTime": 0.05
}
JWT Verification: true (admin only) Security: Sandboxed execution, no file system access

test-cases-run

Purpose: Run test cases and return results Input:
{
  "testSuite": "unit" | "integration" | "rls",
  "testFiles": ["test1.ts", "test2.ts"] // Optional
}
Output:
{
  "success": true,
  "results": {
    "passed": 50,
    "failed": 2,
    "skipped": 1,
    "duration": 12.5
  },
  "failures": [ ... ]
}
JWT Verification: true (admin only)

test-datasets-import

Purpose: Import test datasets for testing Input:
{
  "dataset": "employees" | "residents" | "transactions",
  "organizationId": "uuid",
  "count": 100
}
Output:
{
  "success": true,
  "recordsCreated": 100,
  "dataset": "employees"
}
JWT Verification: true (admin only) Note: Only works in development/staging environments

Reporting Functions

execute-scheduled-reports

Purpose: Execute scheduled reports for Platform (PF) or Finance (FA). Single function with request body module to route. Input:
{
  "module": "pf" | "fa",  // default "pf"
  "scheduleId": "uuid",   // optional, for PF: run specific schedule
  "manual": true,         // optional
  "source": "pg_cron"     // optional
}
For PF: queries pf_report_schedules, runs reports, emails via send-email-notification. For FA: calls fa_get_due_scheduled_reports, creates fa_report_runs, updates fa_report_schedules. Output:
{
  "success": true,
  "reportsExecuted": 5,
  "results": [ ... ]
}
JWT Verification: false (scheduled task) Scheduled: Daily/Weekly/Monthly via pg_cron Related Tables: pf_report_definitions, pf_report_history

generate-compliance-report

Purpose: Generate compliance reports (HR credentials, RH incidents, etc.) Input:
{
  "organizationId": "uuid",
  "reportType": "credential_compliance" | "incident_compliance",
  "dateRange": {
    "start": "2025-01-01",
    "end": "2025-01-31"
  }
}
Output:
{
  "success": true,
  "reportId": "uuid",
  "fileUrl": "https://storage.supabase.co/...",
  "findings": [ ... ]
}
JWT Verification: false Related Tables: hr_employee_credentials, rh_significant_events, pf_reports

generate-report-narrative

Purpose: Generate AI-powered narrative summaries for reports via OpenRouter (PF-59) Model: openai/gpt-4o (for detailed analysis and recommendations) Input:
{
  "reportTitle": "Monthly Financial Summary",
  "reportType": "financial",
  "data": {
    "totalRevenue": 125000,
    "totalExpenses": 98000,
    "metrics": [ ... ]
  },
  "dateRange": {
    "start": "2025-01-01",
    "end": "2025-01-31"
  },
  "options": {
    "includeInsights": true,
    "includeRecommendations": true,
    "tone": "formal",
    "maxLength": 500
  }
}
Output:
{
  "narrative": "Executive summary text with insights and recommendations...",
  "model": "openai/gpt-4o"
}
Environment Variables:
  • OPENROUTER_API_KEY (required)
  • APP_URL (optional)
JWT Verification: false (called by scheduled reports) Rate Limiting: Exponential backoff retry on 429 Error Codes:
  • 400 - Missing required fields
  • 402 - AI credits exhausted
  • 429 - Rate limited
  • 500 - Service error
Related Tables: pf_reports, pf_report_narratives, pf_ai_usage_logs Related Documentation: specs/pf/PF-59-ai-provider-migration.md

System Functions

process-alert-escalations

Purpose: Process alert escalations based on time and severity Input:
{
  "organizationId": "uuid",
  "alertType": "all" | "credential" | "budget" | "compliance"
}
Output:
{
  "success": true,
  "escalationsProcessed": 10,
  "escalatedAlerts": [ ... ]
}
JWT Verification: false (scheduled task) Scheduled: Hourly via pg_cron Related Tables: pf_alerts, pf_notifications

Function Categories Summary

CategoryCountFunctions
Platform Foundation8admin-reset-password, ai-assistant, ai-document-analyze, event-consumer, execute-report, send-email-notification, send-sms-notification, send-pending-notifications
Forms & Workflow9aggregate-form-analytics, automation-executor, process-entity-mapping, validate-form-submission, workflow-debug-control, workflow-metrics-aggregate, workflow-notification-trigger, workflow-path-aggregate, workflow-version-compare
HR8export-employee-list, export-payroll-data, generate-schedule, generate-timesheets, process-leave-accruals, process-swap-request, send-credential-alerts, validate-shift-assignment
Finance6check-budget-alerts, execute-scheduled-reports (module=fa), generate-fa-report-export, parse-bank-statement, query-payment-status, trigger-invoice-creation
Recovery Housing1rh-charge-invoice
Facilities3check-overdue-pms, check-vendor-certifications, generate-pm-work-orders
Testing4calculate-test-coverage, sandbox-execute, test-cases-run, test-datasets-import
Reporting3execute-scheduled-reports, generate-compliance-report, generate-report-narrative
System1process-alert-escalations
Total43
Note: Some functions may serve multiple purposes. Count reflects primary categorization. AI Functions (PF-59): The functions ai-assistant, ai-document-analyze, and generate-report-narrative use OpenRouter for AI capabilities with module-specific model selection. See supabase/functions/_shared/ai-utils.ts for model configuration.

Best Practices

1. Error Handling

  • Always use _shared/errors.ts for consistent error responses
  • Include correlation IDs for tracing
  • Never expose PHI/PII in error messages
  • Return appropriate HTTP status codes

2. Logging

  • Use _shared/logger.ts for structured logging
  • Include correlation IDs in all log entries
  • Never log PHI/PII (only stable IDs)
  • Use appropriate log levels

3. Security

  • Validate all inputs
  • Enforce JWT verification where appropriate
  • Use service role key only when necessary
  • Never expose secrets in responses

4. Performance

  • Keep execution time under 60 seconds (Supabase limit)
  • Use database functions for complex queries
  • Batch operations when possible
  • Handle timeouts gracefully

5. Testing

  • Test with real database (staging)
  • Verify RLS policies are enforced
  • Test error scenarios
  • Verify logging output

Troubleshooting

Common Issues

1. Function Timeout
  • Symptom: Function returns 504 after 60 seconds
  • Solution: Break into smaller functions, use database functions for heavy processing
2. CORS Errors
  • Symptom: Browser blocks requests
  • Solution: Ensure CORS headers are included in all responses
3. JWT Verification Failures
  • Symptom: 401 Unauthorized
  • Solution: Check verify_jwt setting in config.toml, ensure valid JWT in request
4. Missing Environment Variables
  • Symptom: Function fails with “not configured” error
  • Solution: Set secrets via supabase secrets set KEY=value
5. Database Connection Issues
  • Symptom: Function can’t connect to database
  • Solution: Verify SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY are set

  • Constitution: constitution.md §5.8-5.9 (Edge Function Patterns)
  • AI Guide: AI_GUIDE.md (Edge Function Patterns)
  • Integration Contracts: docs/architecture/integrations/EVENT_CONTRACTS.md
  • Supabase Setup: docs/integrations/SUPABASE_SETUP.md (when created)

Document Owner: Platform Team
Review Frequency: Quarterly
Last Updated: 2026-02-01