Skip to main content

11 posts tagged with "ai"

View All Tags

From a Local Claude Code QBR to a Copilot-Ready Azure Function

· 7 min read
Mike Homol
Principal Consultant @ ThreeWill

A manufacturing client already had a working Customer QBR generator. It lived in Claude Code: a Python script, a handful of Excel extracts, and a self-contained HTML dashboard that sales could actually present. The ask was not “make Copilot write a nicer report.” It was “let sales ask Copilot for the same dashboard, for any customer, without running a laptop script.”

That sounds like a prompt problem. It was an architecture problem.

The local solution was already good

Someone on the client side had used Claude Code to build a deterministic pipeline, not a chatty summarizer. The script read four monthly Excel workbooks (orders, returns, forecast, item/customer master), computed a pile of KPIs, and injected the results into an HTML template. The output was an interactive canvas: YTD sales, units, on-time delivery, fill rate, forecast variance, RMAs, pipeline, recommended actions.

That is the kind of artifact consulting teams usually wish they had. Charts with real numbers. Tooltips. A predictable layout so the next quarter looks like the last quarter, just with new data.

The Excel files were not a convenience dump. They were the contract. Sheet names looked like ERP/BI view exports. The Python encoded client-specific windows and matching keys on top of that shape. If you skip the contract and ask an LLM to “read the spreadsheet and build a dashboard,” you get a different report every time — and you cannot hand it to a customer.

Phase 1 had to mimic that pipeline, not replace it. Going straight to the source system was the right end state — just not the first proof.

What Copilot cannot fake

The Copilot Studio agent had been pointed at Excel as knowledge and asked to author HTML. Two things break that design:

  1. Generative HTML is not the generator. The Python already owned the KPI math. An LLM rewriting dashboards from spreadsheets will drift, miss rows, and invent layout. Sales QBR is a repeatable artifact, not a one-off essay.
  2. Copilot Studio does not natively hand back a file. Chat can show a summary. It cannot reliably deliver a downloadable, self-contained HTML canvas unless something else produces the bytes and returns a link — Power Automate, an Agent Flow, or an external API.

The gap was wiring. Copilot should collect a customer name and return a URL. The engine should stay Python.

Wrap the engine, keep the contract

I stood up a Python 3.11 Azure Function App as an HTTP wrapper around the original generator. First data mode was Excel: the same four workbooks, staged in Blob (or a local folder for the laptop proof). The Function resolved a customer name, ran the engine, uploaded the HTML, and returned a time-limited SAS download URL.

A ThreeWill-tenant POC was enough to prove the stack before recreating it in the client’s subscription. Function-level auth (code / x-functions-key) kept the first connector simple.

MethodRouteRole
GET/api/healthLiveness + which data mode is live
GET/api/qbr/customersCustomer name search
POST/api/qbrStart generation → jobId
GET/api/qbr/statusPoll until downloadUrl

Copilot Studio imported that surface as a REST API from OpenAPI. Four operations, API key in the query string, no custom connector science project.

Copilot’s 30-second wall

Generation is not a cheap lookup. After warm-up it is often 15–60 seconds; a cold run with a fat extract can take a couple of minutes. Copilot tool calls time out around 30 seconds.

So the default POST /api/qbr does not wait for HTML. It queues a Storage Queue message, returns 202 + jobId immediately, and a queue-triggered worker does the minutes-long work. A sync=true path exists for curl and smoke tests — Copilot never uses it.

Agent instructions matter as much as the API. Copilot is an orchestrator: search if the name is fuzzy, start a job, remember jobId, and on “ready?” call status with that id only. It must not author HTML, invent KPIs, or re-ask for the customer name just to poll. Hiding customerName on the status tool is what stops that re-prompt.

SAS lifetime defaults to 24 hours. The link is a download, not a forever intranet page.

Then stop copying Excel

Once Copilot could deliver the same canvas, the monthly Excel ritual became the next bottleneck. Those workbooks were already pictures of lakehouse views. Phase 2 flipped QBR_DATA_MODE from excel to fabric.

Same Function. Same OpenAPI. Same Copilot tools. Different loaders:

  1. Resolve the customer in the lakehouse (company name → customer key)
  2. Query orders, RMAs, and forecast by that key
  3. Take the latest forecast version
  4. Pull deals from the CRM table and inventory for the customer’s items
  5. Still load the HTML template from Blob — branding is injected at generate time

An Entra app registration in the client’s tenant, granted on the Fabric workspace/lakehouse, lets the Function use Lakehouse SQL. The Function host needs ODBC Driver 18; that is a runtime footnote, not a Copilot change.

Excel mode stayed as rollback. That mattered during the first Fabric mapping: column case, identifier quoting, and “which table actually has city/state” are the unglamorous half of reuse.

