Projects
🧠 AI Automation & Data Engineering Projects
A collection of builds spanning two disciplines: AI-powered automation — LLM-driven document processing, agentic workflows, and human-in-the-loop approval systems — and end-to-end data engineering, carrying raw data from source through BigQuery and dbt to live production dashboards in Power BI.
📊 Medicare Data Pipeline: Raw Data to Production Dashboard
Type: Data Engineering / Cloud Data Pipeline Stack: Google Cloud Storage, BigQuery, dbt, Power BI Code: View on GitHub
A real, working pipeline built on public CMS Medicare provider/payment data — de-identified, public-domain data, no PII — carried end to end from raw CSV to a live production dashboard. Built specifically to demonstrate cloud-native data warehousing and transformation (BigQuery + dbt), not just a script that reads a CSV.
Highlights
- Raw CMS provider/service data (millions of rows) landed in Cloud Storage, loaded to BigQuery, modeled with dbt
- Staging layer normalizes and types raw fields; production marts aggregate to provider- and procedure-level summaries
- dbt-defined tests (not_null, unique) enforce data quality on every run
- Power BI connects directly to the BigQuery production marts — no manual export/import step
🧩 Workflow Diagram
📊 Medicare Data Pipeline — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Ingest [📥 Ingest]
A1["(1) data.cms.gov<br/>raw CSV download"]
A2["(2) Cloud Storage<br/>raw landing zone"]
A1 --> A2
end
A2 --> B1["(3) BigQuery<br/>bq load raw table"]
subgraph Transform [🧱 dbt Transform]
B1 --> C1["(4) Staging model<br/>clean, rename, type-cast"]
C1 --> D1["(5) Mart: provider summary<br/>aggregated by NPI"]
C1 --> D2["(6) Mart: procedure summary<br/>aggregated by HCPCS + state"]
D1 --> E1["(7) dbt test<br/>not_null / unique checks"]
D2 --> E1
end
subgraph Serve [📈 Serve]
E1 --> F1["(8) Power BI<br/>connects to BigQuery marts"]
F1 --> F2["(9) Publish to web<br/>live embedded dashboard"]
end
Workflow Steps
- Source: Download the CMS “Medicare Physician & Other Practitioners - by Provider and Service” CSV from data.cms.gov
- Land: Upload the raw file to a Cloud Storage bucket — the raw, untouched landing zone
- Load:
bq loadthe CSV into a raw BigQuery table, no transformation yet - Stage: dbt staging model cleans column names, casts types, filters obvious nulls — no business logic
- Model (provider): dbt mart aggregates to one row per provider (NPI) — total services, beneficiaries, Medicare payments
- Model (procedure): dbt mart aggregates to one row per (procedure code, state) — cost and volume by geography
- Test: dbt’s built-in test framework enforces not_null/unique constraints on key columns before the marts are trusted downstream
- Connect: Power BI connects directly to the BigQuery production marts — no CSV export step in between
- Publish: Power BI’s “Publish to web” generates a live, filterable embed for the portfolio site
🎬 Try it live
This is the actual production Power BI dashboard, built on the pipeline above — filter and explore it directly.
📈 Superstore Sales & Profitability Dashboard
Type: Data Engineering / Cloud Data Pipeline Stack: BigQuery, dbt, Power BI Code: View on GitHub
A complete, working pipeline built on the Sample Superstore dataset — sales, profit, and discount data across product categories, regions, and customer segments — carried from a raw CSV straight through to a live production dashboard. Deliberately chosen after an earlier attempt (GA4 e-commerce data) turned out to have deliberately-stripped pricing fields — this dataset is complete by design, letting the analysis focus on the actual business question instead of working around missing data.
Highlights
- Direct CSV upload straight into BigQuery — no Cloud Storage step needed at this scale
- dbt staging layer normalizes raw column names (including literal spaces/hyphens from the source CSV) before any business logic runs
- Two production marts: category/region profitability, and segment/state performance
- Reveals a real, visible pattern in the data — heavier discounting correlates with lower profit margin, and it hits some categories far harder than others
- Grouping logic applied defensively from the start (using
ANY_VALUE()for descriptive fields rather than a fragile composite key) — a lesson carried over from an earlier project rather than learned the hard way twice
🧩 Workflow Diagram
📈 Superstore Pipeline — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Ingest [📥 Ingest]
A1["(1) Sample Superstore CSV<br/>direct download"]
A2["(2) BigQuery<br/>direct upload, no GCS needed"]
A1 --> A2
end
subgraph Transform [🧱 dbt Transform]
A2 --> B1["(3) Staging model<br/>clean, rename, type-cast"]
B1 --> C1["(4) Mart: category/region<br/>sales, profit, margin, discount"]
B1 --> C2["(5) Mart: segment/state<br/>profit by segment + geography"]
C1 --> D1["(6) dbt test<br/>not_null / unique checks"]
C2 --> D1
end
subgraph Serve [📈 Serve]
D1 --> E1["(7) Power BI<br/>connects to BigQuery marts"]
E1 --> E2["(8) Publish to web<br/>live embedded dashboard"]
end
Workflow Steps
- Source: Download the Sample Superstore CSV (complete, no missing-by-design fields)
- Load: Direct upload into BigQuery — small enough to skip Cloud Storage entirely
- Stage: dbt staging model cleans column names (including literal spaces/hyphens from the raw headers) and casts types
- Model (category/region): dbt mart aggregates sales, profit, quantity, discount, and margin by category, sub-category, and region
- Model (segment/state): dbt mart aggregates the same metrics by customer segment and state
- Test: dbt’s test framework enforces not_null/unique constraints before the marts are trusted downstream
- Connect: Power BI connects directly to the BigQuery production marts
- Publish: Power BI’s “Publish to web” generates a live, filterable embed for the portfolio site
🎬 Try it live
The actual production Power BI dashboard, built on the pipeline above — filter by segment and explore it directly.
🗳️ 2026 Congressional Campaign Finance Dashboard
Type: Data Engineering / Cloud Data Pipeline Stack: BigQuery, dbt, Power BI Code: View on GitHub
A pipeline built on genuinely live, current data — real 2025-2026 federal election cycle campaign finance filings, downloaded directly from the FEC’s official bulk data files and carried through to a live production dashboard. Unlike the other pipelines in this portfolio, this one tracks an active, ongoing dataset that updates as new filings are received, rather than a static historical snapshot.
Highlights
- Built against the FEC’s exact real column schema, verified directly against the source file before writing any SQL — no guess-and-fix iteration needed
- Reveals a genuinely contrasting story: House races raise more total dollars, but Senate candidates raise more per-candidate on average — visible side by side in two deliberately paired charts
- Surfaces the well-documented incumbency advantage clearly: incumbents outraise both open-seat and challenger candidates by a wide margin
- Party codes normalized at the source layer (e.g., Minnesota’s “DFL” folded into “DEM”) so downstream charts tell an accurate national story
🧩 Workflow Diagram
🗳️ FEC Campaign Finance Pipeline — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Ingest [📥 Ingest]
A1["(1) FEC.gov<br/>candidate_summary_2026.csv"]
A2["(2) BigQuery<br/>direct upload, no GCS needed"]
A1 --> A2
end
subgraph Transform [🧱 dbt Transform]
A2 --> B1["(3) Staging model<br/>clean, rename, normalize party codes"]
B1 --> C1["(4) Mart: fundraising by party/office<br/>totals + per-candidate averages"]
B1 --> C2["(5) Mart: candidate leaderboard<br/>one row per candidate"]
C1 --> D1["(6) dbt test<br/>not_null / unique checks"]
C2 --> D1
end
subgraph Serve [📈 Serve]
D1 --> E1["(7) Power BI<br/>connects to BigQuery marts"]
E1 --> E2["(8) Publish to web<br/>live embedded dashboard"]
end
Workflow Steps
- Source: Download the FEC’s official “candidate_summary_2026.csv” bulk data file for the 2025-2026 election cycle
- Load: Direct upload into BigQuery — small enough to skip Cloud Storage entirely
- Stage: dbt staging model cleans column names, casts types, and normalizes party affiliation codes (e.g., DFL → DEM) and office codes (H/S/P → House/Senate/President)
- Model (fundraising): dbt mart aggregates receipts, disbursements, and cash-on-hand by party and office, including both totals and per-candidate averages
- Model (leaderboard): dbt mart produces one row per candidate, grouped defensively by the reliable
candidate_idfield - Test: dbt’s test framework enforces not_null/unique constraints before the marts are trusted downstream
- Connect: Power BI connects directly to the BigQuery production marts
- Publish: Power BI’s “Publish to web” generates a live, filterable embed for the portfolio site
🎬 Try it live
The actual production Power BI dashboard, built on genuinely live 2026 election cycle data — explore it directly.
🏀 NBA Team Performance & Shooting Trends
Type: Data Engineering / Cloud Data Pipeline Stack: BigQuery, dbt, Power BI Code: View on GitHub
A pipeline built on real NBA team game data spanning 2010-2024 — fourteen regular seasons carried from a public, actively-maintained GitHub dataset through to a live production dashboard, tracking the sport’s most significant modern tactical shift: the rise of the three-point shot.
Highlights
- Built against a fully-documented public schema, verified directly against the source repo before writing any SQL
- League-wide shooting trends reveal the well-documented “3-point revolution” — average 3-point attempts per team climbing steadily across the full 2010-2024 span
- Team-level win percentage, scoring, and point differential tracked season over season, filterable by team
PLUS_MINUSused directly for point differential, avoiding an unnecessary self-join against opponent data
🧩 Workflow Diagram
🏀 NBA Team Stats Pipeline — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Ingest [📥 Ingest]
A1["(1) GitHub<br/>regular_season_totals_2010_2024.csv"]
A2["(2) BigQuery<br/>direct upload, no GCS needed"]
A1 --> A2
end
subgraph Transform [🧱 dbt Transform]
A2 --> B1["(3) Staging model<br/>clean, rename, type-cast"]
B1 --> C1["(4) Mart: team season summary<br/>win %, scoring, shooting efficiency"]
B1 --> C2["(5) Mart: league shooting trends<br/>3-point attempts by season"]
C1 --> D1["(6) dbt test<br/>not_null / unique checks"]
C2 --> D1
end
subgraph Serve [📈 Serve]
D1 --> E1["(7) Power BI<br/>connects to BigQuery marts"]
E1 --> E2["(8) Publish to web<br/>live embedded dashboard"]
end
Workflow Steps
- Source: Download “regular_season_totals_2010_2024.csv” from the publicly maintained NocturneBear/NBA-Data-2010-2024 GitHub repository
- Load: Direct upload into BigQuery — no Cloud Storage step needed at this file size
- Stage: dbt staging model cleans column names and casts types against the source’s own documented schema
- Model (team season): dbt mart aggregates wins, losses, win percentage, scoring, and shooting efficiency by team and season
- Model (league trends): dbt mart aggregates league-wide shooting and scoring averages by season, surfacing the 3-point attempt trend
- Test: dbt’s test framework enforces not_null/unique constraints before the marts are trusted downstream
- Connect: Power BI connects directly to the BigQuery production marts
- Publish: Power BI’s “Publish to web” generates a live, filterable embed for the portfolio site
🎬 Try it live
The actual production Power BI dashboard, built on the pipeline above — filter by team and explore fourteen seasons of shooting trends directly.
🎯 March Madness ML: 2025 NCAA Bracket Predictions
Type: Machine Learning / Predictive Modeling Stack: Python, pandas, scikit-learn, XGBoost Code: View on GitHub
A machine learning pipeline trained blind on NCAA tournament data through 2024 — from the official Kaggle “March Machine Learning Mania” competition dataset, frozen right before Selection Sunday 2025 — then scored against the real 2025 tournament results once they’d actually happened. Both Men’s and Women’s brackets.
Highlights
- Feature engineering across 7,981 (Men’s) and 5,602 (Women’s) team-seasons of real box score data
- Two models compared head-to-head (Logistic Regression, XGBoost) with proper time-based validation — trained on older seasons, tested on held-out recent ones, not randomly shuffled
- Real-world validation: predicted the entire 2025 bracket before it played out, then checked against actual results — 12/14 (85.7%) correct across the Elite Eight through Championship, including a perfect 7/7 on the Women’s side
🧩 Workflow Diagram
🎯 March Madness ML — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Features [📥 Feature Engineering]
A1["(1) Kaggle dataset<br/>box scores through 2024"]
A2["(2) Per-team-season stats<br/>win%, shooting, rebounds, etc."]
A1 --> A2
end
subgraph Training [🧠 Model Training]
A2 --> B1["(3) Matchup training data<br/>symmetric augmentation"]
B1 --> B2["(4) Train + validate<br/>LogReg vs XGBoost, time-split"]
end
subgraph Predict [🔮 2025 Predictions]
B2 --> C1["(5) Every possible matchup<br/>among 68 tournament teams"]
C1 --> C2["(6) Simulate real bracket<br/>round by round"]
end
subgraph Validate [✅ Real-World Scoring]
C2 --> D1["(7) Fetch actual 2025 results<br/>after the tournament happened"]
D1 --> D2["(8) Score predictions<br/>vs. real outcomes"]
end
Workflow Steps
- Source: Kaggle’s official “March Machine Learning Mania 2025” competition dataset — frozen before the 2025 tournament, so 2025 results genuinely weren’t in the training data
- Feature engineering: aggregate each team’s season stats (win %, scoring, shooting efficiency, rebounding, turnovers) from game-level box scores
- Training data: historical tournament games become matchup rows, symmetrically augmented (each game contributes one “Team A wins” and one “Team B wins” row) to avoid team-order bias
- Train & validate: Logistic Regression and XGBoost, evaluated on held-out recent tournament seasons — not a random split, which would leak future information
- Generate 2025 predictions: win probability for every possible pairing among the 68 tournament teams
- Simulate the bracket: walk the real slot structure (First Four through Championship) round by round, advancing the higher-probability team at each step
- Fetch real results: once the 2025 tournament had actually happened, pull the real outcomes from published sources
- Score: compare blind predictions against real results — 12/14 correct across the Elite Eight through Championship
🏀 Predictions vs. What Actually Happened
Trained blind on data through 2024, then scored against the real 2025 tournament outcomes.
Backtested Accuracy (Men's)
67.9%
vs. 68.3% seed-only baseline
Backtested Accuracy (Women's)
81.3%
vs. 77.2% seed-only baseline
2025 Real Results (Combined)
12 / 14
Elite Eight through Championship
🏀 Men's Bracket — 5/7 correct
| Round | Our Pick | Actual | ✓ |
|---|---|---|---|
| Elite 8 | Florida | Florida | ✓ |
| Elite 8 | Duke | Duke | ✓ |
| Elite 8 | Auburn | Auburn | ✓ |
| Elite 8 | Houston | Houston | ✓ |
| Final Four | Houston | Houston | ✓ |
| Final Four | Auburn | Florida | ✗ |
| Champion | Houston | Florida | ✗ |
Correctly called all four Elite Eight winners, matching the historic all-#1-seed Final Four. Picked the actual national runner-up as champion.
🏀 Women's Bracket — 7/7 correct
| Round | Our Pick | Actual | ✓ |
|---|---|---|---|
| Elite 8 | UConn | UConn | ✓ |
| Elite 8 | S. Carolina | S. Carolina | ✓ |
| Elite 8 | UCLA | UCLA | ✓ |
| Elite 8 | Texas | Texas | ✓ |
| Final Four | S. Carolina | S. Carolina | ✓ |
| Final Four | UConn | UConn | ✓ |
| Champion | UConn | UConn | ✓ |
Perfect: all four Elite Eight winners, both Final Four semifinal winners, and the eventual champion — all called correctly, blind, before the tournament played out.
Scoring covers the Elite Eight through Championship (the rounds that decide the tournament), sourced from published game results. Earlier rounds (First/Second Round, Sweet 16) weren't individually re-verified against game-by-game results for this summary.
🎯 Full Predicted Bracket — 2025
Every round, every predicted winner. Green/red borders mark picks verified against real results (Elite Eight through Championship); gray borders are earlier-round predictions not individually re-verified against game-by-game results.
⚙️ Contract Processing Bot
Type: Document Intelligence
Stack: Zapier, OpenAI, Google Drive, Gmail, Slack, Google Sheets
This bot automates contract intake and review—extracting key clauses, identifying risks, logging results, and routing approvals.
Highlights
- 80–90% reduction in contract triage time
- Real-time Slack alerts for risky clauses
- Seamless Google Drive + Sheets tracking
🧩 Workflow Diagram
⚙️ Contract Processing Bot — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Intake [📥 Intake]
A1["(1) Gmail Trigger<br/>new attachment 'contract'"]
A2["(2) Slack<br/>intake notification"]
A3{"(3) Filter<br/>contract file?"}
A1 --> A2 --> A3
end
A3 -- Yes --> A4["(4) Save to Drive<br/>/Contracts/Incoming"]
A3 -- No --> R1["Skip + log<br/>in Sheets"] --> H1([End])
subgraph AI_Validation [🧠 AI Extraction + Validation]
B1["(5) OpenAI<br/>extract JSON summary"]
B2{"Schema-valid<br/>JSON?"}
B1 --> B2
B2 -- No --> B1R["Retry<br/>stricter prompt"]
B2 -- Yes --> C1["(6) Code step<br/>parse JSON → fields"]
end
A4 --> B1
C1 --> D1["(7) Sheets<br/>append run log"]
subgraph Routing [📊 Routing & Actions]
D1 --> D2{"(8) Risks<br/>detected?"}
D2 -- Yes --> E1["Slack<br/>review thread"]
D2 -- No --> F1["Move to<br/>/Contracts/Approved"]
F1 --> F2["(9) Gmail<br/>confirmation email"]
end
E1 --> H1
F2 --> H1
Workflow Steps
- Trigger: Gmail — new attachment containing “contract”
- Notify: Send immediate Slack notification (intake)
- Filter: Only process contract files (skip & log others)
- Store: Upload to Google Drive →
/Contracts/Incoming - Extract: OpenAI step creates JSON summary (parties, dates, amounts, renewal, risks)
- Parse: Code by Zapier converts JSON to typed fields
- Log: Append all run details to Google Sheets
- Route: If risks found → Slack human review thread; else continue
- Confirm: Send email confirmations for auto-approved contracts
🎬 Try it live
Paste contract text (or use the example below) and this calls the actual deployed FastAPI backend — not a canned response.
⚠️ Not legal advice. This is a demo of an AI document-scanning tool, not a substitute for review by a licensed attorney. Do not rely on its output for real contract decisions.
📧 Support Email Agent
Type: Agentic Workflow
Stack: Zapier, OpenAI, Gmail, Zendesk, Slack, Google Sheets
This agent triages every inbound support email, drafts a reply grounded in your knowledge base, and routes anything customer-facing through a one-click Slack approval before it ever leaves the outbox.
Highlights
- 24/7 first-response coverage — no ticket sits untouched overnight
- Human-in-the-loop approval keeps a person accountable for every reply
- Confidence-based routing sends only low-risk replies (e.g., password resets) automatically
- Daily Slack digest tracks response time and escalation rate
🧩 Workflow Diagram
📧 Support Email Agent — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Intake [📥 Intake]
A1["(1) Gmail/Zendesk Trigger<br/>new support email"]
A2["(2) OpenAI<br/>classify intent + urgency"]
A1 --> A2
end
A2 --> B1{"(3) Escalation<br/>keywords? refund/cancel/legal"}
B1 -- Yes --> H1["Route to<br/>human queue"] --> H2([End])
B1 -- No --> C1["(4) KB Lookup<br/>Sheets/Airtable match"]
subgraph AI_Draft [🧠 Draft + Review]
C1 --> D1["(5) OpenAI<br/>draft grounded reply"]
D1 --> D2{"(6) Confidence<br/>+ risk check"}
D2 -- Low-risk/high-confidence --> E1["Auto-send"]
D2 -- Needs review --> F1["(7) Slack thread<br/>Approve / Edit / Reject"]
end
F1 -- Approved --> E1
F1 -- Edited/Rejected --> D1
E1 --> G1["(8) Send via<br/>Gmail/Zendesk API"]
G1 --> G2["(9) Log to Sheets<br/>+ daily digest"]
G2 --> H2
Workflow Steps
- Trigger: Gmail/Zendesk — new inbound support email
- Classify: OpenAI scores intent (billing, technical, general) and urgency
- Escalation check: Refund/cancel/legal/angry-sentiment keywords route straight to a human, bypassing AI drafting
- Retrieve: Pull the matching FAQ/knowledge-base article via lookup table
- Draft: OpenAI generates a reply grounded in the matched KB content, in brand voice
- Confidence check: Low-risk, high-confidence replies (e.g., password reset) go straight to send
- Human-in-the-loop: Everything else posts to a Slack thread with Approve / Edit / Reject actions
- Send: Approved replies go out via the Gmail/Zendesk API
- Log & report: Every reply logged to Sheets; daily Slack digest shows volume, response time, escalation rate
🗒️ Meeting Intelligence & Action-Item Agent
Type: Agentic Workflow + Document Intelligence
Stack: FastAPI, OpenAI (GPT-4o-mini), Whisper, MongoDB, Slack API, Notion/Asana API
Meetings generate decisions and action items that usually die in someone’s notes app. This service listens for a finished meeting, turns the recording or transcript into structured minutes, and pushes every action item — with an owner and a due date — straight into the team’s task tool.
Highlights
- Cuts meeting write-up time from ~20 minutes to under 2
- Action items land in Notion/Asana automatically, no manual re-typing
- Weekly rollup flags overdue items by owner, closing the accountability gap
- Searchable meeting history in MongoDB — “what did we decide about X?” answered in seconds
🧩 Workflow Diagram
🗒️ Meeting Intelligence Agent — Diagram
%%{init: {'flowchart': { 'htmlLabels': true, 'wrap': true, 'nodeSpacing': 60, 'rankSpacing': 80 }}}%%
flowchart LR
subgraph Intake [📥 Intake]
A1["(1) Webhook<br/>Zoom/Teams recording ready"]
A2["(2) Whisper<br/>transcribe audio"]
A1 --> A2
end
A2 --> B1["(3) FastAPI<br/>send transcript to LLM"]
subgraph AI_Extract [🧠 Extraction]
B1 --> C1["(4) OpenAI<br/>extract summary + decisions + action items"]
C1 --> C2{"(5) Schema-valid<br/>JSON?"}
C2 -- No --> C1R["Retry<br/>stricter prompt"] --> C1
C2 -- Yes --> D1["(6) Store in MongoDB<br/>meeting record"]
end
subgraph Action [📊 Action + Notify]
D1 --> E1["(7) Create tasks<br/>Notion/Asana API"]
D1 --> E2["(8) Post summary<br/>to Slack channel"]
end
E1 --> F1["(9) Weekly cron<br/>check overdue items"]
F1 --> F2["Slack digest<br/>to owners + organizer"]
E2 --> H1([End])
F2 --> H1
Workflow Steps
- Trigger: Zoom/Teams webhook fires when a recording is ready (or a transcript is uploaded manually)
- Transcribe: Whisper API converts audio to text if a transcript wasn’t already provided
- Send to LLM: FastAPI service forwards the transcript for structured extraction
- Extract: GPT-4o-mini pulls out a summary, key decisions, and action items (task, owner, due date)
- Validate: Schema check on the returned JSON; retry with a stricter prompt on malformed output
- Store: Structured meeting record saved to MongoDB for searchable history
- Create tasks: FastAPI calls the Notion/Asana API to create one task per action item, tagged to the right owner
- Notify: Clean summary + action item list posted to the team’s Slack channel
- Track & digest: Weekly cron checks the DB for items past due date and Slack-DMs each owner, with a rollup to the meeting organizer
🎬 Try it live
Paste a meeting snippet (or use the example below) and this calls the actual deployed FastAPI backend — not a canned response.