Case study2026live

A 2-week AI-augmented build that returned ~1,500 hours/year to the team.

Python service on the Salesforce REST API: auto-assignment, AI resolution summaries, Slack notifications. Built in 2 weeks in Cursor + Claude CLI - what used to be a 6-month Apex/Flow project.

RoleSenior BI Analyst (lead)
CompanyIndeed
Duration2 weeks · 2026
TeamBI Team
TagsBIAutomationAI
~1,500/yearHours returned
2weeksSpec to live
100%automatedCommon-path triage
100%by mo. 1Team adoption
Annualized return~1,500 hrs/yearmeasured against an 8-week pre-build baseline
/ view
~6 min · full

01The headline

A 5-person BI team was spending most of every morning hand-triaging Salesforce cases - pulling the new ones, assigning owners, summarizing for routing, posting to Slack so everyone knew what they had. The work was routine but not skippable. I replaced the morning ritual with a Python service that does it automatically. Returns ~1,500 analyst hours per year, redirected toward the cases that actually need human judgment. Two-week build in Cursor with Claude CLI, on top of the Salesforce REST API - what used to be a six-month Apex/Flow project.

02Context & constraints

The team I lead supports all CRM Analytics dashboards and central analytics data globally - five people, growing scope, no headcount on the horizon. Case triage was eating the morning before anyone could touch real work.

A few constraints shaped the build:

  • Auditability. Every automated decision had to be reviewable and reversible. No silent moves on customer-touching records.
  • Don't touch the data model. I could build flows on top of the case object, but the schema itself stayed exactly as-is. No new fields, no migrations.
  • Smooth the load. Assignment logic couldn't just round-robin. It had to factor in current load per analyst so one person didn't get five new cases on a Monday morning.
  • Two weeks. I didn't want to spend a quarter on this. If I couldn't ship in two weeks, the right answer was probably not to ship at all.

03The decision

I built three small pieces, each replaceable:

  • An auto-assigner. Rules-based, with a small ML-assisted bucket for cases that fit a known pattern. Smooths analyst load by checking each person's current case count before routing.
  • An AI summarizer. For each newly-assigned case, generates a 4-sentence resolution starter and appends it to the internal notes field. The analyst reads it as a prompt, then does the real work.
  • A Slack notifier. Posts every morning to the team channel: who got what, with the AI summary inlined. Replaces the manual "I'm taking this one" round-robin we'd been doing in standup.

The whole thing is a Python service on the Salesforce REST API, written in Cursor with Claude CLI as the pair-programmer. The AI-augmented workflow is what made the 2-week timeline real - same scope, an Apex/Flow build the year before would have been a quarter of work.

/ What I chose not to do

Auto-respond or auto-close cases. The AI summaries are good. They are not yet good enough to send to a customer. The cost of one bad auto-response on a real case is significantly worse than the cost of every analyst reading a one-paragraph internal summary. The human stays in the loop on anything outbound until the resolution model has been pressure-tested over a full quarter of confidence-bucket data.

04Process

Two weeks of build, two weeks of supervised operation, then a cron job.

  • Week 1: auto-assignment logic. Pulled case data via the Salesforce REST API, wrote the routing rules, built the load-smoothing logic. Validated against a week of historical assignments to check the script would have made the same calls the team did manually.
  • Week 2: AI summary + Slack notifier. Wrote and iterated on the prompt that turns a raw case into a 4-sentence resolution starter. Wired the Slack webhook. Ran end-to-end against a day of cases.
  • Weeks 3–4: supervised runs. Manually triggered the script every morning, read everything it produced. Caught two prompt-shape issues in the first three days - quick fix, push, run again.
  • Week 5+: automated. Scheduled the run as a daily cron job. Output to Slack, occasional spot-checks. It's been running unattended since.

Almost killed it. The first auth flow used a Salesforce session ID - easy to set up, instantly broken. Session IDs expire on the order of hours and the script was harvesting them manually from a browser session. Fine for a prototype run; fatal for a daily automated job. The fix was a pivot to OAuth 2.0 with a refresh token - the script trades the long-lived refresh token for a fresh access token on every run, no manual step. That pivot is the difference between "neat script I demo'd once" and "cron job that's been running unattended for months."

In hindsight, the SID-first approach was the right pragmatic call - get something working, then worry about scaling it. The mistake wasn't choosing SID; it was not budgeting for the auth rewrite upfront.

05Results

Annualized return~1,500 hrs/yearmeasured against an 8-week pre-build baseline
Common-path triage100% automated
Team adoption100% by month 1
Auth modelOAuth 2.0 + refresh token
StackPython + SFDC REST + Slack
Before - weekly manual triage hrs
~38 hrs/wk avg
After - weekly manual triage hrs
~6 hrs/wk avg

The chart on the work-index card shows the cumulative version of this - hours returned to the team, climbing from zero at launch to ~1,500 by the end of the first year.

06Tradeoffs & what I'd do differently

  • Would do again - AI summaries to internal notes, not to the customer. The summaries are a tool for the human analyst, not a replacement for them. Pasting them into the internal notes field gave the team a starting point without ever risking a bad customer-facing message. Same call next time without question.
  • Would revisit - the state-tracking layer. The script needs a place to log per-run state. I built that on local files initially; in hindsight a shared Google Sheet (or a small DB) would have made the daily output reviewable by anyone on the team without me sending updates. Friction on visibility costs you adoption.
  • Would do differently - n8n turned out to be unnecessary. I lost 2 days figuring out what I needed and waiting on credentials, then realized I didn't need it for this iteration. Pure Python was lower friction for the scope. Definitely something to keep in mind for the future, just not the right tool for this build.
  • Open question - automated responses. The AI summaries keep getting better. The honest question is whether they're good enough to auto-respond on the lowest-stakes case types. I'd want a quarter of confidence-bucket data and a peer review of the resolution model before I'd flip that switch.

07Artifacts

  • Anonymized walkthrough · available on request
  • Architecture overview (Python + Salesforce REST API) · available on request
  • Sanitized auto-assignment logic · code excerpts on request

Want to talk through it?

I respond within 24 hours on weekdays. Happy to walk you through the architecture.