High-Level Architecture — Layer View
Data Sources
M365
SharePoint
Documents, lists, sites
Outlook
Mail, calendar, contacts
Teams
Chat, channels, meetings
Business Central
ERP, finance, ops
API Gateway
Microsoft Graph
Unified REST API for M365
Entra ID (OAuth)
Identity + auth via MSAL
Application
Backend
FastAPI
Custom backend / orchestrator
Logic Apps
Event-driven workflows
Service Bus
Queue / topic messaging
Worker Apps
KEDA-scaled consumers
Cosmos DB
Idempotency + metadata
AI & RAG
Pipeline
Document Ingestion
Extract → chunk → embed
Vector Index
Azure AI Search
LLM (GPT / Claude)
Generation + reasoning
Copilot
Experience
Copilot Studio
Custom agent builder
M365 Copilot
Inline in Word, Outlook, Teams
Teams Bot / Web Chat
Conversational interface
Analytics &
Storage
Microsoft Fabric
Lakehouse + warehouse
OneLake
Unified data lake
Power BI
Dashboards + reporting
Cross-Cutting — Security & Infrastructure
Azure Key Vault
Secrets, certificates, API keys
Terraform / Bicep
IaC (Terraform MVP → Bicep v2)
GitHub Actions
CI/CD pipelines
Entra ID
Identity, RBAC, managed identities

FastAPI Backend

The central orchestrator. Runs on Azure Container Apps (consumption plan) — chosen over App Service for native KEDA integration, scale-to-zero cost savings, and the ability to run multiple apps (API + workers) in a shared environment with independent scaling.

Authenticates via MSAL for Python against Entra ID to obtain tokens for Microsoft Graph calls.

Python 3.11+ FastAPI MSAL Container Apps Docker

Microsoft Graph

Unified REST API layer for all M365 services. Provides read/write access to SharePoint files, Outlook mail, Teams channels, calendar, users, and Business Central data through a single authenticated endpoint.

FastAPI calls Graph endpoints using OAuth2 tokens. Supports delta queries for incremental sync and change notifications via webhooks.

REST API OAuth 2.0 Webhooks Delta Queries

Logic Apps (Workflows)

Low-code automation for event-driven workflows. Triggers on new Outlook mail, SharePoint file uploads, Teams messages, or scheduled intervals. Calls FastAPI endpoints for AI processing, classification, and routing.

Connectors for 400+ services. Handles approval flows, notifications, and cross-system orchestration without custom code.

Azure Logic Apps Connectors HTTP Actions Triggers

RAG Pipeline

Retrieval-Augmented Generation for document intelligence. Documents from SharePoint and Outlook are extracted, split into semantic chunks, embedded into vectors, and stored in a search index.

At query time, relevant chunks are retrieved via hybrid search (vector + keyword) and passed as context to the LLM for grounded, accurate answers.

Azure AI Search Embeddings Chunking Hybrid Search LLM

Copilot Studio Agent

Custom AI agent built in Microsoft Copilot Studio. Connects to Azure AI Search as its grounding knowledge source, enabling the agent to answer questions based on indexed organizational content with citations.

FastAPI endpoints are registered as plugins, allowing the agent to perform actions — create tasks, send notifications, query Business Central, or trigger Logic App workflows — all from natural language conversation.

Copilot Studio AI Search Plugin FastAPI Actions M365 Copilot Teams Web Chat

Microsoft Fabric

Unified analytics platform combining lakehouse, data warehouse, ETL pipelines, notebooks, and Power BI into a single managed environment. Serves as the central data and reporting layer for the entire solution.

Operational data from all integrated systems flows into OneLake for long-term storage, transformation, and business intelligence through Power BI dashboards.

OneLake Lakehouse SQL Warehouse Power BI Spark

Unified Event-Driven Pipeline

All M365 changes — new documents, emails, messages — flow through a single event backbone. Service Bus topics fan out to domain-specific worker apps that scale independently via KEDA.

