Open-source AI-powered Power BI data model analyzer and DAX/M code optimizer.
Built and open-sourced by Enterprise DNA — a leading data and AI education company.
What is it? • Built with AI • Features • Tech Stack • Quick Start • Self-Hosting • Architecture • Dev with AI • Contributing • License
AI Power BI Analyzer is a web application that ingests the metadata of a Power BI report (.pbix model) and produces AI-generated insights: DAX measure optimizations, Power Query (M) code reviews, data-model audits, performance bottleneck analysis, and a chat interface that lets you ask questions about your model in plain English.
Think of it as a Power BI co-pilot you self-host — bring your own Gemini key, your own Supabase, your own data, and the AI never has to phone home to a vendor SaaS.
Most Power BI tooling stops at static analyzers and rule packs. This is different:
- AI-first analysis — Gemini reads your DAX measures, M code, and model structure, then explains issues and proposes fixes in your context, not generic best-practice prose
- Chat with your model — Ask "why is this measure slow?" or "is this relationship causing the wrong totals?" and get answers grounded in the actual model you uploaded
- DAX + M + relationships in one place — not three different tools to stitch together
- Self-hostable — Bring your own Supabase project, your own Gemini API key, and optionally your own Stripe credentials. Nothing leaves your infrastructure unless you want it to
- Pluggable AI providers — Gemini is the default; OpenAI is wired in as an automatic fallback. Add OpenRouter or any other provider with a few lines in
_shared/chat.ts - Open source — MIT licensed. Fork it, extend it, ship it
This entire application was built using AI-assisted development tools. Enterprise DNA believes in the future of AI-augmented software development, and this project is a reference for what's possible. Every Supabase migration, every edge function, every React component was developed collaboratively with AI coding agents.
| Tool | Role |
|---|---|
| Claude Code by Anthropic | Primary development tool. Specialist agents (defined in AGENTS.md) each owned a specific domain. |
| Cursor | AI-powered IDE used throughout development for code navigation, inline edits, and rapid iteration. |
| GitHub Copilot | AI pair programming assistant for code completion and pattern matching. |
Enterprise DNA is committed to demonstrating that AI tools are not just productivity boosters — they are a new way to build software. This project serves as a reference implementation for AI-assisted full-stack development.
- Upload extracted
.pbixmetadata as a project, scoped per user - Per-project Row Level Security — users only ever see their own models
- Metadata stored as JSONB so you can re-run any analysis without re-uploading
- Companion
.pbixextractor utility (link configurable viaVITE_PBIX_EXTRACTOR_URL)
- DAX measure optimization — Find slow measures and get suggested rewrites
- M (Power Query) code review — Best-practice review of your data prep
- Data model audit — Tables, relationships, cardinality, ambiguity warnings
- Performance analysis — Likely bottlenecks called out with reasoning
- Best-practices audit — Sweep against widely accepted Power BI guidance
- Pluggable providers — Gemini default, OpenAI fallback, OpenRouter wired in
_shared/chat.ts
- Conversational interface backed by the
data-model-chatedge function - The AI sees the model structure (tables + relationships), DAX measures, and M code as part of its context
- Ask follow-up questions about a specific measure or about the model as a whole
- Inline advisor that watches what you're looking at on the dashboard and surfaces relevant suggestions
- Independent of the chat — runs as a separate Supabase Edge Function (
ai-advisor)
- Multi-project workspaces, each with its own metadata blob and run history
- Rename or delete projects from the projects page
- Resume in-progress analysis runs (status + progress are persisted)
- Email + password via Supabase Auth
- Password reset flow with email confirmation
- Protected routes via
ProtectedRoutecomponent (redirects to/auth)
- Stripe checkout, billing portal, and subscription mirror are included as edge functions
- Disabled by default in
App.tsx— uncomment and configure if you want a paid tier
- Responsive dashboard (mobile-friendly)
- Dark-mode-ready via
next-themes - Rich form controls powered by shadcn/ui + Radix
- Inline DAX / M code viewing via Monaco Editor
| Layer | Technology |
|---|---|
| Build / Framework | Vite 5 + React 18 |
| Language | TypeScript 5 |
| UI Library | shadcn/ui + Radix UI |
| Styling | Tailwind CSS 3 |
| Icons | Lucide React |
| Routing | React Router 6 |
| Forms | React Hook Form + Zod |
| Data fetching | TanStack Query |
| Code Editor | Monaco Editor |
| Database / Auth | Supabase (PostgreSQL + Row Level Security + Auth) |
| AI Runtime | Supabase Edge Functions (Deno) calling Google Gemini, with OpenAI / OpenRouter fallback |
| Billing (optional) | Stripe via @stripe/react-stripe-js |
| Deployment | Netlify, Vercel, or any static host + Supabase |
- Node.js 20+ and npm (Bun also works if you prefer)
- A Supabase account (free tier works)
- A Google Gemini API key — required for analysis. OpenAI is wired in as a fallback
git clone https://github.com/Enterprise-DNA-OS/ai-power-bi-analyzer.git
cd ai-power-bi-analyzer
npm install- Sign in at supabase.com and click New Project
- Wait for the project to provision (~2 minutes)
- From Settings -> API, copy:
- Project URL ->
VITE_SUPABASE_URL - anon / public key ->
VITE_SUPABASE_ANON_KEY
- Project URL ->
cp .env.example .env.localEdit .env.local with your credentials. At minimum:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-keySee .env.example for the full list, including the optional Stripe and VITE_PBIX_EXTRACTOR_URL settings.
Install the Supabase CLI and link your project:
npm install -g supabase
npx supabase login
npx supabase link --project-ref your-project-idPush the migrations:
npx supabase db pushThis creates bim_metadata, analysis_types, analysis_results, and (optional) subscriptions with Row Level Security policies enabled. The migration also seeds a starter set of analysis types so the app works out-of-the-box.
The AI analysis runs in Supabase Edge Functions:
npx supabase functions deployThis deploys run-analysis, ai-advisor, data-model-chat, and (optional) stripe-checkout-session, stripe-billing-portal, stripe-subscriptions.
Edge functions receive secrets via supabase secrets set, not .env.local:
# Required for AI analysis
npx supabase secrets set GEMINI_API_KEY=your_gemini_key
# Optional fallback / alternative providers
npx supabase secrets set OPENAI_API_KEY=your_openai_key
npx supabase secrets set OPENROUTER_API_KEY=your_openrouter_key
# Optional: Stripe for billing
npx supabase secrets set STRIPE_SECRET_KEY=sk_live_...
npx supabase secrets set STRIPE_WEBHOOK_SECRET=whsec_...npm run devOpen http://localhost:8080, sign up for an account, upload a .pbix metadata extract, pick an analysis type, and watch the AI go to work.
- Push the repo to your own GitHub account (or fork it directly)
- Connect the repo to Netlify
- Add
VITE_SUPABASE_URLandVITE_SUPABASE_ANON_KEY(and any otherVITE_*vars) in Site settings -> Environment variables - Build command:
npm run build— Publish directory:dist - Deploy
A netlify.toml is included with a sensible default redirects file.
- Push the repo to your own GitHub account
- Import in Vercel
- Add the
VITE_*environment variables - Vercel auto-detects Vite. Build command
npm run build, outputdist - Deploy
The app is a pure SPA — npm run build produces a dist/ directory you can serve from any static host (Cloudflare Pages, S3 + CloudFront, GitHub Pages, etc.). Make sure the host serves index.html for unknown routes (SPA fallback).
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx-spa.conf /etc/nginx/conf.d/default.conf
EXPOSE 80Where nginx-spa.conf contains an SPA fallback (try_files $uri $uri/ /index.html;).
- Update environment variables — Set every
.env.examplevariable in your hosting platform - Set edge function secrets —
GEMINI_API_KEYis required; rotate it if it ever appears in logs - Supabase Auth redirect URLs — Add your production domain under Supabase Auth settings
- Rate-limit edge functions — AI calls cost money. Add a limiter (Supabase rate limits, Cloudflare, or your reverse proxy)
- Enable HTTPS — Required for Supabase Auth
- Monitor edge function logs — Check the Supabase dashboard for analysis failures and AI provider errors
src/
App.tsx Top-level routes + providers
main.tsx Vite entry
pages/
Auth.tsx Sign in + password reset
Register.tsx Sign up
UpdatePassword.tsx Reset-link landing page
Index.tsx Public landing page
Projects.tsx Authenticated project list
CreateProject.tsx Upload + create flow
Dashboard.tsx Per-project analysis surface
Profile.tsx Account info
PricingPage.tsx Optional Stripe pricing card
PaymentSuccess.tsx Stripe success callback
NotFound.tsx 404
components/
ui/ shadcn/ui primitives
homepage/ Landing page sections (Hero, TrustIndicators, HowItWorks, etc.)
dashboard/ Dashboard surface
ai-advisor/ AI advisor sidebar
ai-assistant/ Inline AI helpers (text selector, etc.)
analysis/ Analysis viewers and selectors
data-model-chat/ Chat-with-the-model UI
project-form/ Upload + create-project flow
projects/ Project list + cards
Navigation.tsx Top nav
Footer.tsx Bottom nav
ProtectedRoute.tsx Auth gate
CodeEditor.tsx Monaco wrapper
contexts/ UserContext, AIAdvisorContext, DataModelChatContext, SubscriptionContext
hooks/ useAnalysis, useAnalysisResults, useAuthCheck, useSupabaseFunction, ...
integrations/supabase/
client.ts The singleton Supabase client (env-driven)
types.ts Generated Database types
types/ Shared TypeScript types
utils/ bimProcessor, formulaFormatter, project, storageUtils, supabaseFunctions
supabase/
config.toml Edge function configuration
migrations/
20260430000000_initial_schema.sql
functions/
_shared/
chat.ts Gemini wrapper (with OpenAI fallback)
m-code.ts M (Power Query) extraction
dax-code.ts DAX measure extraction
data-model.ts Tables / relationships extraction
run-analysis/ Main analysis runner
ai-advisor/ AI advisor chat backend
data-model-chat/ Chat-with-the-model backend
stripe-checkout-session/ Optional billing
stripe-billing-portal/ Optional billing
stripe-subscriptions/ Optional billing (Stripe webhook handler)
User picks an analysis type
-> supabase.functions.invoke("run-analysis", { analysis_type_id, metadata_id, ... })
-> Edge function (Deno) reads analysis_type + bim_metadata
-> _shared/m-code.ts / dax-code.ts / data-model.ts extract relevant slices
-> _shared/chat.ts -> Gemini (or OpenAI fallback)
<- Markdown analysis
-> analysis_results row updated with content + status='completed'
<- Realtime / polling pushes the result to the dashboard
User opens chat, types question
-> supabase.functions.invoke("data-model-chat", { messages, metadata_id })
-> Edge function loads model structure + recent analysis results
-> Builds a system prompt with that context
-> _shared/chat.ts -> Gemini
<- Streamed (or single) response rendered in DataModelChatSidebar
All AI keys live in Supabase Edge Function secrets. They never touch the browser.
The bundled migration creates:
bim_metadata— Uploaded Power BI projects, one per user-uploaded.pbix. JSONBmetadatacolumn holds the extracted model.analysis_types— Catalogue of analysis flavors (DAX, M code, performance, etc.). Read-only for users.analysis_results— Output of each analysis run. Links tobim_metadataandanalysis_types. Status + progress are persisted so runs can be resumed.subscriptions— Optional Stripe mirror. Only used if you enable billing.
Row Level Security is enforced on every user-facing table:
- Users see their own
bim_metadata - Users see
analysis_resultsonly for projects they own analysis_typesis shared, read-only cataloguesubscriptionsis owner-only
| Function | Purpose |
|---|---|
run-analysis |
Main analysis runner. Reads metadata, extracts the relevant slice (M / DAX / model), calls Gemini via _shared/chat.ts, writes back to analysis_results. |
ai-advisor |
Inline advisor sidebar backend. Watches user context and offers suggestions. |
data-model-chat |
Conversational backend. Loads model + recent analysis as context, calls Gemini. |
stripe-checkout-session |
(Optional) Creates a Stripe Checkout session for subscription signup. |
stripe-billing-portal |
(Optional) Generates a Stripe Billing Portal URL for the current customer. |
stripe-subscriptions |
(Optional) Stripe webhook handler that mirrors subscription state into the subscriptions table. |
This project is designed to work well with AI development tools. Two files make this explicit:
CLAUDE.md— Project-wide instructions, conventions, and architecture overview. Claude Code reads this automatically.AGENTS.md— Defines specialist agents with clear ownership boundaries.
Open the project folder in Claude Code. The agent will pick up CLAUDE.md and AGENTS.md automatically and follow the conventions.
Open the project in Cursor. The CLAUDE.md file serves as context for Cursor's AI features. Use inline edit (Cmd+K) for quick changes and the chat panel for larger refactors.
Copilot picks up patterns from the existing codebase (Supabase client usage, auth checks, Tailwind conventions). The consistent conventions in CLAUDE.md make Copilot suggestions more accurate.
We encourage contributors to use AI tools. If you submit a PR:
- Mention which AI tools you used — we see it as a positive
- Follow the conventions in
CLAUDE.md - Use the specialist agent boundaries in
AGENTS.md - Run
npm run typecheck && npm run lint && npm run buildbefore submitting
See CONTRIBUTING.md for detailed guidelines.
TL;DR:
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes (AI tools welcome)
- Run
npm run typecheck && npm run lint && npm run buildto verify - Commit with a descriptive message
- Push to your fork and open a PR
MIT — use it however you want.
- Built with Claude Code by Anthropic
- Developed in Cursor — the AI-powered IDE
- AI pair programming by GitHub Copilot
- AI generation powered by Google Gemini and OpenAI
- Database, auth, and edge functions by Supabase
- UI components from shadcn/ui and Radix UI
- Inline code viewing by Monaco Editor
- Formerly released internally as Power-Vibes by Enterprise DNA
Built with pride by Enterprise DNA
Powered by AI-assisted development with Claude Code, Cursor, and GitHub Copilot