CARR Azure Migration - Program Overview
The whole-system map of the CARR platform and how every layer moves to Barry-Wehmiller's Azure environment. Start here, then use the nav for depth.
Full System Migration Map
Download .docxCARR Full System Migration Map (App + Upstream Tooling -> Azure)
For: Barry-Wehmiller IT + CARR leadership | Prepared by: BioCreative Strategies | Date: 2026-07-21
Purpose: One authoritative picture of the entire CARR platform - the app, its database, its edge functions, and the custom code + agents BC runs outside the database to keep it fed - and how every piece maps onto Barry-Wehmiller's Azure environment. This is the top-level map; the detailed census docs live indocs/azure-migration/.
The whole system in one picture
CARR is not a single app. It is three layers, and a migration has to move all three. Read it top-down: start from the app the user sees, then what sits under it, then what feeds it.
LAYER 1 APP (Lovable/Vite SPA + 26 edge functions + Supabase Auth + PostgREST API)
22 pages: Accounts, Target Universe, Campaigns, Pipeline, Content Studio, etc.
| runs on
v
LAYER 2 DATA + IN-DATABASE LOGIC (Supabase Postgres)
86 tables, 101 views, 131 functions, 252 RLS policies, 46 triggers, 21 pg_cron jobs,
Supabase Vault, pg_net/http
^
| fed by (webhooks + sync RPCs)
LAYER 3 UPSTREAM DATA TOOLING (runs on BC infra, feeds CARR)
Sales Navigator -> PhantomBuster -> Clay + FullEnrich -> HeyReach / EmailBison
BC Hub DB (17,290-company master)
Everything BW's team can see (the app, the pages) is Layer 1. The value is in Layers 2 and 3, which are mostly invisible from the UI. This doc makes all three explicit.
Where each layer lands on Azure
| Layer | What it is today | Azure target | Effort | Detail doc |
|---|---|---|---|---|
| 1a - Frontend | Lovable-built React/Vite SPA, Supabase Auth, PostgREST auto-API | Azure Static Web Apps (host) + custom API middleware on Container Apps (validates Entra JWT, injects identity for RLS) + Entra ID / External ID for reps | L (auth + middleware are the genuine rewrite) | 03, 04, 05 |
| 1b - Edge functions (26) | Deno/TypeScript on Supabase Edge | Azure Functions (Node/TS) or Deno on Container Apps; Foundry Model Router for AI calls; Key Vault for secrets | M per group, L in aggregate | 08_edge_function_census.md |
| 2 - Database + in-DB logic | Postgres 17 + RLS + functions + triggers + pg_cron + Vault | Azure SQL (T-SQL) per BW's 2026-06-17 decision. Functions/RLS/triggers hand+agent-rewritten; cron -> SQL Agent / Elastic Jobs / Functions timers; Vault -> Key Vault; pg_net/http -> Functions | L (major rewrite, not a port) | 07_azure_sql_conversion.md |
| 3 - Upstream tooling + custom code | SaaS (Sales Nav, PhantomBuster, Clay, FullEnrich, HeyReach, EmailBison) + BC scripts/notebooks/crons + BC Hub feed | Internalized as a 7-agent CARR fleet (Ingestion, Enrichment, Account-Matching HITL, Classification, SSO, Content Authoring, Orchestrator) running hybrid on Foundry + Container Apps; Hub feed phased-out | M-L; Hub decision gates standalone | 09_upstream_data_agents.md, 11_carr_agent_fleet.md |
What BW owns after vs what stays BC-run (transition view)
| Piece | After migration | During transition |
|---|---|---|
| Azure SQL database + schema | BW | BC assists conversion + validation |
| App hosting + Entra auth | BW | BC + BW co-build the middleware + auth swap |
| 26 edge functions (re-hosted) | BW (Azure Functions) | BC ports; BW hosts |
| Outreach SaaS (HeyReach, EmailBison) | Shared - SaaS stays, integration in BW tenant | BC runs sends until wired |
| Sourcing/enrichment SaaS (Sales Nav, PhantomBuster, Clay, FullEnrich) | BW-driven via Azure Functions (vendors retained) | BC-run on bc-ops until internalized |
| Colab notebooks (import/classify/enrich) | BW (Azure ML / Foundry) or retired | BC-run manually |
| BC Hub DB feed | Open decision (keep BC-run feed vs internalize) | BC-run |
The three genuine hard parts (call these out to BW)
- Identity (Layer 1a). External sales reps are not in BW's directory. Entra vs External ID vs custom flow is the single biggest unknown, and it gates the RLS rework. See
04. - Database rewrite (Layer 2). Postgres -> Azure SQL is a rewrite, not a port: 131 functions, 252 RLS policies, 80 JSONB + 105 array columns, and in-DB networking all change. There is no first-party Microsoft PG->T-SQL converter. See
07. - The upstream supply chain (Layer 3). CARR is fed by BC-run SaaS + the BC Hub. Deciding what BW internalizes vs what stays a BC-run feed determines whether CARR can run standalone on Azure. See
09. The target-state answer is a 7-agent CARR fleet that internalizes the whole chain - see11_carr_agent_fleet.md.
Planned agent fleet (Layer 3 target-state)
Rather than keep the upstream pieces BC-run forever, the plan internalizes them into a 7-agent CARR fleet on Azure (full spec: docs/azure-migration/11_carr_agent_fleet.md):
- Ingestion / API - replaces the Hub feed + Sales Nav/PhantomBuster sourcing (phased: keep Hub, then pull ClinicalTrials/NIH/SEC/PatentsView directly).
- Enrichment - replaces Clay + FullEnrich.
- Account-Matching (HITL) - replaces
carr_account_matcher, with a human review queue modeled on Made's stakeholder-registry resolver. - Classification - replaces the classifier notebooks.
- SSO / Outreach - replaces the message generators, built as a superset of the SpanCorr + Made SSO agents.
- Content Authoring - replaces
generate-content(Content Studio); drafts sender-voice posts. Drafts only - a human reviews and posts. No automated posting and no social listening (both out of scope for this migration). - Orchestrator / Conductor - propose-only router across the fleet (BC Cortex / SpanCorr Conductor pattern).
Runtime is hybrid: Foundry for Entra Agent ID + Model Router + observability, portable agent logic on Foundry Hosted Agents / Container Apps. Prerequisites: the Azure SQL database (Layer 2) and Entra identity (Layer 1a) land first.
How to read the pack
- This doc - the whole-system map (start here).
docs/azure-migration/00_START_HERE.md- the research-pack index.07_azure_sql_conversion.md- the database rewrite (Layer 2).08_edge_function_census.md- all 26 edge functions (Layer 1b).09_upstream_data_agents.md- the upstream tooling + custom code (Layer 3).11_carr_agent_fleet.md- the planned 7-agent fleet that internalizes Layer 3.05_carr_migration_map.md- the component-by-component crosswalk.02,03,04- Foundry/AI, compute/frontend, identity/DevOps.
Open decisions to bring back to BW
- Hub dependency: keep BC-run feed into Azure, or internalize the Hub subset into Azure? Target-state is phased retirement via the Ingestion agent. (
09Part B4,11) - Agent fleet host + review-queue ownership: Foundry Hosted Agents vs Container Apps, and who works the Account-Matching + message-QA review queues during transition. (
11) - Azure SQL flavor: Managed Instance vs SQL Database vs SQL-on-VM (not pinned on the 6/17 call). (
07section 6) - Rep identity model: Entra-only, External ID, or hybrid. (
04) - Compute host: Container Apps vs App Service vs AKS for the functions + middleware. (
03) - Lovable: keep as the builder (host output on Azure) or mandate Power Platform. (
03,05)
This map is a point-in-time snapshot (2026-07-21). Counts are from a live read of the CARR repo, the CARR DB census in 07, and the bc-ops crontab. Re-verify before relying on any specific figure.
Azure Migration Briefing (client brief)
Download .docxCARR Sales-Intelligence Platform → Azure: Environment Briefing & Migration Decision Guide
Prepared by: BioCreative Strategies (BC) for Barry-Wehmiller IT & CARR Biosystems
Audience: Chad Evans, Nancy Risch, Heather Greffe, Landon Godar (BW IT) · Colby Bishop (CARR)
Date: 2026-06-17 · Updated: 2026-06-28 · Status: Core migration brief (v2)
Purpose: A transparent, vendor-neutral reference covering (1) what BC built for CARR, (2) how the target Azure environment works, (3) the database-engine question and BW's selected path, and (4) what the migration actually entails — with honest effort, current 2026 industry context, and how the work is de-risked. This is the core, shareable document; the deeper working detail behind every section lives in the companion documents mapped in §VIII.
What's new in v2: reflects BW IT's 2026-06-17 selection of Azure SQL as the standard; folds in current external research on database trends + AI tooling (§3.5), the verified conversion scope, and how modern tooling makes that conversion tractable (§3.6).
Executive summary
CARR runs a production sales-intelligence platform that BC built over the last ~4 months. Barry-Wehmiller IT is bringing it in-house onto BW's enterprise Azure footprint. Three workstreams are already moving in parallel: GitHub Enterprise (repo home), the database/hosting environment, and a "virtual environment" (governed Azure landing zone). This document lays out everything the migration touches, with the database-engine decision — the one genuinely consequential choice — front and center.
Where the engine decision landed. On the 2026-06-17 BW IT call, BW selected Azure SQL as the target database, to align CARR with BW's enterprise data-platform standard (single supported engine, one DBA toolchain, Entra-native security, Microsoft-stack/Foundry adjacency). This brief treats that as the working path and details what it entails. For full transparency it also preserves the Azure Database for PostgreSQL comparison, because that was the lower-rebuild-cost technical alternative and the comparison is useful context for BW's own records.
The single most important clarification. The choice in front of BW is not "Microsoft-managed Azure SQL vs. unmanaged open-source Postgres." Both candidate engines are first-party, fully Microsoft-managed Azure services with the same enterprise security posture (Microsoft Defender, automated patching, SLAs, Entra ID auth, private networking):
- Azure SQL Database — Microsoft's SQL Server engine (T-SQL), BW's current data-platform standard.
- Azure Database for PostgreSQL — Flexible Server — Microsoft's managed PostgreSQL PaaS. It is the same kind of governed, Microsoft-run service as Azure SQL; it is not the self-hosted open-source product CARR runs today on Supabase.
So the real trade-off is engine fit + migration cost + DBA-team familiarity, not security or "managed vs. unmanaged." BW's DBA standard is Microsoft SQL (per Nancy Risch), and that is a legitimate organizational consideration; at the same time, BW's DBA lead (Venkata) confirmed the team "doesn't have a problem supporting Postgres." Both are viable. The two paths differ mainly in how much of CARR's existing code has to be rebuilt.
The two paths in one line each:
- Path A — Azure Database for PostgreSQL (Flexible Server): near lift-and-shift. Schema, security policies, scheduled jobs, and data move largely intact; the application code keeps working; the main remaining work is re-homing the serverless functions and swapping authentication. Lowest rebuild risk, fastest to production. Off BW's DBA standard.
- Path B — Azure SQL Database (BW standard): a genuine rebuild. Every database migration is re-authored in T-SQL, the security model is re-engineered, scheduled jobs move to a different scheduler, the AI/retrieval layer re-homes to Azure AI Search, and the 20 functions are ported. On-standard for BW, but materially longer timeline.
Neither path is blocked, and BW's selection of Azure SQL is a legitimate enterprise-standardization decision. The good news from the latest research: while there is no one-click PG→Azure SQL converter, the conversion is tractable with modern tooling — the SQL-dialect knowledge is well-understood by today's AI models, open transpilers handle the mechanical bulk, and BC can build a purpose-made translation step plus a verification loop to do it accountably (see §3.6). BC's role going forward is to support the build, educate both teams, and help establish best practices in a fast-moving environment — not to dictate the stack.
A note on two things said on the live call, now verified, so the team is working from accurate facts: (1) CARR's serverless functions are written in Deno/TypeScript, not Python — this changes the "port to Azure Functions" assessment (see Part IV). (2) There is no meaningful technical difference in management or security between Azure SQL and Azure Database for PostgreSQL — both are managed Microsoft PaaS; the differences are in SQL dialect, extensions, and ecosystem (see Part III).
Part I — What BC built for CARR (full transparency)
CARR's platform is a purpose-built "mini-CRM + marketing-intelligence engine" that sits outside CARR's systems of record. It finds, enriches, scores, and engages prospects, and gives reps a single place to work. Important scope clarification (as stated on the call): the platform contains no Barry-Wehmiller CRM data. Every account and contact was independently built by BC via public sources and BC's own scrapers — not pulled from BW's Dynamics 365/CE or XA systems. CRM/XA integration is a future want, not a current dependency.
1.1 The data tier (Supabase Postgres)
- Engine: PostgreSQL (hosted by Supabase today).
- Scale: ~4,200 accounts and ~104,000 contacts, fully enriched (company size, location, industry, classification, scoring) plus mapped contacts.
- Schema depth: 89 migration files in the repo / ~560 applied migration steps in the database (many auto-generated during iterative builds) — a deliberately structured schema (accounts, contacts, classifications, scoring, messaging matrices, campaigns, outreach, engagement history, news/signal tables, validation flags). The point for migration planning: this is real accumulated schema, not a prototype.
- Row-Level Security (RLS): access policies enforced at the database engine, keyed off the authenticated user (rows are stamped with
actor_id/skipped_byetc.). - Database triggers & stored logic: PL/pgSQL triggers (e.g., a 300-character guard on LinkedIn messages) and helper functions/RPCs (e.g.,
resolve_messaging_strategy()). - Extensions in use (verified):
pg_cron(scheduling),pg_net+http(the database makes outbound HTTP calls to trigger functions/webhooks),pgcrypto,supabase_vault(secret storage),uuid-ossp,pg_stat_statements. Note: there is nopgvector/in-database embedding today — the "knowledge graph / RAG" Brian described lives in the GitHub markdown context system (see 1.5), not as in-DB vectors. In-database vectors are a roadmap capability (relevant to the engine choice — see Part V).
1.2 The serverless functions (20, Deno/TypeScript)
CARR runs 20 Supabase Edge Functions, all written in Deno/TypeScript (index.ts, Deno std serve, URL-based imports, @supabase/supabase-js). They are the application's "back-end verbs." Grouped:
- Generation:
generate-outreach-message,batch-generate-outreach,generate-content,generate-carr-daily-brief,generate-carr-newsletter(call Anthropic Claude + OpenAI). - EmailBison (email outreach):
push-to-emailbison,sync-emailbison,emailbison-webhook,emailbison-forward,emailbison-reply,carr-bison-reconcile. - HeyReach (LinkedIn outreach):
create-heyreach-lead-lists,heyreach-webhook,sync-heyreach-accepted,sync-heyreach-overall-stats,send-linkedin-messages. - Signals & validation:
validate-data-flag,validate-rep-note,transcribe-audio.
These hold API keys (via Vault secrets), call third-party services, and do the JSON-heavy orchestration that generates messages and syncs campaign state.
1.3 Scheduled automation (21 pg_cron jobs)
21 active pg_cron jobs keep the platform live (verified in cron.job). Examples:
- High-frequency: HeyReach accepted/replies every 15 min; EmailBison push every 2 h; LinkedIn sends every 2 h.
- Medium: news sync every 4 h; HeyReach refresh every 6 h.
- Daily/weekly: stats rollups daily; clinical-trials, grants, CGT-accounts syncs weekly; nightly cleanups/purges.
These call functions and run maintenance directly from the database.
1.4 Secrets, auth, frontend
- Secrets: API keys (EmailBison, HeyReach, Anthropic, OpenAI, scrapers) in Supabase Vault.
- Auth: Supabase Auth (reps + admins), feeding the RLS identity context.
- Frontend: a React/Vite single-page app generated and currently hosted on Lovable with a custom domain.
supabase-jsconnects the UI to the data + functions.
1.5 The "spine" (BC methodology — kept at the level of what, not how)
Around the app, BC maintains a modular context system: a GitHub repository of structured markdown (value props, buyer personas, positioning, associations) that acts as the LLM's "brain." When the platform generates a message or asset, an Edge Function assembles context (contact + account + signals + positioning) and passes it to the LLM. The news/signal layer scrapes 22+ RSS feeds plus public APIs (PubMed, ClinicalTrials.gov, SBIR, NIH grants), scores relevance to CARR, and writes summaries into the database for reps. (BC's reusable cross-client methodology is described here at a capability level, consistent with the engagement's IP boundary.)
Part II — How the target Azure environment works (orientation)
For a team moving from a single all-in-one Supabase project, Azure's enterprise scaffolding is new. The key pieces:
2.1 "Virtual environments" = Azure Landing Zones
What was described on the call as a "virtual environment" maps to Microsoft's Cloud Adoption Framework / Azure Landing Zone model:
- Management Groups → Subscriptions → Resource Groups — a governed hierarchy. Landon's instinct to "create a resource group for CARR" is exactly the right first concrete step.
- Dev/Test/Prod are typically isolated (own subscriptions or resource groups) for blast-radius control, with Azure Policy + RBAC + tagging applied centrally.
2.2 The two managed database engines
Both are GA, both fully Microsoft-managed:
| | Azure SQL Database | Azure Database for PostgreSQL — Flexible Server |
|---|---|---|
| Engine | Microsoft SQL Server (T-SQL) | Community PostgreSQL (managed by Microsoft) |
| BW standard? | ✅ Yes | ⚠️ Off-standard (but supportable per Venkata) |
| Management/security | Managed, Defender, patching, SLA, private networking | Same — managed, Defender, patching, SLA, private networking |
| Relationship to CARR today | Different engine → conversion | Same engine → near lift-and-shift |
2.3 Compute for the functions (all GA)
- Azure Functions — serverless FaaS; native Node/TypeScript and Python (not Deno).
- Azure Container Apps — serverless containers; can run the Deno runtime as-is in a container.
- Azure Static Web Apps — host for the React/Vite frontend (global CDN, managed TLS, GitHub Actions deploy).
- Logic Apps / Power Automate — visual low-code; fine for simple triggers, not for CARR's code-heavy TypeScript logic.
2.4 Identity, secrets, networking
- Microsoft Entra ID (workforce) + Entra External ID (external reps) replace Supabase Auth.
- Azure Key Vault (+ Managed Identity) replaces Supabase Vault.
- Private endpoints / VNet — Nancy's point is correct and important: networking (private vs. public, since Azure SQL is a SaaS endpoint) must be decided up front; retrofitting later is painful-to-impossible.
2.5 Microsoft Foundry + AI services (read the maturity caveat)
Microsoft Foundry (renamed from Azure AI Foundry; "Azure" prefix dropped Jan 2026) is Microsoft's AI app/agent platform — model catalog, Agent Service (GA March 16 2026), Model Router, and Foundry IQ (managed retrieval/RAG). It is where BW's AI-agent ambitions will live.
- Maturity reality (as BW's own team noted on the call): BW's Foundry work today is proof-of-concept, not production, "Microsoft keeps changing things," and there is no AI architect in seat yet (John Katsapis is hiring; two senior data architects inbound). Many advanced Foundry features (agent memory, agent-to-agent orchestration) are still preview. This is the main reason a "this-week-to-production" timeline is not realistic — and that is a Microsoft/Foundry-readiness constraint, independent of the database choice.
2.6 Enterprise LLM data protection (the "no-training" question)
A concern raised was whether the model trains on CARR's data. BW already has the answer in-house: Chad confirmed BW holds Enterprise Claude, which enforces data privacy — submitted data is not used to train the public models. The right move is to route CARR's LLM calls through BW's Enterprise Claude (and/or Azure OpenAI within BW's tenant, which carries the same no-training, data-stays-in-tenant commitment). Today CARR's app touches the LLM in only a few places (e.g., assembling and sending context when a rep generates a follow-up); most processing is data-side. BW's MCP security-review process should also cover any Model Context Protocol connectors before they're enabled.
Part III — The database engine decision (the core section, neutral)
3.1 Clearing the misconception
On the call, the concern was framed as "Postgres is open source vs. Azure SQL is fully managed with higher security." That comparison conflates two different things:
- CARR runs Postgres on Supabase today (a managed third-party BaaS).
- The Azure target would be Azure Database for PostgreSQL — Flexible Server, a first-party Microsoft-managed PaaS.
Choosing Azure Database for PostgreSQL does not mean running unmanaged open-source software, and it does not lower the security bar: it is patched, monitored (Defender), backed by SLA, Entra-integrated, and private-network-capable exactly like Azure SQL. The genuine, legitimate differences are: SQL dialect (PL/pgSQL vs. T-SQL), extension ecosystem (e.g., pg_cron, pgvector), and BW's DBA-team familiarity/standard (Microsoft SQL).
"Free online converters can translate the SQL" is only partly true: simple table/column DDL converts mechanically, but RLS policies, PL/pgSQL triggers/functions,
pg_cronjobs,pg_net/httpcalls, and (future)pgvectorhave no automatic T-SQL equivalent and must be re-engineered by hand. That hand-work is the real cost of Path B.
3.2 Path A — Azure Database for PostgreSQL (Flexible Server)
What carries over (near lift-and-shift):
- Schema + all migrations (same dialect) — 89 files / ~560 applied steps replay as-is.
- RLS policies (same syntax) — only the identity source changes (see Part IV, identity).
- PL/pgSQL triggers & functions, including the 300-char guard.
- pg_cron (GA on Flexible Server) — the 21 jobs port largely unchanged.
- http/pgcrypto/uuid-ossp (supported); pg_net to verify on the Azure allowlist.
- Data (small, <1 GB) via pg_dump/pg_restore or Azure Database Migration Service.
- The roadmap pgvector path stays native (GA on Flexible Server).
What still must change (same as Path B): Supabase Auth → Entra; Supabase Vault → Key Vault; the 20 Edge Functions need a compute home (Container Apps or Azure Functions); frontend host → Static Web Apps/internal.
Net: lowest rebuild risk, fastest to production. Trade-off: off BW's DBA standard.
3.3 Path B — Azure SQL Database (BW standard)
What must be rebuilt:
- Every migration re-authored in T-SQL; data types remapped (JSONB → native JSON/nvarchar(max)).
- RLS re-engineered (Azure SQL supports RLS via security policies/predicate functions — different model).
- pg_cron (21 jobs) → Elastic Jobs / Azure Functions Timer triggers (re-implemented + re-tested).
- pg_net/http in-DB calls → no in-database HTTP in Azure SQL; that logic moves to external compute.
- PL/pgSQL triggers/functions → T-SQL stored procedures.
- Retrieval/RAG roadmap: Azure SQL has no pgvector equivalent → vectors/RAG re-home to Azure AI Search or Foundry IQ (a deliberate re-architecture, not a blocker).
- The 20 Deno/TS Edge Functions → ported (see Part IV).
Net: on-standard for BW and fully supportable, but a genuine rebuild that extends the timeline. Brian's on-call read — "it's doable, but you'd essentially be rebuilding it" — is accurate.
3.5 2026 industry context (neutral, for transparency)
So the team is working from current facts, BC ran an external research sweep (2026-06-27; sources in Appendix C). Two findings matter and they cut in both directions — which is why the decision is genuinely balanced:
- PostgreSQL leads developer adoption and is the fastest-rising relational engine. In the Stack Overflow 2025 Developer Survey it was the most-used database at 55.6% (second year running), versus ~27% for SQL Server in the prior year's survey; DB-Engines shows the two within a few points of each other at the top, with PostgreSQL the faster climber. It also anchors the open AI ecosystem (the
pgvectorextension is a common default for in-database vector/RAG search). This is why Path A is the lower-friction technical option for an AI-forward roadmap. - Azure SQL / SQL Server 2025 has closed most of the "AI gap." The SQL Server 2025 release (GA 2025-11-18) added a native vector data type, DiskANN-based vector indexing, in-engine external-AI-model management, and GitHub Copilot in SQL Server Management Studio — Microsoft explicitly positions it as "the AI-ready enterprise database." This means BW's standard is not an AI dead-end: RAG and vector search are now first-class on Azure SQL, alongside Azure AI Search / Foundry.
Net, stated plainly: PostgreSQL is where broad developer and open-source AI momentum sits; Azure SQL is a fully capable, enterprise-secure, increasingly AI-ready engine, and standardizing on it is a reasonable governance choice. The trade-off BW is accepting is a heavier one-time conversion (§3.3) in exchange for fitting its supported standard — not a loss of capability.
3.6 How the Azure SQL conversion is de-risked (the encouraging part)
There is no first-party Microsoft tool that converts PostgreSQL to Azure SQL automatically (SSMA doesn't take Postgres as a source; DMS moves data, not dialect). That sounds daunting, but the conversion is bounded and tractable with a modern approach BC has scoped in detail:
- The dialect knowledge is well-understood. A controlled test across leading AI models (Claude, GPT, Gemini) showed they reliably produce the correct Azure SQL idioms for the hard constructs (security-policy + session-context RLS, set-based triggers, JSON functions, MERGE upserts) with no special prompting — so this is a context-engineering + verification problem, not a "teach the machine T-SQL" problem.
- Open tooling handles the mechanical bulk. A mature open-source transpiler (
sqlglot) deterministically converts the large, repetitive layer (queries, views, casts, paging) with no model involvement. - A purpose-built translation step covers the tail. For the procedural code, RLS policies, and triggers that no tool handles, BC can build a small, reviewable translation step with a compile + behavior-parity + RLS verification loop against an Azure SQL target, so every converted object is proven, not just plausible.
- The data move itself is trivial (the dataset is small, <1 GB).
What this means for BW: the genuinely careful work is verifying behavior equivalence across CARR's stored logic and security policies (a real QA effort worth budgeting for), plus the Azure-side foundations everyone needs regardless of engine — identity (Entra), the API/security layer, networking, and standing up the functions. The conversion of the database code is real work, but it is a known, plannable quantity, not an open-ended unknown.
3.4 Side-by-side
| Component | Path A (Azure DB for PostgreSQL) | Path B (Azure SQL) |
|---|---|---|
| Schema + migrations (89 files / ~560 applied) | Lift-and-shift (same dialect) | Re-author in T-SQL |
| RLS policies | Port as-is (swap identity source) | Re-engineer (different model) |
| PL/pgSQL triggers/functions | Port as-is | Rewrite as T-SQL procs |
21 pg_cron jobs |
Keep pg_cron |
Rebuild on Elastic Jobs / Timer |
pg_net/http in-DB calls |
Supported (verify pg_net) |
Move to external compute |
RAG / pgvector (roadmap) |
Native | Azure AI Search / Foundry IQ |
| 20 Edge Functions (Deno/TS) | Re-home (same for both) | Re-home (same for both) |
| Auth, Vault, frontend host | Change (same for both) | Change (same for both) |
| Data migration (~<1 GB) | pg_dump/restore or DMS |
ETL into new schema |
| BW DBA standard | Off-standard | On-standard |
| Relative timeline | Shorter | Longer |
Part IV — Code-level gates (the short-term holdups)
4.1 Edge Functions → Azure compute (correct the language fact first)
The 20 functions are Deno/TypeScript, not Python. That matters:
- Azure Functions runs Node/TypeScript and Python natively — not Deno. So the Deno code needs adaptation to Node (swap Deno std serve/URL imports for Node + npm, Deno.env → process.env), or
- Azure Container Apps can run the Deno runtime unchanged inside a container — lower code-change risk.
- Recommended proof step (matches the team's agreed milestone): port one function end-to-end first (e.g., generate-outreach-message) to measure real effort before committing the other 19. This is true on either DB path.
- Logic Apps/Power Automate are not appropriate for this logic.
4.2 Scheduled jobs (21) → the right analog
- Path A: keep
pg_cron— minimal change. - Path B: re-implement on Azure Functions Timer triggers or Elastic Jobs. Watch the high-frequency ones (15-min HeyReach sync/replies; 2-hourly sends) — they need reliable sub-hourly scheduling.
4.3 Identity / RLS rework (either path)
- Supabase Auth → Entra ID (internal) + Entra External ID (external reps; B2B-guest vs. CIAM is an open sub-decision).
- The app no longer gets
auth.uid()automatically. Pattern: an API layer validates the Entra token and injects the user id into the DB session (SET app.user_id = '<entra-oid>'); RLS policies read that session value. The frontend swapssupabase-jsauth for MSAL.
4.4 Hosting
- Move the React/Vite app off Lovable to Azure Static Web Apps (or an internal host). Keep Lovable as the UI builder via GitHub sync if CARR wants to retain rapid iteration — no need to rebuild the UI in Power Apps.
Part V — Does the AI / interface build work the same on Azure SQL?
Honest answer: mostly yes for the app; the AI-retrieval roadmap is where the engine choice bites.
- The CRUD app, campaigns, reps' workflow, message generation — all work on either engine (the generation calls hit Claude/OpenAI regardless of DB).
- The part most coupled to Postgres is the future retrieval/embedding layer (RAG). Today CARR has no in-DB vectors — the "knowledge" lives in the GitHub markdown spine. As that matures into true RAG:
- On Path A: add pgvector in the same database — simplest, co-located with the data.
- On Path B: retrieval re-homes to Azure AI Search or Foundry IQ — a capable, Microsoft-native pattern, but a separate system to stand up and sync.
- For the broader agent/interface roadmap Colby and Cam described, both paths reach the destination; Path A keeps more of it in one place, Path B aligns with BW's AI-on-Foundry direction. Neither forecloses the vision.
Part VI — Safety, security & the model-training opt-out
- No-training / data privacy: route LLM calls through BW's Enterprise Claude (already licensed, enforces no-training) and/or Azure OpenAI in BW's tenant (data stays in tenant, not used to train foundation models). This directly addresses the concern raised on the call.
- Tenant isolation & residency: all compute/data inside BW's subscription + region.
- Private networking: decide private endpoints / VNet topology up front (Nancy) — Azure SQL and Azure DB for PostgreSQL both support private-only access; Foundry private endpoints are not the default and need deliberate setup.
- Reviews: BW security review before any external connection; MCP connectors go through BW's MCP review.
- Secrets & identity: Key Vault + Managed Identity (no secrets in code); Entra for users; per-agent identity (Entra Agent ID) as the agent layer matures.
Part VII — Recommended path forward & BC's role
7.1 The no-regret bridge (do this now — engine-agnostic)
These steps create momentum without waiting on the engine decision:
1. Stand up a CARR resource group (Landon) in the agreed subscription.
2. Port the raw data first — get accounts/contacts into a staging database on BW's side (fast; BC can grant scoped access/token to pull). Engine-agnostic.
3. Proof-test one Edge Function → Azure Function/Container App (e.g., generate-outreach-message) to measure real port effort.
4. Stand up a Foundry POC resource for the AI pieces, knowing it's pre-production.
5. Adopt Enterprise Claude for CARR's LLM calls.
7.2 Decisions BW needs to make
- DB engine: ✅ Decided 2026-06-17 — Azure SQL (BW standard). Remaining sub-decision: the Azure SQL flavor (Managed Instance vs. SQL Database) — it drives the scheduler choice (SQL Agent vs. Elastic Jobs) and cross-database behavior; worth confirming early.
- AI architect / owner: who owns the Foundry + agent architecture (John's hire).
- Networking topology: private vs. public, decided before build.
- External-rep identity model: Entra B2B-guest vs. CIAM.
7.3 Timeline framing (honest)
A production cutover "this week" is not realistic — not because of CARR's app, but because BW's Foundry/AI environment is pre-production, the AI architect isn't in seat, and security/networking reviews must complete. A reasonable near-term milestone is the data port + one-function proof, which is achievable quickly and de-risks everything after it.
7.4 BC's role
BC will support the build, educate both teams, and help establish best practices as this environment keeps changing. For the Azure SQL conversion specifically, BC can deliver a purpose-built translation step + verification loop (per §3.6) so the database code is converted accountably, with behavior-equivalence proven object-by-object. The mechanics of the port (who does what, and how far BC carries it) sit slightly outside the current agreement and are a scope/commercial conversation to have with Colby and Chad — BC is open to it.
7.5 IP / learning boundary (noted respectfully)
Per the engagement understanding, CARR's own application, data, and build are CARR's; BC's reusable cross-client methodology (the "spine" approach) is described here at a capability level and remains BC's. This doesn't constrain the migration — it just frames what's being moved vs. what's being learned-from.
Appendix A — Component crosswalk (quick reference)
| CARR today (Supabase) | Path A (Azure DB for PostgreSQL) | Path B (Azure SQL) |
|---|---|---|
| Postgres DB (89 migration files / ~560 applied) | Azure DB for PostgreSQL (lift-and-shift) | Azure SQL (re-author T-SQL) |
| RLS (rep/admin) | Port; swap identity source | Re-engineer (security policies) |
| PL/pgSQL triggers/functions | Port as-is | Rewrite as T-SQL procs |
21 pg_cron jobs |
pg_cron |
Elastic Jobs / Timer triggers |
pg_net/http in-DB |
Supported (verify pg_net) |
External compute |
| Supabase Vault | Azure Key Vault | Azure Key Vault |
| Supabase Auth | Entra ID + External ID | Entra ID + External ID |
| 20 Edge Functions (Deno/TS) | Container Apps (Deno) or Functions (Node) | Same |
| Lovable-hosted Vite SPA | Static Web Apps (keep Lovable as builder) | Same |
| RAG/embeddings (roadmap) | pgvector (native) |
Azure AI Search / Foundry IQ |
| LLM calls (Claude/OpenAI) | Enterprise Claude / Azure OpenAI (no-train) | Same |
Appendix B — People & roles (from the call)
- Colby Bishop (CARR) — Product Manager, AI rollout lead.
- Chad Evans (BW-NA) — infrastructure/DBA lead, driving the migration.
- Nancy Risch (BW-NA) — architecture standards/governance.
- Heather Greffe (BW-NA) — DBA team.
- Landon Godar (BW-STL) — hands-on Azure (resource groups).
- John Katsapis — AI team lead (hiring the AI architect); Venkata — DBA lead (OK supporting Postgres); two senior data architects inbound (Intella started this week).
Appendix C — Maturity tags & sources
- GA: Azure SQL, Azure DB for PostgreSQL Flexible Server,
pg_cron/pgvectoron Flexible Server, Container Apps, Functions, Static Web Apps, Entra ID/External ID, Key Vault, Web PubSub, Foundry Agent Service (Mar 16 2026), SQL Server 2025 native vector type + AI-model management (GA 2025-11-18; vector index preview-flagged). - Preview / pre-production at BW: Foundry agent memory, agent-to-agent orchestration; BW's own Foundry deployment is POC, not production.
- Deprecation to avoid: Azure OpenAI Assistants API retires Aug 26 2026 — build on Foundry Agent Service.
- Sources: the companion research docs in §VIII, live inspection of the CARR app + CARR DB (
drzxmokguptvwptuqjcv, census 2026-06-27), and the BW IT call (2026-06-17). - External research sweep (2026-06-27): Stack Overflow 2025 Developer Survey; DB-Engines ranking; Microsoft Learn "What's new in SQL Server 2025"; industry trend coverage (rapydo.io, tech-insider.org); vector-database + MCP-ecosystem surveys. Point-in-time figures; re-verify before reuse. 2026 pricing/feature dates are projections unless from an official Microsoft page.
Part VIII — Companion documents (where to go deeper)
This brief is the core, neutral, shareable layer. The companion documents below are the deeper detail behind each section — all included in this folder.
| # | Document | What it covers |
|---|---|---|
| 01 | 01_data_layer.md |
The data-tier deep dive — Azure SQL vs Postgres, RLS/identity, migration mechanics |
| 02 | 02_ai_foundry_agents.md |
Microsoft Foundry, the Agent Service, and how the AI layer maps to Azure |
| 03 | 03_compute_frontend.md |
Where the app + functions run (Container Apps / Functions / Static Web Apps) |
| 04 | 04_github_devops_governance.md |
GitHub Enterprise → Azure CI/CD, Entra identity, Key Vault, governance |
| 05 | 05_carr_migration_map.md |
Component-by-component Supabase → Azure crosswalk + effort |
| 06 | 06_glossary.md |
Plain-English Azure terms for the CARR/BW team |
| 07 | 07_azure_sql_conversion.md |
The verified PG→Azure SQL conversion scope + per-object rewrite map + data-transfer runbook |
| 10 | 10_llm_knowledge_and_oss_landscape.md |
The model-knowledge test + open-source tooling landscape (sqlglot) |
| 13 | 13_postgres_vs_azure_sql_reanalysis.md |
The full engine reanalysis behind §3 (pros/cons + recommendation) |
| 14 | 14_strategic_trend_analysis.md |
The cited 2026 industry-trend + AI-tooling research behind §3.5 |
Note on scope: this brief is the document to share with the CARR/BW team; the companion files are the reference detail behind it, and can be opened up as the team needs. (A few internal working notes — effort estimates and engagement/scope options — are kept separately and are not part of this set.)
Prepared by BioCreative Strategies. This is a neutral migration brief: BW has selected Azure SQL, that path is fully viable and supportable, and the conversion is a known, de-riskable quantity. The standing recommendation is to begin with the no-regret data-port + single-function proof while the Azure foundations (identity, networking, AI architect) come into place.
Research Pack - Start Here
Download .docxCARR → Azure Migration — Research Pack (Start Here)
This folder is the research pack behind CARR's move from Supabase to Barry-Wehmiller's Azure environment. It's assembled so you can drop the whole folder into a Claude Project (as knowledge) and ask questions in plain language — the files are self-contained and cross-reference each other by filename.
What this covers
- How CARR's current build (Supabase Postgres + edge functions + Lovable frontend) maps onto Azure.
- The database engine decision — managed Postgres vs Azure SQL — with a balanced pros/cons reanalysis and the 2026 industry-trend context.
- The Postgres → Azure SQL conversion: what it takes, how hard it is, and how it gets de-risked.
- Identity, compute, DevOps/governance, and a plain-English Azure glossary.
Context: On the 2026-06-17 BW IT call, BW standardized on Azure SQL as the database target (not Postgres). Several docs preserve the original "Postgres is the cleaner engine" analysis for the record; the working plan is the Azure SQL path.
The documents
| Read this when you want… | File |
|---|---|
| The single client-facing brief (start here) | CARR_AZURE_MIGRATION_BRIEFING.md (+ .docx) |
| The data-tier deep dive (Postgres vs Azure SQL, RLS, identity) | 01_data_layer.md |
| Microsoft Foundry + how an AI/agent layer maps to Azure | 02_ai_foundry_agents.md |
| Where the app + functions run (Container Apps / Functions / Static Web Apps) | 03_compute_frontend.md |
| GitHub → Azure CI/CD, Entra identity, Key Vault, governance | 04_github_devops_governance.md |
| Component-by-component Supabase → Azure crosswalk + effort | 05_carr_migration_map.md |
| Plain-English Azure glossary for the team | 06_glossary.md |
| The PG → Azure SQL conversion scope + per-object rewrites + data-transfer runbook | 07_azure_sql_conversion.md |
| The full edge-function census (all 26) + Azure landing (engineer + leadership views) | 08_edge_function_census.md |
| The upstream data tooling + custom code (Sales Nav, PhantomBuster, Clay, FullEnrich, Hub) + Azure internalization | 09_upstream_data_agents.md |
| The planned 7-agent CARR fleet (Ingestion, Enrichment, Account-Matching HITL, Classification, SSO, Content Authoring, Orchestrator) that internalizes the upstream layer | 11_carr_agent_fleet.md |
| The whole-system map across all three layers (top-level, BW-facing) | ../CARR_FULL_SYSTEM_MIGRATION_MAP.md |
Whether frontier LLMs already know the conversion (+ sqlglot tooling) |
10_llm_knowledge_and_oss_landscape.md |
| The full engine reanalysis (pros/cons + recommendation) | 13_postgres_vs_azure_sql_reanalysis.md |
| The 2026 industry-trend view (adoption, AI features, long-term fit) | 14_strategic_trend_analysis.md |
Suggested prompts (once loaded into a Claude Project)
- "In plain English, what changes when CARR moves from Supabase to Azure SQL?"
- "Summarize the pros and cons of Azure SQL vs managed Postgres for CARR."
- "What's the hardest part of the migration, and why?"
- "Explain Row-Level Security and how it's rebuilt on Azure SQL."
- "What does the database → data → validate → cutover runbook look like?"
- "Which Azure SQL flavor is recommended, and what open question should we take back to BW?"
- "What should we ask Barry-Wehmiller's IT team to provide before the conversion starts?"
- "Define the Azure terms in this pack for someone new to Azure."
- "List every edge function and where each one lands on Azure."
- "What custom code and SaaS tools run outside CARR's database to keep it fed, and how do they move to Azure?"
- "Give me the whole-system view across all three layers."
- "Describe the planned CARR agent fleet and which upstream piece each agent replaces."
- "Confirm social listening is out of scope and explain what the Content Authoring agent does (and does not) do."
Notes
- Currency: Azure features move monthly and figures are point-in-time (mid-2026). Docs tag GA vs preview and flag projections — re-verify before relying on any specific price or feature date.
- Scope: this pack is the shareable reference set. A few internal working notes (effort estimates and engagement/scope options) are kept separately and are not included here.
Plain-English Azure Glossary
Download .docx06 — Azure Glossary (for the CARR / BW team)
Plain-English definitions of the Azure terms that come up in CARR's migration, each tied back to the Supabase concept it replaces where relevant. Keep this the friendly on-ramp.
Triggers: "what is", "azure term", "glossary", "what does X mean".
Data + backend
⚠ 2026-06-17 client decision: BW IT locked Azure SQL as the database target (not Postgres). The Postgres-Flexible-Server entries below are kept for context but are no longer the plan — see
07_azure_sql_conversion.md.
- Azure SQL (the target) — Microsoft's managed SQL Server family, using the T-SQL dialect. CARR is migrating here per BW standard. Comes in three flavors (below). Replaces: Supabase Postgres — via a full code conversion, not a lift-and-shift.
- T-SQL (Transact-SQL) — SQL Server's SQL dialect. Different from Postgres's SQL + PL/pgSQL: every CARR function, view, trigger, and RLS policy must be rewritten into it.
- Azure SQL Managed Instance (MI) — the PaaS flavor closest to a full SQL Server (has SQL Server Agent, cross-database queries). BC's recommended target — easiest landing for CARR's 21 scheduled jobs + procedural code.
- Azure SQL Database — the single-database PaaS flavor. Cheaper, but no SQL Agent (uses Elastic Jobs) and more constraints.
- SQL Server on a VM — full SQL Server you run/patch yourself (IaaS). Most control; defeats BW's managed-cloud preference.
- Azure Database for PostgreSQL (Flexible Server) — Microsoft's managed PostgreSQL (same engine as Supabase). Was BC's recommended target; superseded by the 6/17 Azure SQL decision.
- Row-Level Security (RLS) — rules limiting which rows a user can see/edit (a rep sees only their leads). CARR has 252 such policies. In Azure SQL this is rebuilt as a SECURITY POLICY + predicate function (below), not Postgres
CREATE POLICY. - SECURITY POLICY (Azure SQL) — the T-SQL object that attaches FILTER (read) and BLOCK (write) predicates to a table to enforce RLS. The Azure SQL replacement for Postgres RLS policies.
- SESSION_CONTEXT — a per-connection key/value store in Azure SQL the app sets (
sp_set_session_context) so RLS predicates know who the user is. Replaces Postgresauth.uid()as the identity source inside the database. - OPENJSON / JSON_VALUE / JSON_QUERY — T-SQL functions for reading JSON held in
NVARCHAR(MAX). How CARR's 80JSONBcolumns are queried after conversion (Azure SQL has no binaryJSONBtype). - pg_cron — a Postgres extension that runs scheduled jobs inside the database. CARR has 21. No in-database equivalent in Azure SQL → moves to SQL Agent (MI) or Elastic Jobs (SQL Database).
- pg_net / http — Postgres extensions that let the database make HTTP calls. No Azure SQL equivalent → that logic moves out to Azure Functions.
- Azure Key Vault — secure store for secrets (API keys, passwords). Replaces: Supabase Vault.
- Azure Blob Storage — file/object storage (docs, images). Replaces: Supabase Storage.
- Azure Event Grid / SignalR — event fan-out / live updates. Replaces: Supabase Realtime.
Compute + hosting
- Virtual Machine (VM) — a full rented computer in the cloud you manage yourself. Most control, most upkeep.
- Azure Kubernetes Service (AKS) — managed Kubernetes for running many containers at scale. Powerful, complex.
- Azure Container Apps — run containers without managing Kubernetes. Good middle ground for apps/services like CARR's Edge Functions.
- Azure App Service — managed hosting for web apps/APIs; "deploy your code, Azure runs it."
- Azure Static Web Apps — hosting purpose-built for single-page frontends (React) + a serverless API. Candidate host for CARR's Vite/React UI.
- Azure Functions — serverless functions that run on a trigger (HTTP, timer, queue). Candidate replacement for CARR's Deno Edge Functions.
- "Virtual environments" (BW's phrasing) — usually means isolated dev / test / prod environments. In Azure this is done with subscriptions, resource groups, and landing zones (see below).
Identity + governance
- Microsoft Entra ID (formerly Azure Active Directory / Azure AD) — Microsoft's identity system; how BW employees sign in. Replaces: Supabase Auth for internal users.
- Microsoft Entra External ID (CIAM) — Entra for external users (customers, partners) who aren't BW employees. The likely path for CARR's external sales reps.
- Managed identity — lets an Azure app authenticate to other Azure services (like Key Vault) without storing a password.
- Resource group — a folder that groups related Azure resources (DB, app, storage) for one project/environment.
- Subscription — a billing + access boundary that contains resource groups.
- Management group — groups multiple subscriptions for org-wide policy (enterprise scaffolding).
- Azure Landing Zone — Microsoft's blueprint for a well-governed enterprise Azure setup (networking, identity, policy, cost controls) before apps move in. BW IT will likely impose one.
- Azure Policy / RBAC — rules (Policy) and role-based permissions (RBAC) that govern what can be deployed and who can do what.
AI
- Microsoft Foundry (formerly Azure AI Foundry) — Azure's platform for building AI apps and agents. Went GA March 2026.
- Foundry Agent Service — the managed service within Foundry for building, deploying, and scaling AI agents. A managed home for an AI-agent layer.
- Model catalog — the menu of AI models (OpenAI, Anthropic, Llama, Phi, etc.) you can deploy in Foundry.
- GA vs preview — GA (General Availability) = production-ready, supported. Preview = early, may change/break, not for production. Always check which one applies — Azure AI features move monthly.
Migration tooling
- SSMA (SQL Server Migration Assistant) — Microsoft's free DB-migration tool. Does NOT support PostgreSQL as a source (only Access, Db2, MySQL, Oracle, SAP ASE) — so it can't convert CARR. Named here because people assume it can.
- Azure Database Migration Service (DMS) — Azure's managed migration service. Does not convert Postgres → Azure SQL; not applicable to CARR's path.
- Azure Data Factory (ADF) — Azure's data-pipeline service; a candidate for bulk-loading CARR's data (PG source → Azure SQL sink) once the schema exists.
- bcp / BULK INSERT — SQL Server's bulk data-load utilities; a scripted alternative for moving CARR's ~500 MB of data in.
- Ispirer / DBConvert — commercial tools that automate part of a PostgreSQL → Azure SQL move (schema + data + some code); leave the procedural/RLS tail manual.
- LLM-assisted SQL conversion — using a large language model (with human review) to convert the procedural + RLS + Supabase-specific SQL tail that commercial tools don't handle.
DevOps
- GitHub Enterprise — the enterprise tier of GitHub BW uses; CARR's repo is migrating into it.
- GitHub Actions — GitHub's CI/CD automation; can deploy straight to Azure.
- OIDC federated credentials — a passwordless, modern way for GitHub Actions to authenticate to Azure (preferred over storing secrets).
- Azure DevOps — Microsoft's alternative CI/CD suite (Pipelines, Boards). An enterprise picks GitHub Actions or Azure DevOps.
- Dataverse — Microsoft's structured data backend for Power Platform. Relevant because BW floated Power Apps + Dataverse virtual tables as a Lovable alternative.
- Power Apps / Power Automate / Logic Apps — Microsoft's low-code app + workflow tools BW proposed for some Edge-Function / UX needs.