Phase 1 Event Ingestion
01
Change Event
Graph sends change notification — new file in SharePoint, email in Outlook, message in Teams
02
Webhook App
FastAPI on Azure App Service receives, validates, and normalizes the notification
03
Enqueue
Normalized event published to Service Bus topic with metadata labels
Phase 2 Domain Fan-Out via Service Bus Subscriptions
Document Worker
Container App — documents-worker
Subscription filter: source = 'sharepoint'
Fetch file via Graph API
Extract text (PDF, DOCX, PPTX)
Chunk into 512–1024 token passages
Generate embeddings
Index in Azure AI Search
Output: Searchable vector index for RAG queries
Email Worker
Container App — email-worker
Subscription filter: source = 'outlook'
Fetch email content via Graph
Classify intent + urgency with LLM
Extract entities (client, project, amount)
Draft response or escalation
Route to Teams channel / SharePoint list / CRM
Output: Classified, routed, and optionally auto-replied emails
Teams / Comms Worker
Container App — comms-worker
Subscription filter: source = 'teams'
Process channel messages / meeting transcripts
Summarize discussions, extract action items
Create tasks in Planner via Graph
Post summaries back to channel
Output: Automated meeting notes, task creation, team notifications
Analytics Worker
Container App — analytics-worker
Subscription filter: all events (catch-all)
Receive all processed events from sibling workers
Normalize and transform into analytics schema
Write to Fabric OneLake / Lakehouse
Trigger Power BI dataset refresh
Output: Dashboards, KPIs, operational intelligence in Power BI
Phase 3 Copilot Integration & End-User Experience
08
AI Search Index
Chunked & embedded content from all workers converges in Azure AI Search — the shared knowledge layer
09
Copilot Studio Agent
Custom agent built in Copilot Studio connects to AI Search as a knowledge source + FastAPI for actions
10
Copilot Experience
Users interact via M365 Copilot, Teams chat, SharePoint web part, or standalone web app
11
Dashboards
Power BI surfaces operational KPIs, usage analytics, and pipeline health metrics
Copilot Studio — How It Binds to the Pipeline
M365 & External Docs
SharePoint files, Outlook emails, Teams content, uploaded documents
FastAPI / Domain Workers
Ingest, extract text, chunk into passages, generate embeddings
Azure AI Search Index
Vector + keyword hybrid index — the shared knowledge base for all AI surfaces
Copilot Studio Agent
Custom agent with AI Search as knowledge source and FastAPI plugin for actions
User Channels
M365 Copilot · Teams chat · SharePoint web part · standalone web chat
Knowledge source — Copilot Studio connects directly to Azure AI Search as a grounding data source. The agent retrieves relevant chunks at query time and generates cited, contextual answers.
Custom actions — The agent can call FastAPI endpoints as plugins to perform actions: create tasks, send emails, update SharePoint lists, or trigger Logic App workflows — all from natural language.
Multi-channel — A single Copilot Studio agent deploys to M365 Copilot (inline in Word, Outlook, Teams), as a Teams bot, as a SharePoint web part, or as a standalone web chat widget — same knowledge, same actions, multiple surfaces.
Always current — Because the event-driven pipeline continuously indexes new content, the Copilot agent always queries the latest knowledge without manual re-indexing or batch schedules.
KEDA Auto-Scaling — Per Worker
Service Bus Subscription
Each domain worker has its own subscription with filtered messages
KEDA Scale Rule
Monitors subscription message count independently per worker
Independent Scaling
Document worker may scale to 5 replicas while email worker stays at 1
Scale to Zero
Idle workers drop to 0 replicas — no cost until next event arrives
Domain isolation — Each worker is a separate Container App with its own codebase, scaling rules, and deployment lifecycle. A bug in the email worker cannot affect document processing.
Parallel processing — A single Graph change notification publishes once to the topic. All matching subscriptions receive it simultaneously, enabling parallel domain processing with no duplication logic.
Durability & retry — Service Bus provides at-least-once delivery with configurable retry policies and dead-letter queues per subscription. Failed messages are preserved for inspection and reprocessing.

Idempotency & Document Metadata Tracking

Every processed event is tracked in Azure Cosmos DB (NoSQL API) to guarantee exactly-once processing semantics and provide a complete audit trail of all pipeline activity.

