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

# ADR-011: Supabase Edge Functions on Deno Runtime

> The platform uses Supabase Edge Functions for server-side logic (298 functions across AI, auth, finance, HR, clinical, workflow, governance, integrations, noti…

**Status:** Accepted\
**Date:** 2026-04-12\
**Participants:** Platform Architecture Team

***

## Context

The platform uses Supabase Edge Functions for server-side logic (298 functions across AI, auth, finance, HR, clinical, workflow, governance, integrations, notifications, document generation, and data processing). Supabase Edge Functions run on the Deno runtime. The question was whether to use Deno (Supabase native) or to try to use a Node.js-compatible approach.

## Options Considered

### Option A: Node.js-style functions (non-native)

* **How it works:** Write functions in a Node.js-compatible style; use polyfills or a compatibility layer for Deno.
* **Pros:** Familiar Node.js APIs; reuse npm packages directly.
* **Cons:** Supabase Edge Functions are Deno-native; fighting the platform adds complexity; Deno has native `fetch`, `Deno.serve()`, and TypeScript support without compilation; npm package compatibility in Deno is improving but not 100%.
* **Why not chosen:** Supabase Edge Functions are Deno-native. Using non-native patterns adds friction without benefit.

### Option B: Deno runtime (native) ✓

* **How it works:** Functions use `Deno.serve()` entry point; TypeScript natively supported; `_shared/` directory for cross-function utilities; npm packages via `npm:` specifier or `esm.sh`; CORS via `_shared/cors.ts`.
* **Pros:** Zero-config TypeScript; native `fetch`; fast cold starts; Supabase platform support; `_shared/` utilities shared across all 298 functions.
* **Cons:** Different module system than the main Vite app (ESM with URL imports vs npm); some npm packages don't work in Deno; `Deno.serve()` entry point differs from `export default` patterns in some tutorials.
* **Why chosen:** Deno is the native Supabase Edge Function runtime. The `_shared/` pattern (`_shared/cors.ts`, `_shared/auth.ts`, `_shared/supabase.ts`) provides excellent code reuse. Native TypeScript eliminates a build step.

## Decision

All Supabase Edge Functions use `Deno.serve()` as the entry point. Shared utilities live in `supabase/functions/_shared/` and are imported via relative paths. Authentication in functions uses `verifyOrgAccess()` or `verifyOrgRole()` from `_shared/auth.ts` (never inline `pf_user_role_assignments` queries). CORS is handled via `_shared/cors.ts`. Functions are tested with `npm run test:functions` (Deno test runner).

## Consequences

### Positive

* Native Supabase platform support
* Zero-config TypeScript in functions
* Shared utilities across 298 functions via `_shared/`
* `verifyOrgAccess()` centralizes auth + tenant isolation in edge functions

### Negative

* Different module system than the main app requires mental context switch
* Some npm packages require `npm:` prefix or `esm.sh` fallback
* Deno test runner differs from Vitest used in the main app

### Mitigations

* `_shared/` directory with pre-built auth, CORS, Supabase client helpers
* `edge-functions.md` Cursor rule documents Deno patterns
* AGENTS.md "What AI Must Never Do" explicitly prohibits inline `pf_user_role_assignments` queries

## Related Documents

* [.cursor/rules/edge-functions.md](https://github.com/Encore-OS/encoreos/blob/development/.cursor/rules/edge-functions.md) — Deno patterns
* [AGENTS.md](https://github.com/Encore-OS/encoreos/blob/development/AGENTS.md) — "use `verifyOrgAccess()` or `verifyOrgRole()` from `_shared/auth.ts`"
* [supabase/functions/\_shared/](https://github.com/Encore-OS/encoreos/tree/development/supabase/functions/_shared) — shared utilities
