CARR Azure Migration - Program Overview
Your entry point into the CARR → Azure migration. Start with the four-layer map below, jump into any part of the pack from the cards, then read the whole-system map for the full picture.
The CARR Platform in Four Layers
Jump into the pack
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/.Status update (2026-08-07): the network blocker is cleared - a BW-hosted in-VNet Azure Virtual Desktop went live 2026-08-06, so the Azure SQL database is reachable and SSMS is usable. The database migration (Phase 1) begins the week of Aug 11, 2026, gated only on the DB-principal grant + written confirmation
siplatformis CARR-dedicated. The Layer-4 agent runtime is built container-first on Azure Container Apps (Foundry optional, not required). Live status:docs/azure-migration/15_migration_status.md.
The whole system in one picture
CARR is not a single app. It is four layers, and a migration has to move all four. Read it top-down: start from the app the user sees, then the backend functions it calls, then the database under those, then what feeds it.
LAYER 1 APP (frontend) - React/Vite SPA + Lovable hosting + Supabase Auth
22 pages: Accounts, Target Universe, Campaigns, Pipeline, Content Studio, etc.
| app calls (supabase-js invoke)
v
LAYER 2 EDGE FUNCTIONS (backend logic) - 26 Deno/TS functions on Supabase Edge
AI/content gen · outreach sync (HeyReach/EmailBison) · scoring/classify · utility
(separate compute from Postgres - the "backend verbs" the app calls)
| SQL / PostgREST
v
LAYER 3 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 4 THE SUPPLY CHAIN (runs on BC infra, feeds CARR) - three separate things
4a APIs: ClinicalTrials/NIH/SEC/PatentsView/PubMed/RSS + Sales Nav/PhantomBuster/Clay/FullEnrich
4b Agent VE: bc-ops crons + Colab (capture -> summarize -> match -> enrich -> internalize)
4c Outreach + Hub: 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, 3 and 4, which are mostly invisible from the UI. This doc makes all four explicit.
Where each layer lands on Azure
| Layer | What it is today | Azure target | Effort | Detail doc |
|---|---|---|---|---|
| 1 - App (frontend) | React/Vite SPA (built in GitHub, hosted on Lovable — hosting only), Supabase Auth | Azure Static Web Apps (host) + custom API middleware on Container Apps (validates Entra JWT, injects identity for RLS) + Entra ID (workforce — all users BW-internal) | M (auth swap + middleware are the genuine work; hosting swap is trivial) | 03, 04, 05 |
| 2 - Edge functions (26) | Deno/TypeScript on Supabase Edge (separate compute from Postgres; the backend verbs the app calls) | 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 |
| 3 - 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 |
| 4a - Data-source APIs | BC-held third-party subscriptions + keys: life-sci/news feeds (ClinicalTrials, NIH, SEC, PatentsView, PubMed, RSS) + sourcing/enrichment SaaS (Sales Nav, PhantomBuster, Clay, FullEnrich) | CARR's own subscriptions + keys (Key Vault) + integration code | S-M (procurement + wiring) | 09_upstream_data_agents.md |
| 4b - Agent Virtual Environment | BC virtual environment (bc-ops crons + Colab notebooks) that captures/summarizes/matches/enriches/internalizes | CARR's own virtual environment (Container Apps + Functions timers) running the 7-agent fleet (Ingestion, Enrichment, Account-Matching HITL, Classification, SSO, Content, Orchestrator) | L (the genuine build) | 09_upstream_data_agents.md, 11_carr_agent_fleet.md |
| 4c - Outreach + Hub | HeyReach + EmailBison (BC workspaces) + BC Hub feed | CARR's own HeyReach/EmailBison workspaces; Hub retired via the Ingestion agent | M; 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)
- Auth replacement (Layer 1). Identity is resolved (all users are BW-internal — CARR is a BW subsidiary), but the auth system must be rebuilt: Supabase Auth → Entra workforce (MSAL on frontend, custom middleware validating Entra JWT, user provisioning via Entra admin portal). This gates the RLS rework. See
04. - Database rewrite (Layer 3). 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 4). Two separate things CARR must stand up: (4a) the APIs — CARR's own third-party subscriptions + keys + integration code — and (4b) the Agent Virtual Environment — CARR's own containers/scheduled jobs running the 7-agent fleet that captures/matches/enriches/internalizes. Plus (4c) their own HeyReach/EmailBison workspaces and phased retirement of the BC Hub. Deciding the API-subscription and Hub-retirement pace determines whether CARR runs standalone on Azure. See
09; target-state fleet in11_carr_agent_fleet.md.
Planned agent fleet (Layer 4 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 3) and Entra identity (Layer 1) 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 3).08_edge_function_census.md- all 26 edge functions (Layer 2).09_upstream_data_agents.md- the upstream tooling + custom code (Layer 4).11_carr_agent_fleet.md- the planned 7-agent fleet that internalizes Layer 4.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) - Compute host: Container Apps vs App Service vs AKS for the functions + middleware. (
03) - Frontend framework: accept the existing React SPA on SWA/ACA, or mandate Power Platform? Lovable is hosting only — no capability loss when removed. (
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.