What sales actually get

The deliverable is still the interactive HTML — not a chat summary pretending to be a QBR.

Customer QBR dashboard — names, logo, and item codes redacted

Typical sections:

  • Customer summary (YTD sales and units vs prior year)
  • Monthly sales and order-to-ship
  • On-time delivery and fill rate
  • Top items, forecast vs actual, recommended forecast actions
  • Returns / RMA
  • Open pipeline

The layout is stable because the template is stable. Copilot’s job is to get the right customer into the engine and hand back the file. The screenshot above is a real generated dashboard with account names, logos, and item codes swapped for placeholders.

What I would repeat

  • Treat a local Claude Code win as a product to host, not a prompt to recreate. If the Python already computes the truth, wrap it.
  • Make the extract schema explicit before you skip it. Excel was the contract that let us prove Copilot delivery without boiling the ERP ocean.
  • Design for Copilot timeouts on day one. Async job + poll + SAS link is boring and it works.
  • Keep the LLM off the KPI path. Instructions that say “you do not author HTML” are load-bearing.
  • Flip data mode behind the same OpenAPI. Copilot makers should not notice Fabric vs Excel except that the numbers stop depending on last month’s export.

The pattern is reusable anywhere a desktop agent built a real report and the enterprise agent is expected to serve it: host the engine, let Copilot orchestrate, put durable data behind the same API when the first file lands.

Operational Dashboard for the Human Services Scorecard

· 2 min read
Mike Homol
Principal Consultant @ ThreeWill

Scorecard tiles are great for a check-in moment. Operators still need a full-page place to see what needs attention across communities, compare locations, and read trends without hopping web parts. This week I shipped that shell for the Human Services Scorecard — and tightened the metric math that feeds it.

What happened

  • Added a new Operational Dashboard SPFx web part with a full-page shell: Attention panel, Summary panel, community comparison, KPI strip, trend chart destinations, and shell nav/context
  • Added weighted rollups and per-location goal overrides for Sum metrics so “All communities” views stop lying about local targets
  • Surfaced location Needs Attention on category pages when viewing All communities
  • Colored week-over-week trend arrows by target favorability (lower-is-better down = good) instead of raw up/down
  • This is the next chapter for both the Human Services Scorecard and ThreeWill as a business: HSS is the spine for displaying metrics that matter to human services organizations — especially Senior Living — while we work toward automated integration with the back-end systems that bring those dashboards to life (Financial, CRM, HR, and EHR apps/services)

Human Services Scorecard Operational Dashboard — Executive Overview on the demo site

Weekly AI Builds - August 10, 2026

· One min read
Mike Homol
Principal Consultant @ ThreeWill

Shelf week for the Human Services Scorecard: I shipped a full Operational Dashboard shell — Attention, Summary, and favorability-aware trends — as the next chapter in how ThreeWill surfaces metrics that matter for human services and Senior Living.

Highlights

  • Built a new Human Services Scorecard Operational Dashboard SPFx shell — Attention + Summary panels, community comparison, KPI strip, trend destinations, weighted Sum rollups, per-location goal overrides, and WoW arrows colored by target favorability.
  • Positioned HSS as the display spine for metrics that matter, with a path toward automated Financial / CRM / HR / EHR integrations that bring those dashboards to life for Senior Living and other human services orgs.
  • Continued side work without separate Learn More posts: Memento Mori iOS 26 PNG freeze fix, Backseat Games Android solo-launch packaging, state licensing monorepo/ADO hardening, and a small knowledge-base hygiene script.

Learn More

From Discovery Notes to an ADO Import Pack

· 4 min read
Mike Homol
Principal Consultant @ ThreeWill

Discovery backlogs often die as sprawling spreadsheets. This week I turned a kickoff architecture, an estimating sheet, and a gap analysis into an Azure DevOps import pack — so a multi-app modernization engagement can load phased work items instead of debating a static file.

What happened

Planned architecture (discussion-grade)

Married the system design with the Azure architecture into a living trajectory the team can share:

  • API-first, location-driven platform — one Azure SQL system of record, document binaries in Azure Blob (SQL keeps metadata / blob_uri), shared .NET API behind API Management
  • Three clients, one API — internal React SPA, offline-capable field app (.NET MAUI + SQLite sync), and an external React portal (Entra External ID + accessibility expectations)
  • Scriptable Azure baseline — PowerShell orchestrating Azure CLI against a JSON resource manifest (Key Vault, App Insights, SQL, App Service, Functions, Static Web Apps stubs, Communication Services) in a single primary resource group
  • Auth split — Entra ID for internal users; Entra External ID for portal users
  • Integrations later in the sequence — payments, HR feed, insurer file drop, addressing, notifications — after core domain and apps stand up
  • Migration + hardening as late phases — cutover from the legacy permitting platform, then security/docs/go-live

