<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Tan Le — Field notes</title><description>Technical write-ups from production systems: AI agents, MCP, .NET, Azure and automation for legacy systems.</description><link>https://tanle.ca/</link><language>en</language><item><title>A Real-Time AI Meeting Assistant for the Enterprise, and the Road to an AI Phone Receptionist</title><link>https://tanle.ca/blog/ai-meeting-assistant/</link><guid isPermaLink="true">https://tanle.ca/blog/ai-meeting-assistant/</guid><description>Live transcripts with speakers, answers grounded in company context and on-screen data about two seconds after the question, and why the same engine leads to an AI phone receptionist.</description><pubDate>Sat, 03 Oct 2026 00:00:00 GMT</pubDate><category>AI Agents</category><category>Voice AI</category><category>LLM</category><category>.NET</category><category>Case Study</category></item><item><title>Two Features, Two Days: What Spec-Driven Development with Spec Kit Taught Me</title><link>https://tanle.ca/blog/spec-driven-development-spec-kit/</link><guid isPermaLink="true">https://tanle.ca/blog/spec-driven-development-spec-kit/</guid><description>Shipping two real features to production with Claude Code and GitHub&apos;s Spec Kit, and where production proved the spec wrong.</description><pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate><category>AI Agents</category><category>Claude Code</category><category>Lessons Learned</category></item><item><title>Setting Up Local Routines with AI Agents: What Worked and What Didn&apos;t</title><link>https://tanle.ca/blog/local-routines-with-ai-agents/</link><guid isPermaLink="true">https://tanle.ca/blog/local-routines-with-ai-agents/</guid><description>Moving back-office jobs from &quot;a person does this every morning&quot; to &quot;an agent does it, a person checks the summary&quot;, and what did and did not work.</description><pubDate>Wed, 23 Sep 2026 00:00:00 GMT</pubDate><category>AI Agents</category><category>Claude Code</category><category>Automation</category><category>Lessons Learned</category></item><item><title>Under the Hood of IProcessor: Parsing 60+ Vendor Invoice Formats with an Azure WebJob</title><link>https://tanle.ca/blog/iprocessor-under-the-hood/</link><guid isPermaLink="true">https://tanle.ca/blog/iprocessor-under-the-hood/</guid><description>The parsing engine, the stack and the delivery pipeline behind IProcessor: an Azure WebJob that reads 60+ vendor invoice layouts from a shared mailbox.</description><pubDate>Tue, 22 Sep 2026 00:00:00 GMT</pubDate><category>.NET</category><category>Azure</category><category>Integration</category><category>Case Study</category></item><item><title>IProcessor for GMD Stores: From Vendor Invoice to Store Shelf in One Web App</title><link>https://tanle.ca/blog/iprocessor-gmd-stores/</link><guid isPermaLink="true">https://tanle.ca/blog/iprocessor-gmd-stores/</guid><description>A tour of IProcessor: vendor invoice PDFs parsed automatically, reconciled against purchase orders, received in the warehouse with RFID pick-and-pack checks and Zebra labels, and reported on for margins.</description><pubDate>Sun, 20 Sep 2026 00:00:00 GMT</pubDate><category>.NET</category><category>Automation</category><category>Case Study</category></item><item><title>Hiding Complex Detail Sections on Phones Without Breaking Deep Links</title><link>https://tanle.ca/blog/hiding-detail-sections-on-phones/</link><guid isPermaLink="true">https://tanle.ca/blog/hiding-detail-sections-on-phones/</guid><description>Hiding two desktop-only tabs on phones in a legacy ASP.NET WebForms app turned into a small routing policy: saved links, window resizes and slow AJAX responses.</description><pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate><category>Legacy .NET</category><category>Frontend</category><category>Case Study</category></item><item><title>Syncing Staff Assignments to Google Calendar in a Legacy ASP.NET WebForms App</title><link>https://tanle.ca/blog/staffpoint-google-calendar-sync/</link><guid isPermaLink="true">https://tanle.ca/blog/staffpoint-google-calendar-sync/</guid><description>The backend for syncing staff assignments to Google Calendar in Staffpoint, a large ASP.NET WebForms staffing platform on .NET Framework 4.8: the product, its stack, and how the sync works.</description><pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate><category>Legacy .NET</category><category>Integration</category><category>Case Study</category></item><item><title>I gave my support team an AI that reads our database. It cost $0/month and zero lines of code.</title><link>https://tanle.ca/blog/zero-cost-sql-mcp-server/</link><guid isPermaLink="true">https://tanle.ca/blog/zero-cost-sql-mcp-server/</guid><description>A read-only SQL MCP server for Claude and ChatGPT with Microsoft&apos;s Data API builder: one JSON file, a two-line Dockerfile, an App Service plan we already paid for, and the eight things I wish I had known.</description><pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate><category>MCP</category><category>AI Agents</category><category>Azure</category><category>Lessons Learned</category></item><item><title>Moving a React app on Azure Static Web Apps to a Cloudflare custom domain</title><link>https://tanle.ca/blog/azure-static-web-apps-to-cloudflare/</link><guid isPermaLink="true">https://tanle.ca/blog/azure-static-web-apps-to-cloudflare/</guid><description>Moving a React app on Azure Static Web Apps to a Cloudflare-managed custom domain without exposing an unfinished site, and everything else the hostname touched: CORS, email and Stripe redirects.</description><pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate><category>Azure</category><category>Cloudflare</category><category>DevOps</category></item><item><title>Building a Real-Time Ticket Listings Monitor in Python: From Legacy .NET to a Lean Alerting Pipeline</title><link>https://tanle.ca/blog/ticket-listings-monitor-python/</link><guid isPermaLink="true">https://tanle.ca/blog/ticket-listings-monitor-python/</guid><description>Porting a ticket-listings monitor from legacy .NET to a lean Python service: a proof-of-work bot challenge in pure code, &quot;what is new&quot; decided in SQL Server, and Slack alerts within seconds.</description><pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate><category>Python</category><category>Automation</category><category>Integration</category></item><item><title>A self-shutting-down Linux VM for a weekly batch job on Azure (.NET 8 + CZDS zone files)</title><link>https://tanle.ca/blog/self-shutting-down-azure-vm/</link><guid isPermaLink="true">https://tanle.ca/blog/self-shutting-down-azure-vm/</guid><description>About 280 million domain names from ~1,000 TLD zone files, processed weekly on a Linux VM that a Logic App boots and that deallocates itself when the .NET 8 job is done, so idle cost stays close to zero.</description><pubDate>Sun, 06 Sep 2026 00:00:00 GMT</pubDate><category>Azure</category><category>.NET</category><category>Cloud Cost</category><category>DevOps</category></item><item><title>100k Blobs a Day and the Retention Rule Azure Doesn&apos;t Have</title><link>https://tanle.ca/blog/azure-blob-retention/</link><guid isPermaLink="true">https://tanle.ca/blog/azure-blob-retention/</guid><description>About 100,000 blobs a day, never deleted. How a &quot;should we just move this to SQL?&quot; question became a lesson about where cloud costs hide, and the retention job that fixed it.</description><pubDate>Fri, 04 Sep 2026 00:00:00 GMT</pubDate><category>Azure</category><category>Cloud Cost</category><category>Lessons Learned</category></item><item><title>Automating a Weekly Inventory Workflow with Power Automate Desktop</title><link>https://tanle.ca/blog/power-automate-desktop-inventory/</link><guid isPermaLink="true">https://tanle.ca/blog/power-automate-desktop-inventory/</guid><description>Automating a weekly StubHub research routine with Power Automate Desktop: repeatable browser filters, an Excel work list, a state file for the weekly cycle, and the choices that let it run unattended.</description><pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate><category>Power Automate</category><category>Automation</category><category>Case Study</category></item><item><title>Building a Market-Intelligence Platform for a Ticket Broker (Freelance Project)</title><link>https://tanle.ca/blog/market-intelligence-platform/</link><guid isPermaLink="true">https://tanle.ca/blog/market-intelligence-platform/</guid><description>A year of freelance work for a US ticket broker: Ticketmaster event ingest, seat-availability snapshots as time series, Slack alerts, and data pipelines running across two clouds.</description><pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate><category>.NET</category><category>Azure</category><category>AWS</category><category>Case Study</category></item><item><title>Syncing Lysted → SkyBox Through Slack: When an HTML Email Is the Only API</title><link>https://tanle.ca/blog/lysted-skybox-sync-via-slack/</link><guid isPermaLink="true">https://tanle.ca/blog/lysted-skybox-sync-via-slack/</guid><description>A sales platform with no webhooks and no usable order API: parsing &quot;tickets sold&quot; HTML emails out of Slack to record sales in SkyBox, plus automatic settlement reconciliation.</description><pubDate>Fri, 28 Aug 2026 00:00:00 GMT</pubDate><category>Integration</category><category>Automation</category><category>.NET</category></item><item><title>Defending Against LLM Output: Parsing Dirty JSON in C#</title><link>https://tanle.ca/blog/parsing-dirty-llm-json-csharp/</link><guid isPermaLink="true">https://tanle.ca/blog/parsing-dirty-llm-json-csharp/</guid><description>LLMs return almost-JSON: greetings, Markdown code fences, numbers as strings, the odd missing bracket. The defensive layers I use in C# to treat model output like user input, not like an API response.</description><pubDate>Tue, 25 Aug 2026 00:00:00 GMT</pubDate><category>LLM</category><category>.NET</category></item><item><title>Classifying Event-Ticket Emails with AI: From Prompt Engineering to Fine-Tuning GPT-4o-mini</title><link>https://tanle.ca/blog/classifying-ticket-emails-fine-tuning/</link><guid isPermaLink="true">https://tanle.ca/blog/classifying-ticket-emails-fine-tuning/</guid><description>The AI pipeline that reads and classifies hundreds of event-ticket emails a day: prompt engineering, emails with images, building a dataset and fine-tuning GPT-4o-mini.</description><pubDate>Sun, 23 Aug 2026 00:00:00 GMT</pubDate><category>LLM</category><category>AI Agents</category><category>.NET</category><category>Case Study</category></item><item><title>Building an Automation Hub for a Ticket-Resale Business in .NET</title><link>https://tanle.ca/blog/automation-hub-dotnet/</link><guid isPermaLink="true">https://tanle.ca/blog/automation-hub-dotnet/</guid><description>One .NET console app, dispatched by command-line argument and driven by Task Scheduler, that connects more than 10 systems for a ticket-resale business: POS, marketplaces, banking, Slack and an AI that reads email.</description><pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate><category>.NET</category><category>Automation</category><category>Integration</category><category>Case Study</category></item><item><title>Four Months Building a Domain Research Platform: What I Learned</title><link>https://tanle.ca/blog/domain-research-platform-lessons/</link><guid isPermaLink="true">https://tanle.ca/blog/domain-research-platform-lessons/</guid><description>Four months and a hundred-plus commits building a domain research SaaS: SQL performance at 13 million rows, stale third-party data, background jobs and multi-tenancy.</description><pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate><category>Lessons Learned</category><category>Case Study</category></item><item><title>Receiving real-time webhooks with an Azure Function</title><link>https://tanle.ca/blog/webhook-receiver-azure-function/</link><guid isPermaLink="true">https://tanle.ca/blog/webhook-receiver-azure-function/</guid><description>A C# HTTP-triggered Azure Function that receives SkyBox invoice webhooks in real time, with the subscription request and HMAC signature check.</description><pubDate>Fri, 18 Mar 2022 00:00:00 GMT</pubDate><category>Azure</category><category>.NET</category><category>Integration</category></item><item><title>Connecting to Azure SQL over a point-to-site VPN</title><link>https://tanle.ca/blog/azure-p2s-vpn-azure-sql/</link><guid isPermaLink="true">https://tanle.ca/blog/azure-p2s-vpn-azure-sql/</guid><description>Working notes on a point-to-site VPN into an Azure virtual network: self-signed certificates in PowerShell, a private endpoint for Azure SQL, and connecting from SSMS.</description><pubDate>Sat, 19 Feb 2022 00:00:00 GMT</pubDate><category>Azure</category><category>DevOps</category></item><item><title>GitLab CI/CD to Azure App Service for a .NET Framework app</title><link>https://tanle.ca/blog/gitlab-cicd-azure-app-service/</link><guid isPermaLink="true">https://tanle.ca/blog/gitlab-cicd-azure-app-service/</guid><description>A GitLab CI/CD pipeline that builds a .NET Framework web app and WebJob on Windows runners and deploys to staging, DR and production App Services with Web Deploy.</description><pubDate>Sat, 19 Feb 2022 00:00:00 GMT</pubDate><category>DevOps</category><category>Azure</category><category>.NET</category></item><item><title>Power Automate business case: Slack alerts from Azure SQL</title><link>https://tanle.ca/blog/power-automate-slack-alerts/</link><guid isPermaLink="true">https://tanle.ca/blog/power-automate-slack-alerts/</guid><description>Posting alerts to Slack with Power Automate when a stored procedure in Azure SQL finds rows that hit the criteria.</description><pubDate>Tue, 03 Aug 2021 00:00:00 GMT</pubDate><category>Power Automate</category><category>Automation</category></item><item><title>Power Automate business case: shared mailbox attachments to SharePoint</title><link>https://tanle.ca/blog/power-automate-mailbox-to-sharepoint/</link><guid isPermaLink="true">https://tanle.ca/blog/power-automate-mailbox-to-sharepoint/</guid><description>A Power Automate flow that watches a shared mailbox for expense reports, saves attachments to a SharePoint library and marks each email read and complete.</description><pubDate>Wed, 14 Jul 2021 00:00:00 GMT</pubDate><category>Power Automate</category><category>Automation</category></item><item><title>Power Automate business case: a holiday request flow</title><link>https://tanle.ca/blog/power-automate-holiday-request/</link><guid isPermaLink="true">https://tanle.ca/blog/power-automate-holiday-request/</guid><description>A holiday request flow built from Microsoft Forms, Teams, Power Automate and Exchange: the form, the manager lookup, the approval and the condition, with screenshots.</description><pubDate>Sat, 10 Jul 2021 00:00:00 GMT</pubDate><category>Power Automate</category><category>Automation</category></item><item><title>API Gateway, Lambda and Cognito: login from the CLI</title><link>https://tanle.ca/blog/aws-api-gateway-lambda-cognito/</link><guid isPermaLink="true">https://tanle.ca/blog/aws-api-gateway-lambda-cognito/</guid><description>Working notes on securing an API Gateway + Lambda endpoint with Amazon Cognito: logging in from the CLI and with plain curl, plus the references that helped.</description><pubDate>Fri, 11 Jun 2021 00:00:00 GMT</pubDate><category>AWS</category></item><item><title>Hands-on: an automated CI/CD pipeline for .NET Core Lambda on AWS</title><link>https://tanle.ca/blog/aws-cicd-pipeline/</link><guid isPermaLink="true">https://tanle.ca/blog/aws-cicd-pipeline/</guid><description>Working notes on applying the AWS DevOps blog&apos;s automated CI/CD pipeline for .NET Core Lambda functions to my own project, including a CodeCommit credential issue on Windows.</description><pubDate>Sat, 05 Jun 2021 00:00:00 GMT</pubDate><category>AWS</category><category>DevOps</category></item><item><title>Uploading to S3 through an API Gateway service proxy, with subdirectories</title><link>https://tanle.ca/blog/aws-api-gateway-s3-proxy/</link><guid isPermaLink="true">https://tanle.ca/blog/aws-api-gateway-s3-proxy/</guid><description>Step-by-step notes for an API Gateway service proxy that reads and writes S3 objects in nested folders through a single {proxy+} resource.</description><pubDate>Wed, 26 May 2021 00:00:00 GMT</pubDate><category>AWS</category></item><item><title>AWS API Gateway as an S3 proxy: IAM role and path parameters</title><link>https://tanle.ca/blog/aws-api-gateway-s3/</link><guid isPermaLink="true">https://tanle.ca/blog/aws-api-gateway-s3/</guid><description>Notes on exposing an S3 bucket as a REST API with API Gateway: the IAM role, its trust relationship, and folder/item path parameters.</description><pubDate>Tue, 25 May 2021 00:00:00 GMT</pubDate><category>AWS</category></item></channel></rss>