Why Azure Cosmos DB
Sub-millisecond lookups — Idempotency checks happen on every incoming message. Cosmos DB delivers single-digit-ms point reads by partition key, keeping worker latency low even under burst load.
Schema-flexible documents — Metadata shapes vary across document types (emails, files, messages, meetings). Cosmos DB's schemaless model handles this naturally without migrations.
KEDA-friendly — No connection pool exhaustion under scale-to-zero/scale-up patterns. The HTTP-based SDK handles ephemeral workers cleanly, unlike SQL connection pooling.
Built-in TTL — Processing records can auto-expire after a configurable retention window, keeping storage costs bounded without manual cleanup jobs.
Flow Idempotent Message Processing
01
Receive
Worker pulls message from Service Bus subscription
02
Check
Point read in Cosmos DB by idempotency key — if exists and status = completed, skip
03
Claim
Upsert record with status = processing and a lease timestamp to prevent duplicate work
04
Process
Execute domain logic — chunk, embed, classify, route, or index
05
Commit
Update record to status = completed with output metadata and processing duration
06
Ack
Complete the Service Bus message — removed from queue only after successful commit
Schema Cosmos DB Document Structure
Processing Record
{
  "id":              "graph-notif-a1b2c3d4",
  "partitionKey":    "documents-worker",
  "source":          "sharepoint",
  "resourceId":      "/sites/ops/docs/Q2-report.pdf",
  "changeType":      "updated",
  "graphTimestamp":   "2026-03-10T14:22:00Z",

  "status":          "completed",
  "claimedAt":       "2026-03-10T14:22:01Z",
  "completedAt":     "2026-03-10T14:22:08Z",
  "durationMs":      7042,
  "workerInstance":  "documents-worker-replica-3",

  "output": {
    "chunksCreated":  24,
    "indexName":      "corporate-knowledge",
    "embeddingModel": "text-embedding-3-large",
    "contentHash":    "sha256:e3b0c442..."
  },

  "ttl":             2592000
}
Partition key Partition by worker name — each domain worker queries only its own records, ensuring hot partition isolation and efficient point reads.
Idempotency key The id is derived from the Graph change notification ID. Duplicate deliveries from Service Bus resolve to the same document — Cosmos upsert is atomic.
Content hash SHA-256 hash of the source content. If a file is modified but produces the same hash, re-indexing is skipped — saving embedding and AI Search write costs.
Lease & timeout If a worker crashes mid-processing, the claimedAt timestamp acts as a lease. A background sweep or the next delivery reclaims stale records after a configurable timeout (e.g. 5 minutes).
TTL auto-expiry Records expire after 30 days (2592000 seconds) by default. Adjustable per domain — email records may retain longer for audit compliance.
Observability Processing duration, chunk counts, and error fields feed into Fabric analytics for pipeline health dashboards — latency trends, failure rates, throughput by domain.

Use Case Examples

Practical scenarios showing how the architecture components work together to solve real business problems.

RAG + Graph

Company Knowledge Assistant

Employees ask natural-language questions about internal policies, contracts, or product specs. The system retrieves relevant SharePoint documents via Graph, chunks and embeds them, then delivers precise, cited answers through a Teams bot or web chat.

SharePoint→ Graph API→ FastAPI→ RAG Pipeline→ Teams Bot
Logic Apps + FastAPI

Intelligent Email Triage

Incoming client emails in Outlook trigger a Logic App that calls FastAPI. The AI classifies intent (support request, invoice, complaint, inquiry), extracts key entities, drafts a response, and routes to the correct Teams channel or SharePoint list. Urgent items get flagged with priority notifications.

Outlook→ Logic App→ FastAPI + LLM→ Teams / SharePoint
Fabric + Power BI

Business Central Analytics Dashboard

Sales orders, inventory levels, and financial data from Business Central flow into Microsoft Fabric's lakehouse via scheduled pipelines. Power BI dashboards surface real-time KPIs — revenue trends, margin analysis, fulfillment rates — accessible to leadership directly in Teams tabs.

Business Central→ Graph API→ Fabric Lakehouse→ Power BI
Graph + Logic Apps

Client Onboarding Automation

When a new client record is created in the CRM, a Logic App triggers an automated onboarding workflow: creates a dedicated SharePoint site with template documents, sends a welcome email sequence via Outlook, schedules a kickoff meeting in calendar, and posts an intro in the team's channel.

CRM Trigger→ Logic App→ Graph API→ SharePoint + Outlook + Teams
RAG + Fabric

Compliance & Contract Review

Legal and compliance documents stored in SharePoint are continuously ingested, chunked, and indexed. Staff can query across thousands of contracts — "which agreements expire in Q2?" or "find all clauses related to data retention." Analytics on query patterns and document usage flow to Fabric for compliance reporting.

SharePoint Docs→ RAG Index→ FastAPI Query→ Fabric Reports
Full Stack

Meeting Intelligence Hub

Teams meeting transcripts and recordings are processed by FastAPI — summarized, action items extracted, and decisions logged. Summaries are posted back to the meeting chat, action items create tasks in Planner via Graph, and meeting analytics (frequency, topics, participation) are tracked in Fabric dashboards.

Teams Meetings→ FastAPI + LLM→ Graph (Planner)→ Fabric Analytics

Technology Stack Overview