Nothing here claims a finished production tenant; it is the kickoff architecture the backlog is sequenced against.

Delivery phases

Sequencing is P0–P10 (~16-month build). Phases are delivery order labels — not ADO Epics:

CodePhaseIntent
P0Discovery & UX/data designRequirements depth, mocks, SQL + Blob layout
P1Azure platform & IaCScriptable baseline resources
P2Data model & API coreLocation-first anchors, OpenAPI, auth
P3Main app shellInternal React Static Web App framework
P4Domain capabilitiesLicensing, plan review, inspections, complaints, fiscal
P5Field / inspectors appOffline MAUI + sync
P6External portalPublic React + External ID
P7IntegrationsPayments, HR, file drops, notifications, addressing
P8MigrationLegacy platform → new system
P9Reporting & BIAnalytics (decision pending)
P10Hardening & cutoverSecurity, runbooks, go-live

From estimate sheet to picklist

Started from the original estimating backlog (archived workbook — not reproduced in detail here). Ran a gap analysis against the architecture so platform, IaC, auth, observability, and other design-driven work that never appeared as estimating line items still landed as stories.

Final picklist: 238 user stories214 from the estimating backlog and 24 gap stories.

How Azure DevOps sees it

Hierarchy is Epic → Feature → User Story under one existing endeavor Epic (client project names stay private):

  • Features = durable solution layers (Infrastructure, API, Internal SPA, External SPA, MAUI, Integrations, Migration, Reporting, Program & delivery, …) — not one Feature per phase
  • Tags = delivery sequence (Phase-P0Phase-P10), layer markers, which app slice owns the story, and Source-Backlog vs Source-Gap
  • A generator script regenerates the CSV pack when discovery notes change; the import is a single hierarchical CSV for Boards → Import Work Items

Obfuscated picklist sample

A thin slice of Infrastructure / early-platform stories (titles lightly generalized; tags show the real shape):

Feature | User Story | Tags (abbrev.)
Infrastructure | Set up technical work environments (Azure, DevOps, …) | Phase-P1; Layer-Infrastructure; Source-Backlog
Infrastructure | Scaffold PowerShell + Azure CLI + JSON resource manifest| Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Provision Key Vault and wire secret references | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Provision Application Insights / Monitor baseline | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Configure Entra ID for internal app + API | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Configure Entra External ID for portal users | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Provision Azure SQL (dev) via IaC scripts | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Provision APIM + App Service for .NET API | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Provision Static Web Apps stubs (main + portal) | Phase-P1; Layer-Infrastructure; Source-Gap
Infrastructure | Add GitHub Actions CI skeleton for API and web apps | Phase-P1; Layer-Infrastructure; Source-Gap

Gap items (like the IaC scaffold row) are the architecture calling things the estimate sheet never named — exactly why the gap pass matters before import.

Weekly AI Builds - August 3, 2026

· One min read
Mike Homol
Principal Consultant @ ThreeWill

Follow-through week on a state licensing modernization kickoff: I married the architecture and estimating sheet into phased delivery docs, ran a gap analysis, and packaged 238 user stories as an Azure DevOps import pack.

Highlights

  • Built an ADO backlog import pack from architecture + estimating: living solution phases (P0–P10), a gap-aware picklist (214 backlog + 24 gap stories), hierarchical CSV under one endeavor Epic, and a generator script — Features as solution layers, tags for phase/app/source.
  • Kept client project names, endeavor titles, and org paths out of the public write-up while preserving the real shape of the import (Epic → Feature → User Story).
  • Continued adjacent engagement and product work (architecture trajectory docs; Scorecard SPFx polish) without separate Learn More deep-dives this week.

Learn More

Bootstrapping an Enterprise Repo with Engineering Standards

· 2 min read
Mike Homol
Principal Consultant @ ThreeWill

Starting a new enterprise engagement is more than scaffolding code — agents and humans need shared delivery rules from commit one. This week I wired a new delivery repo with ThreeWill Engineering Standards as a git submodule and product-specific agent context before the first feature branch landed.

