CASE STUDY · 01
TAF Webchat
Chat with your Power BI data
- Client
- TAF
- Role
- Full-stack Developer
- Context
- Nawatech
Overview
AI chat app that lets business users ask plain-language questions about Power BI data. An LLM writes and runs DAX against Microsoft Fabric, then answers with text, tables, and charts, without anyone needing DAX skills or a custom report.
What I built
- Frontend: streaming chat UI with Markdown tables, charts, a step trail of each Fabric call, follow-up suggestions, and Retry
- Backend: Next.js API routes for Entra ID sign-in (NextAuth), token refresh, and the Azure OpenAI tool loop with step and time limits
- MCP client connecting to the Microsoft Fabric IQ MCP server with each user's own token, loading tools at runtime plus custom chart and suggestion tools
- Fabric integration: worked around broken search tools with the Power BI REST API and tuned the instructions so the model writes correct DAX
- Playwright E2E tests (mocked and live) and a Docker production image
Engineering highlights
Delegated identity instead of a service account, keeping each user's data permissions
The server holds all secrets; the browser never talks to the LLM or Fabric directly
Fixed 502 errors by shrinking the session cookie from about 10 KB to under 3 KB
Moved follow-ups to a separate forced tool call after gpt-4o-mini skipped the optional one
Credential-free E2E tests using a forged test session and mocked streams
Key features
- Natural-language Q&A: the LLM reads the schema, writes DAX, runs it, and explains the result
- Runs with the user's own token, so Power BI row-level security still applies
- Inline bar and line charts with a 'View data' table
- Transparent reasoning trail for each tool call
- Three follow-up question suggestions per answer
- Streaming responses, Retry, and a Microsoft Graph profile photo
Stack
Frontend
Next.jsReactTypeScriptTailwind CSSshadcn/uiRechartsreact-markdownZodPlaywright
AI
Azure OpenAIVercel AI SDKModel Context Protocol (MCP)Microsoft FabricPower BI
Backend
Next.js API routesNextAuthMicrosoft Entra IDDocker