Component Role Category Alternatives
Microsoft Fabric Lakehouse + warehouse + BI + ETL Analytics Databricks, Snowflake, BigQuery
Microsoft Graph Unified API for M365 services API Layer Google Workspace API, Slack API
FastAPI Custom backend / orchestrator Backend Django, Express, .NET
Azure Logic Apps Low-code workflow automation Automation n8n, Zapier, Power Automate
Azure AI Search Vector + hybrid search index AI / Search Elasticsearch, Weaviate
Azure Service Bus Message queue / topic for event decoupling Messaging RabbitMQ, Amazon SQS
KEDA Event-driven autoscaler for Container Apps Scaling HPA, AWS Lambda triggers
Azure Cosmos DB Idempotency store + document processing metadata State / Metadata DynamoDB, MongoDB Atlas, Azure SQL
Power BI Dashboards + reporting Analytics Tableau, Looker, Metabase
Copilot Studio Custom AI agent builder + multi-channel deployment AI / Copilot Custom Teams bot, Botpress, Voiceflow
Azure Key Vault Centralized secret, certificate, and key management Security AWS Secrets Manager, HashiCorp Vault
Terraform → Bicep Infrastructure as Code — Terraform for MVP, Bicep migration for v2 Infrastructure Terraform, Pulumi, CloudFormation

Technical Highlights

Cloud-Native & Scalable

The entire platform runs on Azure Container Apps (consumption plan) with native KEDA autoscaling, scale-to-zero cost savings, and independent scaling per worker. Logic Apps handle workflow automation, Fabric covers analytics — all managed services with minimal infrastructure overhead.

AI-Powered Document Intelligence

Documents and emails are automatically chunked into semantic passages, embedded as vectors, and indexed for hybrid search — enabling precise, grounded answers from your organization's knowledge base.

Secure Identity & Access

All service-to-service communication is authenticated through Microsoft Entra ID with OAuth 2.0 via MSAL. Azure Key Vault stores all secrets centrally — accessed only through managed identities with zero secrets in code or config.

Reproducible Infrastructure

All Azure resources are provisioned via Terraform (MVP) with a planned migration to Bicep for v2. Environments (dev, staging, prod) are identical by definition, deployed through GitHub Actions CI/CD with no manual portal configuration.

Infrastructure & Deployment

All infrastructure is defined as code, secrets are centralized in Key Vault, and environments are provisioned through automated pipelines — ensuring security, reproducibility, and auditability across all stages.

Secrets Azure Key Vault — Centralized Secret Management
What's Stored
Microsoft Graph app client secrets & certificates
Cosmos DB connection strings
Service Bus shared access keys
Azure AI Search admin keys
LLM API keys (OpenAI / Anthropic)
Copilot Studio plugin auth tokens
How It's Accessed
Managed identities on all App Services & Container Apps
No secrets in environment variables, code, or config files
RBAC-scoped access — each service only reads its own secrets
Key Vault references in App Service configuration
Automatic secret rotation without redeployment
Audit & Compliance
Full access logging via Azure Monitor diagnostic settings
Soft-delete and purge protection enabled
Network restrictions — private endpoint or service firewall
Alerts on unauthorized access attempts
IaC Infrastructure as Code — Terraform (MVP) → Bicep (Target)
Terraform — MVP Phase
# main.tf
variable "env" {
  type    = string
  default = "dev"
  validation {
    condition     = contains(["dev","staging","prod"], var.env)
    error_message = "Must be dev, staging, or prod."
  }
}

variable "location" {
  type    = string
  default = "eastus"  # Confirmed with client
}

resource "azurerm_resource_group" "main" {
  name     = "rg-m365-platform-${var.env}"
  location = var.location
}

module "keyvault"       { source = "./modules/keyvault"       }
module "cosmos"         { source = "./modules/cosmos"         }
module "servicebus"     { source = "./modules/servicebus"     }
module "ai_search"      { source = "./modules/ai-search"      }
module "openai"         { source = "./modules/openai"         }
module "container_apps"  { source = "./modules/container-apps"  }
MVP uses Terraform The MVP sprint uses Terraform — proven tooling with full azurerm provider coverage for all resources in scope (Container Apps, Cosmos DB, Service Bus, AI Search, Key Vault, OpenAI). No learning curve risk on a 17-day deadline.
Target state: Bicep For v2 (Logic Apps, Copilot Studio configs, Fabric workspaces), migration to Azure Bicep is planned. Bicep has same-day Azure resource support with zero provider lag and no state file management. The two can coexist during transition.
State management Terraform state is stored in an Azure Storage Account with blob lease locking. Created manually as the first action on Day 1 before any terraform apply.
Environment parity A single var.env variable (dev / staging / prod) produces identical infrastructure with different naming and SKUs. Parameter files per environment — no branching.
Modular structure Resources are organized into Terraform modules: keyvault, cosmos, servicebus, ai-search, openai, container-apps — each independently testable and reusable.
Secrets flow Terraform provisions Key Vault and writes connection strings as secrets at deploy time. Container Apps reference secrets via Key Vault URI using managed identity — never plaintext in config or pipeline logs.
Deploy CI/CD Pipeline — From Code to Production
01
PR Created
Developer pushes code — GitHub Actions triggers terraform plan (if infra changed) and Docker image build (if app changed)
02
Review
Plan diff reviewed — infrastructure and app changes visible before merge
03
Deploy Infra
terraform apply provisions or updates Azure resources (runs only when infra/ changes)
04
Push Image
Docker images pushed to Azure Container Registry with version tag
05
Deploy Apps
Container Apps, App Service, and Logic Apps updated with new revision
06
Health Check
Readiness probes confirm all services healthy — automatic rollback on failure

