Part 2 of 7 · Churn predictor series ~4 min read

How an at-risk customer gets watched

The predictor only scores what’s in the list. So the first job is making sure the list actually reflects how each customer is behaving right now. There are three ways the signals get in: somebody types them in the Drive sheet, a daily order export updates the order columns, or a support ticket gets read for its mood. The first one is obvious. The other two exist because in real life nobody hand-updates a sheet every time a customer orders late or sends a grumpy email.

Key takeaways

  • Three intake lanes feed one list: the Drive sheet, a daily order-feed import, and a support-inbox lane.
  • The order feed refreshes last-order date and order pace from an export your store already produces.
  • Support tickets are read by Bedrock Haiku 4.5, which rates each one’s mood on a simple scale.
  • The mood reader only writes a number back to the row — it never replies to the customer.
  • The Drive sheet stays the canonical store. The other lanes are conveniences that write into it.

Three lanes into one list

Three intake lanes funnel into one list A diagram with three vertical lane columns at the top and a single unified row at the bottom. Lane one, Drive sheet: somebody types or edits a customer row directly in the Google Sheet that holds the list; the drive-sync Lambda mirrors the sheet to S3 every 15 minutes, and the predictor reads from there. Lane two, Order feed: a daily export from the store or billing tool lands in S3; an import Lambda reads it and updates each customer's last-order date and order-pace columns in the sheet via the Sheets API, no human approval needed because these are facts, not judgements. Lane three, Support inbox: support tickets are forwarded or copied to a dedicated address; SES writes the raw message to S3; a reader Lambda calls Bedrock Haiku 4.5 to rate the customer's mood on a simple scale of sour, flat, or happy, and writes that number back to the customer's row. The mood reader never replies to the customer. All three lanes converge on the same Drive sheet, which the drive-sync Lambda keeps mirrored to S3 for the scorer to read. A note at the bottom: the Drive sheet stays the source of truth — the other lanes refresh the signals it holds. Lane 1 · manual Drive sheet • Somebody types a customer row • drive-sync mirrors to S3 every 15 min • Scorer reads from S3 • Source of truth stays in Drive Lane 2 · daily export Order feed • Store exports a daily CSV to S3 • Import Lambda reads each customer • Updates last order and pace columns • Facts, so no approval needed Lane 3 · SES + Haiku Support inbox • Forward a ticket to support-address • SES writes it to S3 • Haiku 4.5 rates mood: sour/flat/happy • Number written back → sheet Drive customer list (source of truth) name · owner · last order · order count · mood · last login · plan · value drive-sync mirrors it to S3 every 15 min — scorer reads from S3 to scorer, weekly run The Drive sheet stays the source of truth — the other lanes refresh the signals it holds.
Fig 2. Three lanes converge on one Drive sheet. The sheet is the source of truth; the order feed and the support inbox are conveniences that refresh the signals. The drive-sync Lambda mirrors the sheet to S3 so the scorer can read it without hitting Drive on every run.

Lane 1: the Drive sheet itself

The simplest lane. Open the list sheet in Drive, add or edit a row, save. The columns are short: name, owner email, last order date, order count, support mood, last login date, plan, and monthly value. A small Lambda — drive-sync — runs every fifteen minutes, exports the sheet as plain CSV via the Drive API, and writes it to s3://cp-list-source/customers.csv if the sheet has changed since the last sync. The scorer reads from S3, not Drive directly. That keeps Drive API calls predictable and gives you S3 versioning for free, so a bad bulk-edit can be rolled back in one click.

This lane covers the initial setup — loading your customers and the things that don’t change often, like owner and plan — and the occasional manual fix, like marking a customer “never flag.”

Lane 2: the order feed (the one that keeps the score honest)

The strongest churn signal a small business has is usually the simplest: did they order, and how recently. Most stores and billing tools can already export a daily file — orders, dates, customers. Lane 2 picks that up. The export lands in s3://cp-order-feed/ (your store drops it there on a schedule, or a tiny connector does). The S3 PUT triggers an import Lambda. The Lambda groups the rows by customer, finds each customer’s most recent order date and their typical gap between orders, and writes last_order_date and order_pace back to the Drive sheet via the Sheets API.

This lane needs no human approval, because it isn’t making a judgement — it’s copying facts. A customer either ordered on the 14th or they didn’t. The order feed is what lets the predictor notice the quiet slowdown — weekly to monthly — that is the clearest early sign someone is drifting, long before they cancel anything.

Lane 3: the support inbox

The other early sign is mood. A customer who sends a string of frustrated tickets and then goes quiet is often on their way out. Lane 3 reads that without anyone hand-scoring it. Set up a dedicated address — something like support-signals@your-company.com — via Amazon SES, and forward (or auto-copy) support tickets there. SES writes the raw message to s3://cp-raw-mime/. The S3 PUT triggers a reader Lambda. The Lambda pulls the ticket text and calls Bedrock Haiku 4.5 with a short prompt: “Rate this customer’s mood: sour, flat, or happy. Return one word. Do not reply to the customer.” The result is turned into a number and written to the customer’s support_mood column, blended with recent tickets so one bad day doesn’t dominate.

The mood reader is the only place a model touches a customer’s words, and it is strictly read-only. It rates a mood and writes a number. It never drafts or sends anything to the customer — the whole point of this system is that a human, not a model, decides what to say to a wavering customer.

Why the list stays the source of truth

Three lanes in, but only one place the scorer actually reads. That’s deliberate. If two lanes both wrote straight into the scorer’s state, every “why was this customer flagged?” question would mean checking three places. Funneling everything through the Drive sheet means there is exactly one row per customer, and any rep can read or edit any of it without learning a new tool. The convenience lanes keep the signals fresh, but they always land in the sheet on the way.

Next post: how the scorer actually reads the list, turns each signal into points, and lands every customer in one of four bands.

All posts