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.

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