📋 Table of Contents
- Azure Authentication & Setup
- Azure SQL Database Connection
- Azure Cosmos DB Integration
- Power BI Embedded Integration
- Microsoft Graph API Integration
- Azure Functions for Real-Time Processing
- Azure IoT Hub for Supply Chain Sensors
- Microsoft Teams Integration
- Azure Cognitive Services for AI Insights
- Azure Event Grid for Alerts
- Complete Integration Example
- Environment Variables
- Deployment Scripts
🔐 1. Azure Authentication & Setup
Azure AD Authentication with MSAL.js
npm install @azure/msal-browser
JavaScript
import { PublicClientApplication } from "@azure/msal-browser";
const msalConfig = {
auth: {
clientId: "YOUR_CLIENT_ID", // Azure AD App Registration Client ID
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
redirectUri: "https://yourdomain.com/optimind"
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false
}
};
const msalInstance = new PublicClientApplication(msalConfig);
// Login function
async function loginToAzure() {
try {
const loginResponse = await msalInstance.loginPopup({
scopes: ["User.Read", "Files.Read.All", "Sites.Read.All"]
});
console.log("Login successful:", loginResponse);
return loginResponse.account;
} catch (error) {
console.error("Login failed:", error);
throw error;
}
}
// Get access token
async function getAccessToken() {
const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
throw new Error("No accounts found. Please login first.");
}
const request = {
scopes: ["User.Read"],
account: accounts[0]
};
try {
const response = await msalInstance.acquireTokenSilent(request);
return response.accessToken;
} catch (error) {
// Fallback to interactive login
const response = await msalInstance.acquireTokenPopup(request);
return response.accessToken;
}
}
// Initialize authentication on page load
msalInstance.initialize().then(() => {
console.log("MSAL initialized");
// Check if user is already logged in
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
console.log("User already logged in:", accounts[0].username);
}
});
💡 Key Points
- Replace YOUR_CLIENT_ID with your Azure AD App Registration Client ID
- Replace YOUR_TENANT_ID with your Azure AD Tenant ID
- Configure redirect URIs in Azure AD App Registration settings
- Request only the scopes you need for security best practices
💾 2. Azure SQL Database Connection
Connect to Azure SQL for Inventory Data
npm install mssql
JavaScript (Backend - Node.js)
const sql = require('mssql');
const sqlConfig = {
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: 'OptiMindDB',
server: 'your-server.database.windows.net',
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000
},
options: {
encrypt: true, // Required for Azure
trustServerCertificate: false
}
};
// Get inventory data
async function getInventoryData() {
try {
await sql.connect(sqlConfig);
const result = await sql.query`
SELECT
i.SKU,
i.CategoryName,
i.CurrentStock,
i.OptimalLevel,
i.WarehouseLocation,
i.LastUpdated,
(i.CurrentStock - i.OptimalLevel) as Variance
FROM Inventory i
WHERE i.IsActive = 1
ORDER BY i.LastUpdated DESC
`;
return result.recordset;
} catch (err) {
console.error('SQL error:', err);
throw err;
}
}
// Update inventory levels
async function updateInventoryLevel(sku, newQuantity, warehouseId) {
try {
await sql.connect(sqlConfig);
const result = await sql.query`
UPDATE Inventory
SET CurrentStock = ${newQuantity},
LastUpdated = GETDATE(),
UpdatedBy = ${userId}
WHERE SKU = ${sku}
AND WarehouseID = ${warehouseId}
`;
return result.rowsAffected[0] > 0;
} catch (err) {
console.error('Update error:', err);
throw err;
}
}
// Get warehouse performance metrics
async function getWarehouseMetrics() {
try {
await sql.connect(sqlConfig);
const result = await sql.query`
SELECT
w.WarehouseName,
w.Location,
COUNT(DISTINCT o.OrderID) as DailyThroughput,
AVG(o.PickAccuracy) as PickAccuracy,
AVG(DATEDIFF(HOUR, o.OrderReceived, o.OrderDispatched)) as AvgCycleTime,
(w.CurrentUtilization / w.MaxCapacity * 100) as UtilizationPercent
FROM Warehouses w
LEFT JOIN Orders o ON w.WarehouseID = o.WarehouseID
WHERE o.OrderDate >= DATEADD(DAY, -1, GETDATE())
GROUP BY w.WarehouseID, w.WarehouseName, w.Location,
w.CurrentUtilization, w.MaxCapacity
`;
return result.recordset;
} catch (err) {
console.error('Metrics error:', err);
throw err;
}
}
Real-Time Inventory
Query current stock levels across all warehouses
Update Operations
Modify inventory levels with audit trails
Performance Metrics
Track warehouse KPIs and efficiency
Secure Connection
Encrypted connections to Azure SQL
🌐 3. Azure Cosmos DB Integration
Real-Time Supply Chain Events with Cosmos DB
npm install @azure/cosmos
JavaScript
const { CosmosClient } = require("@azure/cosmos");
const endpoint = "https://your-account.documents.azure.com:443/";
const key = process.env.COSMOS_KEY;
const client = new CosmosClient({ endpoint, key });
const databaseId = "OptiMindDB";
const containerId = "SupplyChainEvents";
// Initialize database and container
async function initCosmosDB() {
const { database } = await client.databases.createIfNotExists({
id: databaseId
});
const { container } = await database.containers.createIfNotExists({
id: containerId,
partitionKey: { paths: ["/eventType"] }
});
return { database, container };
}
// Log supply chain event
async function logSupplyChainEvent(eventData) {
const { container } = await initCosmosDB();
const event = {
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
eventType: eventData.type, // "shipment", "inventory_update", "alert"
timestamp: new Date().toISOString(),
warehouseId: eventData.warehouseId,
severity: eventData.severity,
details: eventData.details,
metadata: {
userId: eventData.userId,
source: "OptiMind",
version: "1.0"
}
};
const { resource: createdItem } = await container.items.create(event);
return createdItem;
}
// Query recent events
async function getRecentEvents(eventType = null, limit = 100) {
const { container } = await initCosmosDB();
let querySpec = {
query: eventType
? "SELECT * FROM c WHERE c.eventType = @eventType ORDER BY c.timestamp DESC OFFSET 0 LIMIT @limit"
: "SELECT * FROM c ORDER BY c.timestamp DESC OFFSET 0 LIMIT @limit",
parameters: [
{ name: "@limit", value: limit }
]
};
if (eventType) {
querySpec.parameters.push({ name: "@eventType", value: eventType });
}
const { resources: items } = await container.items
.query(querySpec)
.fetchAll();
return items;
}
✅ Best Practices
- Use appropriate partition keys for optimal performance (e.g., eventType, warehouseId)
- Index frequently queried properties
- Implement TTL (Time-to-Live) for automatic event cleanup
- Use change feed for real-time event processing
📊 4. Power BI Embedded Integration
Embed Power BI Dashboards in OptiMind
npm install powerbi-client
JavaScript
import * as pbi from 'powerbi-client';
// Get Power BI embed token (Backend API call)
async function getPowerBIEmbedToken() {
const response = await fetch('/api/powerbi/embed-token', {
headers: {
'Authorization': `Bearer ${await getAccessToken()}`
}
});
return await response.json();
}
// Embed Power BI report
async function embedPowerBIReport(containerId) {
const embedData = await getPowerBIEmbedToken();
const config = {
type: 'report',
tokenType: pbi.models.TokenType.Embed,
accessToken: embedData.token,
embedUrl: embedData.embedUrl,
id: embedData.reportId,
permissions: pbi.models.Permissions.Read,
settings: {
filterPaneEnabled: false,
navContentPaneEnabled: true,
layoutType: pbi.models.LayoutType.Custom,
customLayout: {
displayOption: pbi.models.DisplayOption.FitToWidth
},
background: pbi.models.BackgroundType.Transparent
}
};
const powerbi = new pbi.service.Service(
pbi.factories.hpmFactory,
pbi.factories.wpmpFactory,
pbi.factories.routerFactory
);
const reportContainer = document.getElementById(containerId);
const report = powerbi.embed(reportContainer, config);
// Event handlers
report.on('loaded', () => {
console.log('Power BI Report loaded');
});
report.on('error', (event) => {
console.error('Power BI Error:', event.detail);
});
return report;
}
Backend: Generate Power BI Embed Token
JavaScript (Azure Function / Express.js)
async function generateEmbedToken(req, res) {
const { default: fetch } = await import('node-fetch');
const tenantId = process.env.AZURE_TENANT_ID;
const clientId = process.env.POWERBI_CLIENT_ID;
const clientSecret = process.env.POWERBI_CLIENT_SECRET;
const workspaceId = process.env.POWERBI_WORKSPACE_ID;
const reportId = process.env.POWERBI_REPORT_ID;
// Get Azure AD token
const tokenResponse = await fetch(
`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
scope: 'https://analysis.windows.net/powerbi/api/.default'
})
}
);
const tokenData = await tokenResponse.json();
const accessToken = tokenData.access_token;
// Get embed token
const embedResponse = await fetch(
`https://api.powerbi.com/v1.0/myorg/groups/${workspaceId}/reports/${reportId}/GenerateToken`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
accessLevel: 'View',
allowSaveAs: false
})
}
);
const embedData = await embedResponse.json();
res.json({
token: embedData.token,
embedUrl: `https://app.powerbi.com/reportEmbed?reportId=${reportId}&groupId=${workspaceId}`,
reportId: reportId
});
}
📁 5. Microsoft Graph API Integration
Access SharePoint and OneDrive Supply Chain Documents
npm install @microsoft/microsoft-graph-client
JavaScript
import { Client } from "@microsoft/microsoft-graph-client";
// Initialize Graph client with access token
function getGraphClient(accessToken) {
return Client.init({
authProvider: (done) => {
done(null, accessToken);
}
});
}
// Get supply chain documents from SharePoint
async function getSupplyChainDocuments() {
const accessToken = await getAccessToken();
const client = getGraphClient(accessToken);
try {
const response = await client
.api('/sites/{site-id}/drive/root/children')
.filter("folder/childCount gt 0 or name eq 'Supply Chain Reports'")
.get();
return response.value;
} catch (error) {
console.error('Error fetching documents:', error);
throw error;
}
}
// Upload inventory report to OneDrive
async function uploadInventoryReport(reportData, fileName) {
const accessToken = await getAccessToken();
const client = getGraphClient(accessToken);
const fileContent = JSON.stringify(reportData, null, 2);
try {
const uploadedFile = await client
.api(`/me/drive/root:/OptiMind/${fileName}:/content`)
.put(fileContent);
console.log('File uploaded:', uploadedFile.webUrl);
return uploadedFile;
} catch (error) {
console.error('Upload error:', error);
throw error;
}
}
// Get user profile and preferences
async function getUserProfile() {
const accessToken = await getAccessToken();
const client = getGraphClient(accessToken);
try {
const user = await client
.api('/me')
.select('displayName,mail,jobTitle,department')
.get();
return user;
} catch (error) {
console.error('Error fetching user:', error);
throw error;
}
}
⚡ 6. Azure Functions for Real-Time Processing
Serverless Functions for Supply Chain Analytics
JavaScript (Azure Function - HTTP Trigger)
// File: AnalyzeInventory/index.js
const { CosmosClient } = require("@azure/cosmos");
module.exports = async function (context, req) {
context.log('Inventory analysis triggered');
const warehouseId = req.query.warehouseId || req.body?.warehouseId;
if (!warehouseId) {
context.res = {
status: 400,
body: "Please provide a warehouseId"
};
return;
}
try {
const client = new CosmosClient(process.env.COSMOS_CONNECTION_STRING);
const database = client.database("OptiMindDB");
const container = database.container("Inventory");
const querySpec = {
query: "SELECT * FROM c WHERE c.warehouseId = @warehouseId",
parameters: [{ name: "@warehouseId", value: warehouseId }]
};
const { resources: items } = await container.items
.query(querySpec)
.fetchAll();
// Perform analysis
const analysis = {
totalItems: items.length,
totalValue: items.reduce((sum, item) => sum + (item.quantity * item.unitCost), 0),
overstock: items.filter(item => item.quantity > item.optimalLevel * 1.2),
understock: items.filter(item => item.quantity < item.optimalLevel * 0.8),
recommendations: []
};
// Generate recommendations
if (analysis.overstock.length > 0) {
analysis.recommendations.push({
type: "OVERSTOCK_ALERT",
severity: "warning",
message: `${analysis.overstock.length} items are overstocked`,
potentialSavings: analysis.overstock.reduce((sum, item) =>
sum + ((item.quantity - item.optimalLevel) * item.unitCost * 0.15), 0
)
});
}
context.res = {
status: 200,
body: analysis
};
} catch (error) {
context.log.error('Analysis error:', error);
context.res = {
status: 500,
body: `Error: ${error.message}`
};
}
};
📡 7. Azure IoT Hub for Supply Chain Sensors
Real-Time Sensor Data from Warehouses
npm install azure-iothub azure-iot-device azure-iot-device-mqtt
JavaScript
const { EventHubConsumerClient } = require("@azure/event-hubs");
const connectionString = process.env.IOT_HUB_CONNECTION_STRING;
const consumerGroup = "$Default";
async function receiveIoTTelemetry() {
const client = new EventHubConsumerClient(
consumerGroup,
connectionString
);
const subscription = client.subscribe({
processEvents: async (events, context) => {
for (const event of events) {
const deviceId = context.partitionId;
const telemetry = event.body;
console.log(`Device ${deviceId}:`, telemetry);
// Process sensor data
await processSensorData({
deviceId: deviceId,
temperature: telemetry.temperature,
humidity: telemetry.humidity,
location: telemetry.location,
timestamp: event.enqueuedTimeUtc
});
// Check for alerts
if (telemetry.temperature > 25 || telemetry.humidity > 70) {
await sendEnvironmentAlert({
deviceId: deviceId,
temperature: telemetry.temperature,
humidity: telemetry.humidity,
severity: 'warning'
});
}
}
},
processError: async (err, context) => {
console.error('Error:', err);
}
});
console.log('Listening for IoT telemetry...');
}
💬 8. Microsoft Teams Integration
Send Alerts to Teams Channels
npm install @microsoft/microsoft-graph-client
JavaScript
// Send alert to Teams channel
async function sendTeamsAlert(alertData) {
const accessToken = await getAccessToken();
const client = getGraphClient(accessToken);
const teamId = process.env.TEAMS_TEAM_ID;
const channelId = process.env.TEAMS_CHANNEL_ID;
const message = {
body: {
contentType: "html",
content: `
🚨 OptiMind Alert
Type: ${alertData.type}
Severity: ${alertData.severity.toUpperCase()}
Message: ${alertData.message}
Warehouse: ${alertData.warehouse}
Time: ${new Date().toLocaleString()}
`
}
};
try {
await client
.api(`/teams/${teamId}/channels/${channelId}/messages`)
.post(message);
console.log('Alert sent to Teams');
} catch (error) {
console.error('Teams alert error:', error);
}
}
🤖 9. Azure Cognitive Services for AI Insights
AI-Powered Demand Forecasting
npm install @azure/ai-text-analytics
JavaScript
const { TextAnalyticsClient, AzureKeyCredential } = require("@azure/ai-text-analytics");
const endpoint = process.env.COGNITIVE_SERVICES_ENDPOINT;
const apiKey = process.env.COGNITIVE_SERVICES_KEY;
const client = new TextAnalyticsClient(endpoint, new AzureKeyCredential(apiKey));
// Analyze supply chain feedback
async function analyzeFeedback(feedbackTexts) {
try {
const sentimentResults = await client.analyzeSentiment(feedbackTexts);
const analysis = sentimentResults.map((result, i) => ({
text: feedbackTexts[i],
sentiment: result.sentiment,
scores: result.confidenceScores,
keyPhrases: []
}));
// Extract key phrases
const keyPhraseResults = await client.extractKeyPhrases(feedbackTexts);
keyPhraseResults.forEach((result, i) => {
analysis[i].keyPhrases = result.keyPhrases;
});
return analysis;
} catch (error) {
console.error('Analysis error:', error);
throw error;
}
}
🔔 10. Azure Event Grid for Alerts
Real-Time Event-Driven Architecture
npm install @azure/eventgrid
JavaScript
const { EventGridPublisherClient, AzureKeyCredential } = require("@azure/eventgrid");
const endpoint = process.env.EVENT_GRID_ENDPOINT;
const accessKey = process.env.EVENT_GRID_KEY;
const client = new EventGridPublisherClient(
endpoint,
"AzureKeyCredential",
new AzureKeyCredential(accessKey)
);
// Publish inventory event
async function publishInventoryEvent(eventType, eventData) {
const events = [{
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
subject: `inventory/${eventData.warehouseId}/${eventData.sku}`,
dataVersion: "1.0",
eventType: eventType,
eventTime: new Date(),
data: {
sku: eventData.sku,
warehouseId: eventData.warehouseId,
currentStock: eventData.currentStock,
optimalLevel: eventData.optimalLevel
}
}];
await client.send(events);
}
🎯 11. Complete Integration Example
Full OptiMind Dashboard with Microsoft Stack
📋 Complete Solution
This example demonstrates a complete OptiMind dashboard integrating Azure AD authentication, Power BI embedding, and real-time inventory data fetching.
HTML + JavaScript
// MSAL Configuration
const msalConfig = {
auth: {
clientId: "YOUR_CLIENT_ID",
authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
redirectUri: window.location.origin
}
};
const msalInstance = new msal.PublicClientApplication(msalConfig);
async function login() {
const response = await msalInstance.loginPopup({
scopes: ["User.Read", "Files.Read.All"]
});
await loadDashboard();
}
async function loadInventoryData() {
const token = await getAccessToken();
const response = await fetch('/api/inventory', {
headers: { 'Authorization': `Bearer ${token}` }
});
return await response.json();
}
⚙️ Environment Variables (.env file)
Environment Variables
# Azure AD
AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
# Azure SQL Database
DB_USER=optimind-admin
DB_PASSWORD=your-secure-password
DB_SERVER=your-server.database.windows.net
DB_NAME=OptiMindDB
# Azure Cosmos DB
COSMOS_ENDPOINT=https://your-account.documents.azure.com:443/
COSMOS_KEY=your-cosmos-key
COSMOS_CONNECTION_STRING=your-connection-string
# Power BI
POWERBI_CLIENT_ID=your-powerbi-app-id
POWERBI_CLIENT_SECRET=your-powerbi-secret
POWERBI_WORKSPACE_ID=your-workspace-id
POWERBI_REPORT_ID=your-report-id
# Azure IoT Hub
IOT_HUB_CONNECTION_STRING=your-iot-hub-connection
# Azure Cognitive Services
COGNITIVE_SERVICES_ENDPOINT=https://your-region.api.cognitive.microsoft.com/
COGNITIVE_SERVICES_KEY=your-cognitive-key
# Azure Machine Learning
AML_ENDPOINT=https://your-ml-endpoint.azureml.net/score
AML_API_KEY=your-ml-api-key
# Azure Event Grid
EVENT_GRID_ENDPOINT=https://your-topic.your-region.eventgrid.azure.net/api/events
EVENT_GRID_KEY=your-event-grid-key
# Microsoft Teams
TEAMS_TEAM_ID=your-team-id
TEAMS_CHANNEL_ID=your-channel-id
# Email (Office 365)
EMAIL_USER=optimind@company.com
EMAIL_PASSWORD=your-email-password
⚠️ Security Warning
Never commit your .env file to version control. Add it to .gitignore and use Azure Key Vault for production secrets.
🚀 Deployment Scripts
Azure CLI Deployment
Bash
#!/bin/bash
# Login to Azure
az login
# Set subscription
az account set --subscription "YOUR_SUBSCRIPTION_ID"
# Create Resource Group
az group create --name OptiMindRG --location eastus
# Create Azure SQL Database
az sql server create \
--name optimind-sql-server \
--resource-group OptiMindRG \
--location eastus \
--admin-user optimindadmin \
--admin-password YourSecurePassword123!
az sql db create \
--resource-group OptiMindRG \
--server optimind-sql-server \
--name OptiMindDB \
--service-objective S0
# Create Cosmos DB
az cosmosdb create \
--name optimind-cosmos \
--resource-group OptiMindRG \
--locations regionName=eastus failoverPriority=0
# Create IoT Hub
az iot hub create \
--name optimind-iot-hub \
--resource-group OptiMindRG \
--sku S1 \
--location eastus
# Create Function App
az functionapp create \
--resource-group OptiMindRG \
--consumption-plan-location eastus \
--runtime node \
--runtime-version 18 \
--functions-version 4 \
--name optimind-functions \
--storage-account optimindstorage
echo "Azure resources created successfully!"
✅ Next Steps
- Set up Azure AD App Registration for authentication
- Configure Power BI workspace and create reports
- Deploy Azure Functions for serverless processing
- Set up IoT Hub for warehouse sensors
- Configure Event Grid for real-time alerts
- Integrate with Teams for notifications
- Test end-to-end integration
📅 Document Information
Last Updated: January 2026
Version: 1.0
Maintained by: OptiMind Development Team
Version: 1.0
Maintained by: OptiMind Development Team