What happened

  • Added threewill-engineering-standards as a git submodule at .cursor/rules/ so team non-negotiables, MCP docs, and SPFx patterns travel with the repo
  • The standards package is the result of a long partnership and rounds of planning with Cursor — so every developer, whether working locally or in the cloud, can trust that agents follow the same rules
  • The approach predates Cursor Cloud agents, but it remains a strong way to distribute consistent agentic behavior; it is still a work in progress, and the team is happy with how far it has come
  • Wrote product-specific AGENTS.md with submodule hygiene: detect missing standards, init/sync commands, and a light cadence for bumping the pinned SHA via PR
  • Documented delivery conventions in docs/delivery.md: branch + PR discipline, Azure DevOps Boards ↔ GitHub PR linkage (AB#<id>), GitHub Actions CI/CD posture, and Azure DevOps MCP setup for Cursor — without publishing client org or cutover details
  • Added Cursor Cloud-specific instructions so cloud agents follow the same submodule and delivery rules as local sessions
  • Adoption across the practice keeps improving — especially on SPFx web parts, where the standards enforce fewer rules but bring a consistent look-and-feel and reusable React components
  • Recent advancements clarify sophistication levels: Enterprise solutions carry a fuller requirements set than smaller/atomic solutions, so agents and humans get the right bar for the work
  • The same submodule pattern shows up across multiple active delivery repos (enterprise engagements and internal SPFx products), not only this kickoff

Weekly AI Builds - July 27, 2026

· One min read
Mike Homol
Principal Consultant @ ThreeWill

Kickoff week for a state licensing, permits, and inspections modernization: I bootstrapped the delivery repo with ThreeWill Engineering Standards so local and cloud agents share the same rules from day one — then used Cursor on discovery artifacts for a discussion-grade data model.

Highlights

  • Bootstrapped a new enterprise delivery repo with the threewill-engineering-standards submodule, product-specific AGENTS.md (submodule hygiene, branch + PR, Azure DevOps work-item linkage, ADO MCP), and Cursor Cloud agent instructions — standards that predate Cloud agents but still distribute consistent agentic behavior.
  • Noted practice-wide adoption improving, especially on SPFx work (lighter rule surface, shared look-and-feel and React components), plus clearer Enterprise vs smaller/atomic sophistication levels with different requirements.
  • Ran an AI-assisted discovery pass over stakeholder transcripts and legacy UI reference screenshots toward a kickoff data model (draft), including a location-first refinement with the team.

Learn More

Weekly AI Builds - July 20, 2026

· 2 min read
Mike Homol
Principal Consultant @ ThreeWill

App Store prep week: Memento Mori got a Skia life calendar, brand-coin widgets, and Homol Works hub pages; Backseat Games shifted monetization for Solo Mode and finished Travel Bingo sprite art.

Highlights

  • Rebuilt Memento Mori's life calendar on Skia, unified the brand coin across widgets and in-app loading (including coin markers on weekly goals), deep-linked home widgets to tabs, and locked the build to iPhone-only for App Store submission — with screenshot prep, an App Preview video, and a new Homol Works app hub.
  • Shipped Backseat Games v1.2 to TestFlight: Solo Mode is free, IAP sits behind Play online, Travel Bingo tiles moved from stock emojis to custom sprites, and marketing/privacy/support pages landed on Homol Works.
  • Refreshed the ThreeWilly managed-services weekly canvas and hardened work-item autonumber / Teams draft signals.

Learn More

Weekly AI Builds - July 13, 2026

· One min read
Mike Homol
Principal Consultant @ ThreeWill

Widgets got clearer, Backseat Games got a delight pass and Solo Mode, and Managed Services tooling kept moving — with public-safe notes on a client Dataverse hygiene win.

Highlights

  • Polished Memento Mori widgets (brand skulls, trimmed set) verified on device / TestFlight; App Store v1 docs will cover the full polished layout set.
  • Shipped Backseat Games v1.1 delight + Solo Mode — update is live on the App Store with the new Travel Bingo and License Plate visuals.
  • Hardened prospect phone matching and duplicate-merge reporting on a client Power Platform / Dataverse engagement (kept generic).
  • Scorecard trend overlays and related web parts continue a strong shelf story — more posts ahead, including a public release.

Learn More

Weekly AI Builds - July 8, 2026

· One min read
Mike Homol
Principal Consultant @ ThreeWill

A packed week across personal apps, Homol Works comeback work, and open-source releases — including the first public cuts of Ruddr MCP and Advanced Page Properties.

Highlights

  • Revived Memento Mori home-screen widgets on Expo SDK 55; Smart Record is active again and in final testing before app go-live.
  • Brought Homol Works back online with a terminal theme, gopher logo, Builds page, and weekly AI-build drafts.
  • Cleared an App Store blocker for Backseat Games, open-sourced Advanced Page Properties (SPFx 1.23) with a demo spotlight shot, and tagged Ruddr MCP v0.3.0 with an install-first public write-up plan.
  • Advanced Managed Services shelf work: Scorecard metrics UX, MS Pulse packaging, and a DDS Referrals demo-reset pipeline.

Learn More