Operational Considerations

Key operational factors to be aware of during implementation and production use.

Graph API Rate Limits

Microsoft Graph enforces per-app and per-tenant throttling. Bulk document uploads (e.g. 500 files at once) will generate a burst of change notifications. Service Bus absorbs the spike, but workers calling Graph to fetch file content can hit 429 (Too Many Requests) responses. All Graph calls use exponential backoff retry with jitter. Workers process at a sustainable rate rather than unbounded parallelism.

Azure OpenAI Throttling

Embedding models have tokens-per-minute (TPM) limits. A batch of 500 documents at ~24 chunks each produces ~12,000 embedding calls — enough to hit default quotas. The document worker uses rate-limited parallel calls with configurable concurrency. For sustained high-volume ingestion, TPM quota increases can be requested through the Azure portal.

Document Size Limits

Very large files (200MB+ PowerPoint, 500+ page PDF) can exceed Container Apps memory limits during text extraction. The worker enforces a configurable max file size check before processing (default: 100MB). Oversized files are logged and skipped with an error status in Cosmos DB. Chunking strategy handles long documents gracefully — text is split into passages regardless of total document length.

Graph Webhook Lifecycle

Graph change notification subscriptions expire after a maximum of 4,320 minutes (~3 days) for most resource types. A background renewal task runs automatically before expiry — no manual intervention required. If renewal fails (e.g. temporary Graph outage), the system detects the expired subscription on the next health check and recreates it.

Estimated Azure Cost Profile

Monthly Azure consumption estimate for the MVP configuration. All resources run in the client's subscription. Costs scale with document volume and query frequency.

Container Apps (Consumption)

FastAPI API + document worker. Scale to zero when idle. Billed per vCPU-second and GB-second of active use. For MVP traffic: ~$15–$40/month. Near-zero cost during idle periods.

Azure AI Search (Basic SKU)

Vector + keyword hybrid index. Basic tier supports up to 1GB index / 5 indexes. Sufficient for MVP with thousands of document chunks. ~$75/month. Can upgrade to Standard for larger knowledge bases in v2.

Azure OpenAI

Pay-per-token for embeddings (text-embedding-3-large) and chat completions (gpt-4o-mini). Embedding cost is primarily during initial indexing. Query cost depends on usage. ~$20–$60/month for moderate use (1,000 documents + 500 queries/month).

Cosmos DB (Serverless)

Idempotency store. Serverless mode — pay per RU consumed, no provisioned capacity. Point reads for idempotency checks are 1 RU each. ~$5–$15/month. TTL auto-expires old records to keep storage bounded.

Service Bus (Standard)

Message queue/topic for event decoupling. Standard tier supports topics + subscriptions. ~$10/month base + per-operation cost (negligible at MVP scale).

Other (Key Vault, ACR, Log Analytics)

Key Vault: ~$1/month. Container Registry (Basic): ~$5/month. Log Analytics: ~$5–$15/month depending on log volume. Terraform state Storage Account: <$1/month.

Total estimated MVP cost $150–$250/month for moderate usage (1,000 documents indexed, 500 queries/month). Actual cost depends on document volume, query frequency, and OpenAI model choice (gpt-4o-mini vs gpt-4o).
Cost optimization built in Container Apps scale to zero when idle. Cosmos DB serverless charges only for actual operations. Content hashing skips re-embedding unchanged files. AI Search Basic tier is the lowest viable SKU.
Separate from development fees Azure infrastructure costs are billed directly to the client's Azure subscription. Development fees (sprint budget) are invoiced separately per the sprint plan milestones.