Application & Edge Functions
The frontend, identity, and compute story, plus a full census of all 26 edge functions and where each one lands on Azure.
Edge Function Census (all 26)
Download .docx08 - Edge Function Census (all 26) + Azure Landing
The "what code runs off-database, and where does it go on Azure" doc. A full census of every CARR edge function, built from a read of each
supabase/functions/*/index.tson 2026-07-21. Companion to07_azure_sql_conversion.md(which covers the in-database code). The edge functions are the application logic that lives outside Postgres today and must be re-hosted on Azure compute.
Triggers: "edge functions", "how many functions", "deno functions", "what moves to azure functions", "ef census", "container apps".
Why this matters
CARR runs on Supabase Edge Functions (Deno / TypeScript). Azure has no Supabase-edge runtime, so all of this code must be re-hosted. The census below drives the compute side of the migration the same way the object census in 07 drives the data side. The prior pack said "19 Edge Functions" (05_carr_migration_map.md row 6); the live count carried into the migration is 26.
Excluded from the migration: the
sync-social-listeningfunction (LinkedIn post + engagement monitoring / ELG) is not part of this migration. Social listening was never fully built out on the BC side, so it is not being handed over or re-hosted. It is out of scope here and, if ever wanted, would be a separate future effort - not a migration deliverable.
How they land on Azure (the pattern)
The recommended internalization is one Azure Function per edge function (Node/TypeScript on the Functions runtime, or a Deno container on Azure Container Apps where we want to preserve the Deno code verbatim), fronted by:
- Azure Key Vault for every secret currently read from Supabase Vault (
get_vault_secret/vault_read). - Timer triggers (or Logic Apps schedules) for the pg_cron-driven syncs.
- HTTP triggers for the webhooks (Clay, EmailBison, HeyReach) and the UI-invoked functions.
- Microsoft Foundry Model Router for every AI call (replacing the direct Anthropic / OpenAI HTTP calls), giving BW one governed model endpoint with Entra identity + observability.
The AI functions are the cleanest win: the model call is a single fetch to a provider today, so repointing it at Foundry Model Router is a small, contained change per function.
Technical per-function census (for engineers)
Effort: S = ~1 day. M = ~2-4 days. L = ~1 week+. All secrets today resolve from Supabase Vault via get_vault_secret / vault_read, with an env-var fallback.
| # | Function | What it does | Trigger | External API | Secrets | Azure target | Effort |
|---|---|---|---|---|---|---|---|
| 1 | batch-generate-outreach |
Bulk-generates outreach messages by buying persona + ICP tier from campaign_goals |
UI / manual | Anthropic (primary), OpenAI (fallback) | ANTHROPIC_API_KEY, OPENAI_API_KEY | Azure Function + Foundry Model Router | M |
| 2 | generate-outreach-message |
On-demand single message (5 data layers: persona, enrichment, positioning, sender, category) | UI | Anthropic + OpenAI fallback | ANTHROPIC_API_KEY, OPENAI_API_KEY | Azure Function + Foundry Model Router | M |
| 3 | generate-content |
LinkedIn post / content generation with outreach_positioning context |
UI | Anthropic (Sonnet) | ANTHROPIC_API_KEY | Azure Function + Foundry | M |
| 4 | generate-carr-daily-brief |
AI daily intelligence brief from news + trials, banded include/exclude + editorial intro | cron / manual | Anthropic | ANTHROPIC_API_KEY | Azure Function (timer) + Foundry | M |
| 5 | generate-carr-newsletter |
Preview-only branded newsletter from client_news_intelligence |
manual | Anthropic (Sonnet 4.5) | ANTHROPIC_API_KEY | Azure Function + Foundry | S-M |
| 6 | validate-data-flag |
AI validation of a flagged data point via web search | UI | Brave Search, Anthropic | BRAVE_API_KEY, ANTHROPIC_API_KEY | Azure Function + Foundry + Bing/Grounding | M |
| 7 | validate-rep-note |
AI validation of a rep note via web scrape | UI | Firecrawl, Anthropic | FIRECRAWL_API_KEY, ANTHROPIC_API_KEY | Azure Function + Foundry | M |
| 8 | transcribe-audio |
Whisper transcription of rep voice notes | UI | OpenAI Whisper | OPENAI_API_KEY | Azure Function + Azure OpenAI Whisper / Speech | S |
| 9 | sync-emailbison |
Pulls Bison campaigns, contacts, accounts, stats into bison_* |
pg_cron (6h) | EmailBison | emailbison_api_key | Azure Function (timer) | M |
| 10 | push-to-emailbison |
Pushes ready_to_send email messages into Bison campaigns; emits Heart heartbeat |
pg_cron (2h) | EmailBison | emailbison_api_key | Azure Function (timer) | M |
| 11 | emailbison-webhook |
Inbound Bison events: opens, replies, bounces, OOO, unsubscribe; noise filtering | webhook | (inbound) | service role | Azure Function (HTTP) | M |
| 12 | emailbison-reply |
Sends a reply via Bison; stamps handoff-to-inbox; workspace-confinement guard | UI | EmailBison | emailbison_api_key | Azure Function | S |
| 13 | emailbison-forward |
Forwards a Bison lead/reply to a rep | UI | EmailBison | emailbison_api_key | Azure Function | S |
| 14 | carr-bison-reconcile |
Reconciles leads/stats for Bison campaigns 17-20 | manual / cron | EmailBison | emailbison_api_key | Azure Function (timer) | M |
| 15 | bison-camp-bump-limits |
PATCHes per-campaign daily send + new-lead limits | manual / admin | EmailBison | emailbison_api_key | Azure Function | S |
| 16 | bison-clear-campaign-leads |
Clears leads from a Bison campaign | manual | EmailBison | emailbison_api_key | Azure Function | S |
| 17 | bison-lead-inspect |
Inspects a single Bison lead (debug/support) | manual | EmailBison | emailbison_api_key | Azure Function | S |
| 18 | send-linkedin-messages |
Delivers ready_to_send LinkedIn messages via HeyReach |
pg_cron (2h) | HeyReach | heyreach_api_key, anon | Azure Function (timer) | M |
| 19 | sync-heyreach-accepted |
Safety-net poll for ConnectionAccepted; mirrors to outreach_messages |
pg_cron (15m) | HeyReach | heyreach_api_key | Azure Function (timer) | S |
| 20 | sync-heyreach-replies |
Backfill + sweep inbound LinkedIn reply text | pg_cron | HeyReach | heyreach_api_key | Azure Function (timer) | M |
| 21 | sync-heyreach-overall-stats |
Pulls HeyReach overall stats (60-day window) | cron | HeyReach | heyreach_api_key | Azure Function (timer) | S |
| 22 | heyreach-webhook |
Inbound HeyReach events (11 types) -> replies + accepted links | webhook | (inbound) | service role | Azure Function (HTTP) | M |
| 23 | heyreach-provision-campaign |
Creates + provisions a HeyReach campaign with sequence templates | UI / manual | HeyReach | heyreach_api_key | Azure Function | M |
| 24 | heyreach-campaign-control |
Pause / resume / stop HeyReach campaigns | UI | HeyReach | heyreach_api_key | Azure Function | S |
| 25 | create-heyreach-lead-lists |
Creates HeyReach lists from campaign contacts (batches of 100) | manual | HeyReach | heyreach_api_key | Azure Function | S |
| 26 | clay-enrichment-callback |
Receives Clay post-back; fills contacts.clay_* by contact_id (don't-clobber) |
webhook (Clay) | (inbound) | service role | Azure Function (HTTP) | S |
Leadership crosswalk (grouped by job)
| Group | Functions | What it accomplishes | Azure landing | Effort |
|---|---|---|---|---|
| AI generation | batch-generate-outreach, generate-outreach-message, generate-content, generate-carr-daily-brief, generate-carr-newsletter, validate-data-flag, validate-rep-note, transcribe-audio | Every message, brief, newsletter, content post, data check, and transcription | Azure Functions + Foundry Model Router (one governed model endpoint) | M (8 functions) |
| Email send + sync (EmailBison) | sync-emailbison, push-to-emailbison, emailbison-webhook, emailbison-reply, emailbison-forward, carr-bison-reconcile, bison-camp-bump-limits, bison-clear-campaign-leads, bison-lead-inspect | The full email outreach loop: sync in, push out, capture events, reply/forward, admin | Azure Functions (timer + HTTP), Key Vault for the Bison key | M (9 functions) |
| LinkedIn send + sync (HeyReach) | send-linkedin-messages, sync-heyreach-accepted, sync-heyreach-replies, sync-heyreach-overall-stats, heyreach-webhook, heyreach-provision-campaign, heyreach-campaign-control, create-heyreach-lead-lists | The full LinkedIn outreach loop: provision, send, capture accepted + replies, control, stats | Azure Functions (timer + HTTP), Key Vault for the HeyReach key | M (8 functions) |
| Enrichment intake | clay-enrichment-callback | Landing point for Clay enrichment post-backs | Azure Function (HTTP); see 09 for the upstream half |
S (1 function) |
Migration notes
- Secrets: consolidate all keys (emailbison_api_key, heyreach_api_key, ANTHROPIC_API_KEY, OPENAI_API_KEY, BRAVE_API_KEY, FIRECRAWL_API_KEY) into Azure Key Vault, read via managed identity. This replaces
get_vault_secret/vault_read. - Scheduling: the timer functions replace pg_cron jobs (see
07for the 21-job census). If BW keeps a database scheduler, SQL Agent (Managed Instance) or Elastic Jobs (SQL Database) can call the HTTP functions instead. - Webhooks: the three inbound webhooks (Clay, EmailBison, HeyReach) need public HTTPS endpoints with the same URLs re-registered in each vendor's dashboard. Front with Azure API Management if BW wants a single ingress + auth layer.
- Workspace confinement:
emailbison-reply(and the Bison sync) enforce single-workspace confinement (CARR = EmailBison workspace 4). Preserve this guard on Azure so a mis-scoped key cannot send from another client's workspace. - AI model calls: all eight AI functions call Anthropic or OpenAI directly. Repointing each
fetchat the Foundry Model Router endpoint is the recommended change (Entra identity, cost routing, observability) and is a small per-function edit.
Cross-references
- In-database code (functions, triggers, RLS, cron):
07_azure_sql_conversion.md - Upstream data-acquisition tooling (Sales Nav, PhantomBuster, Clay, FullEnrich, Hub):
09_upstream_data_agents.md - Component crosswalk:
05_carr_migration_map.md - Foundry / model router:
02_ai_foundry_agents.md - Compute host options:
03_compute_frontend.md
Compute & Frontend Hosting
Download .docx03 — Compute + Frontend Hosting
Deep-research synthesis on Azure compute + frontend hosting for CARR. Costs are 2026 projections; GA/preview tags are point-in-time.
Triggers: "azure compute", "static web apps vite", "container apps deno", "virtual environments azure", "landing zone", "lovable replacement".
Recommended hosting pattern (lowest-disruption, all GA)
- Frontend (Vite/React SPA) → Azure Static Web Apps (SWA) [GA] — global CDN, free managed TLS, native GitHub Actions deploy.
- 19 Deno/TS Edge Functions → Azure Container Apps (ACA) [GA] — containerize the Deno runtime (official
denoland/denoimage), preserve the TypeScript code, scale-to-zero. SWA "Bring Your Own Backend" routes/api→ ACA. - DB → Azure DB for PostgreSQL (see
01); Realtime → Web PubSub.
Compute options (for the team)
| Service | Status | Fit for CARR |
|---|---|---|
| Virtual Machines | GA | Poor — too much ops for 19 light scripts |
| AKS (Kubernetes) | GA | Poor — overkill |
| Container Apps (ACA) | GA | Excellent — serverless containers, runs Deno as-is |
| App Service | GA | Moderate — fine for monoliths; SWA+ACA better here |
| Static Web Apps | GA | Excellent — the frontend host |
| Azure Functions (Flex Consumption) | GA | Good if you rewrite Deno→Node |
Edge functions: containerize, don't rewrite
- Path B (recommended): Dockerize Deno → ACA. Preserves TS/Deno code, migration in weeks. Secrets via Key Vault + Managed Identity.
- Path A: rewrite Deno→Node for Azure Functions (Flex Consumption, GA). Higher effort (
Deno.env→process.env, URL imports→npm, top-level await). Only if BW mandates pure FaaS. - Reject porting complex TS into Logic Apps / Power Automate — visual low-code can't carry this logic (use them only for trivial scheduled triggers).
"Virtual environments" = Azure Landing Zones
BW's "virtual environments" maps to the Cloud Adoption Framework / Azure Landing Zones: a hierarchy of Management Groups → Subscriptions → Resource Groups. Dev/Test/Prod each get their own subscription for blast-radius isolation. This is foundational education for a team coming from a single Supabase project. (More governance detail in 04.)
The Lovable question — keep it, change where it deploys
- Power Apps + Dataverse: total rewrite into low-code; loses the React SPA + the non-dev chat-edit loop. Reject.
- GitHub Spark: preview, built for short-lived "micro-apps" (KV/SQLite) — unsuited to a 104K-contact production app. Reject for this workload.
- Recommended: keep Lovable as the UI builder, use its native GitHub sync to push React commits into BW Enterprise GitHub → GitHub Actions deploy to SWA. Non-devs keep their chat-edit velocity; code lives in corporate Git on Azure. What's lost only if Lovable is removed: the team's rapid-iteration UX entry point.
Vite-on-SWA gotcha (real, fixable)
SWA templates default to CRA's build/; Vite outputs dist/, and the SPA fallback can swallow /assets/*.js → blank screen + MIME error. Fix: set output_location: "dist" in the Actions YAML and add staticwebapp.config.json with navigationFallback.exclude for /assets/*, *.js, *.css. (Exact config in report §4.2.)
Networking + cost
Front Door (WAF) optionally in front of SWA; backend ACA/Functions on VNet + Private Endpoints so DB traffic stays on Azure's backbone. Projected run rate ≈ $230–350/mo (SWA ~$9 + Postgres GP+HA ~$150–250 + ACA ~$20–40 + Web PubSub ~$45 + Blob ~$5 + Key Vault ~$1). Costs balloon only if BW forces dedicated App Service Environments / heavy Logic Apps.
GitHub, DevOps & Governance
Download .docx04 — GitHub Enterprise, DevOps, Identity & Governance
Deep-research synthesis on GitHub/DevOps, identity, and governance for CARR's Azure move. Prices are 2026 list-price projections.
Triggers: "github actions azure", "oidc federated", "entra external id", "key vault managed identity", "landing zone governance", "migration sequencing".
CI/CD: GitHub Actions + OIDC (no stored secrets)
- Repo is already moving into BW Enterprise GitHub → use GitHub Actions (over Azure DevOps) to stay in one ecosystem.
- OIDC federated credentials are the 2026 standard: Actions requests a short-lived token from Entra ID at runtime via
azure/login— zero secrets stored in GitHub. Set up a User-Assigned Managed Identity / App Registration with a federated credential scoped to the BW repo + branch/environment. - Use GitHub Environments (Staging/Production) with manual-approval gates. The ~88 Supabase-CLI migrations move to a standard migration tool (Flyway/Liquibase/db-migrate) run by the pipeline; Docker images → Azure Container Registry → ACA revision update.
Identity — the single biggest risk
Two user populations: internal BW/CARR staff (already in BW Entra workforce tenant) and external sales reps (no BW credentials). Two candidate models — this is an open decision:
- Entra External ID — B2B Collaboration (guest accounts) (report 04 lean): reps become #EXT# guests in BW's directory; one unified directory; BW applies Conditional Access/MFA uniformly; MAU billing with 50,000 free MAU/mo (CARR almost certainly $0).
- Entra External ID — CIAM / B2C (report 01 lean): separate consumer-facing directory; better if the external population is large/consumer-like.
- RLS impact (either way): replace auth.uid() with middleware that decodes the Entra JWT and runs SET LOCAL app.user_id = '<oid>'; rewrite policies to current_setting('app.user_id', true) (see 01). Frontend swaps supabase-js auth for MSAL.
Resolve B2B-vs-CIAM with BW IT early — it gates the RLS rewrite and the frontend auth swap.
Secrets: Key Vault + Managed Identity (zero-secret)
Replaces get_vault_secret. ACA/Functions get a system-assigned Managed Identity granted the "Key Vault Secrets User" role; code uses DefaultAzureCredential (or @Microsoft.KeyVault(SecretUri=...) env binding). Central rotation — update once in Key Vault, no redeploy.
Enterprise governance (new mental model for the team)
Coming from one Supabase project, the team meets: Management Groups → Subscriptions → Resource Groups, Azure Policy (e.g. "no public network access" — non-compliant deploys fail), RBAC least-privilege (devs get Contributor on specific RGs; BW IT keeps Owner), and mandatory tagging (CostCenter, Environment, Application) for chargeback via Azure Cost Management.
Cost / licensing (2026, list prices — projections)
- GitHub Enterprise Cloud $21/user/mo; Advanced Security $49/committer/mo; Copilot Business $19 / Enterprise $39/user/mo. ~10 devs full stack ≈ $1,090/mo tooling.
- Entra External ID: first 50,000 MAU free → external-rep auth likely $0.
- Azure infra consumption ≈ $300–800/mo depending on DB tier/load (see
03for the ~$230–350 lean estimate).
Security/compliance boundary
DB gets no public IP — VNet + Private Endpoints; devs reach it via VPN/Bastion. Logs (Postgres, ACA, Key Vault) → Log Analytics; Defender for Cloud scans posture. Expect a pre-go-live enterprise security review.
Recommended migration sequence (~8 weeks)
- Wks 1–2 — Foundation/Identity: Landing Zone + subscriptions/RGs; Entra External ID; repo → BW Enterprise GitHub; Actions + OIDC.
- Wks 3–4 — Data/Secrets: Key Vault (migrate secrets); Azure DB for PG in VNet; schema+data migrate; RLS refactor to session vars;
pg_cronjobs. - Wks 5–6 — Compute/API: containerize EFs → ACA; deploy JWT-validating API middleware; webhooks.
- Wks 7–8 — Frontend/Go-live: frontend → MSAL auth; deploy to SWA via Actions; pen-test + cutover.
This keeps the three BW workstreams (Claude Enterprise, GitHub migration, Azure DB/hosting) from blocking each other.
Component Crosswalk
Download .docx05 — CARR Migration Map (Supabase → Azure)
The bridge doc. Maps every component of CARR's current Supabase build to its Azure equivalent, the migration effort, and the recommended path. Pillar notes
01–04carry the deep research; this is the at-a-glance crosswalk.
Triggers: "carr azure migration", "supabase to azure", "what moves where", "migration effort".⚠ 2026-06-17 client decision — DATA TIER SUPERSEDED. BW IT locked Azure SQL (T-SQL) as the database target, not Postgres. Rows 1–11 below describe the Azure DB for PostgreSQL path BC recommended (kept for context + to show the cost of the decision). For the actual Azure SQL conversion — difficulty census, per-object rewrites, data-transfer runbook — use
07_azure_sql_conversion.md. Compute/identity/frontend rows (6–14) are largely unaffected by the engine choice.
Component crosswalk
| # | CARR today (Supabase) | Azure target | Carries over? | Effort | BC recommendation |
|---|---|---|---|---|---|
| 1 | Postgres DB (~88 migrations, complex schema) | Azure Database for PostgreSQL (Flexible Server) | ✅ near lift-and-shift | M | Correct target. pg_dump/pg_restore or Azure DB Migration Service. NOT Azure SQL. |
| 2 | Postgres RLS (rep vs admin) | Native PG RLS on Flexible Server | ✅ syntax identical | S | Policies port unchanged — EXCEPT the auth.uid() source changes (see row 9). |
| 3 | auth.getUser() → user ID stamped into rows (actor_id, skipped_by) |
App passes Entra ID object-id into rows | ⚠️ pattern survives, source changes | M | Rework once auth moves to Entra (row 9). Biggest data-model touchpoint. |
| 4 | ~17 pg_cron jobs |
pg_cron (via azure.extensions allowlist) or Azure Functions Timer / Logic Apps schedules |
✅ pg_cron supported | S–M | Keep pg_cron where possible (least change); move to Functions Timer only if BW governance prefers. |
| 5 | DB triggers (incl. 300-char LinkedIn guard) | PG triggers on Flexible Server | ✅ | S | Port as-is. |
| 6 | 26 Edge Functions (Deno/TypeScript) | Azure Functions (Node/TS) or Container Apps (Deno container) or Logic Apps/Power Automate | ⚠️ rewrite/repackage | L | Biggest code effort. Full per-function census + Azure landing in 08_edge_function_census.md. Containerizing Deno onto Container Apps preserves the most code; Logic Apps only for simple webhook glue. |
| 7 | Supabase Vault (get_vault_secret) |
Azure Key Vault (read via managed identity) | ⚠️ rewire | S | Straightforward; rewire secret reads in EFs + CI. |
| 8 | Realtime (light — notifications) | Azure Web PubSub / SignalR (NOT Event Grid) | ⚠️ rewrite if used | S | BW proposed Event Grid — wrong for client WebSockets. Low usage; re-implement only the live-notification path. |
| 9 | Supabase Auth (reps + admins) | Entra ID + Entra External ID (CIAM) for non-BW reps | ❌ replaced | L (highest risk) | The hardest piece. External sales reps are NOT in BW's directory → need External ID / B2B / custom flow. See 04. |
| 10 | Storage (light — docs, images) | Azure Blob Storage (or SharePoint) | ⚠️ re-point | S | Blob Storage; SharePoint only if BW insists. |
| 11 | Custom API access (PostgREST auto-API) | Custom Node/TS API middleware on ACA (validates Entra JWT, injects SET LOCAL app.user_id) |
❌ must build | L | Required — replaces PostgREST AND carries the RLS identity injection. Frontend swaps supabase-js for fetch/MSAL. |
| 12 | Lovable (chat-driven React/Vite UX builder) | Static Web Apps / App Service (host) + keep Lovable as build tool, OR Power Apps / GitHub Spark | ⚠️ host moves; builder contested | L | Keep Lovable as builder, host output on Azure. Power Apps/Dataverse path loses the non-dev UX loop — push back (see 03). |
| 13 | Frontend hosting (Lovable-hosted Vite SPA) | Azure Static Web Apps (note Vite build config) or Container Apps | ⚠️ | M | Static Web Apps; mind the Vite-not-CRA build-output gotcha. |
| 14 | Source repo carr-biosystems-hub (BC GitHub) |
BW Enterprise GitHub | 🟡 in motion | — | Workstream B underway (Madhavan + Binoy). |
| 15 | (no RAG today) | pgvector on Flexible Server (future) | ✅ available | — | Free option later — pgvector is GA on Flexible Server. |
Effort: S = days · M = ~1 week · L = multi-week.
The strategic path (corrected by deep research — then overruled by client on the engine)
Engine note (2026-06-17): the recommendation below to use Azure DB for PostgreSQL was overruled by BW in favor of Azure SQL. The compute/EF/Lovable/identity reasoning still holds; only the database engine changed (and with it, the data tier became a T-SQL rewrite — see
07). The text below is preserved as the original analysis.
Self-hosted Supabase on Azure is NOT viable on managed Azure PG: the Supabase stack needs the BYPASSRLS privilege (restricted) and the pgjwt extension (unsupported) on Flexible Server. The only workarounds — raw Postgres on an IaaS VM (defeats BW's managed-cloud mandate) or a Supabase fork (maintenance nightmare) — are both rejected. (This supersedes an earlier draft that floated self-hosted Supabase as the lean.)
Recommended: Azure-native services, sequenced to minimize rewrite:
1. Data: Azure DB for PostgreSQL Flexible Server (lift schema + RLS; refactor auth.uid() → session vars). Fast win, satisfies data-residency.
2. Compute: containerize the 26 Deno EFs onto Azure Container Apps (preserves the TS code — weeks, not months) rather than rewriting to Node/Functions.
3. Frontend/UX: keep Lovable as the builder via GitHub sync; host the React/Vite output on Static Web Apps.
4. The genuine rewrite: a custom API middleware tier (Entra JWT validation + RLS injection) and the auth swap (supabase-js → MSAL/Entra). This is the unavoidable cost of leaving Supabase's bundled middleware.
Net: Azure-native where Supabase's middleware can't follow, but Deno code and the Lovable loop are preserved.
Highest-risk items (call these out to BW)
- Identity (row 9) — external reps + Entra is the single biggest unknown. Resolve the External ID / B2B / custom-flow decision early; it gates the RLS rework (row 3).
- Edge Functions (row 6) — 26 Deno functions; the rewrite-vs-containerize choice drives the timeline. Per-function census in
08_edge_function_census.md. - Lovable (rows 12–13) — losing it removes the team's UX entry-point. Frame this as a capability loss, not a dev convenience.
Open questions
- Which compute host does BW standardize on (Container Apps vs App Service vs AKS)?
- Entra-only, External ID, or hybrid for the rep population?
- Does BW accept keeping Lovable as the builder, or mandate Power Platform?
- pg_cron retained, or all scheduling moved to Azure-native?