Part 5 of 7 · Price monitor series ~5 min read

How a price alert gets handled

An alert lands in Priya’s Slack DM at 9:12am. A competitor dropped the kettle 13%. There are three buttons. What happens when she taps one? Here’s the most important thing about this whole post: none of the three buttons changes your own price. The monitor watches and tells; the pricing decision stays with Priya. This post walks through the three things she can do on an alert — note, mute, stop — and how the watch list, the page state, and the audit trail stay in sync.

Key takeaways

  • Three actions per alert: note (log a decision, keep watching), mute (silence this page for a while), stop (drop the page).
  • None of the three actions changes your own price — the monitor only ever suggests.
  • Each action writes an audit row; mute and stop also update the page’s state.
  • Mute is bounded — it lasts a set number of days, then the page resumes on its own.
  • The buttons are a Slack interactive message backed by a Function URL.

Three actions on an alert

Three actions on a price alert A diagram showing one input on the left flowing through a small interactive Slack panel, then branching into three action paths. Far left: an "Alert in Slack DM" box showing a typical price alert — product, competitor, old and new price, the percent move, recent history, your own price, link — with three Slack-button placeholders below: Note, Mute, Stop. The owner taps one button. The middle column shows the three branches. Branch one, Note: opens a Slack modal with a short free-text box to record a decision, such as holding the price or planning to match; on save, a Function URL Lambda writes the note to the audit trail and clears the live alert flag so the page keeps being watched without further nagging on this same move. No price is changed. Branch two, Mute: opens a smaller Slack modal asking how many days to mute (default 14); on save, the Function URL Lambda writes a mute row to the pm-mute table that suppresses alerts for that page until the mute ends. The page is still checked and its history still recorded; only the alerting is paused. Branch three, Stop: drops the page from active watching; the Function URL Lambda flags the row in the watch list as stopped via the Sheets API and the page is no longer checked, but its history is kept. Useful when a competitor is discontinued or no longer relevant. The right side shows the convergence: every action writes a row to the pm-audit DynamoDB table with timestamp, page id, action, by-user, and notes. A note at the bottom: no action here changes your own price — the monitor only suggests, and a person always decides. Alert in Slack DM prices, move, history [Note] [Mute] [Stop] Action 1 Note • Modal: record a decision (hold, match, watch) • Writes to audit trail • Keeps watching, no price change Action 2 Mute • Modal: mute N days (default 14) • pm-mute row pauses alerts until it ends Action 3 Stop • Drop page from watching via Sheets API • History kept — no price change Audit trail DynamoDB pm-audit timestamp · page_id action · by-user notes No action here changes your own price — the monitor only suggests, and a person decides.
Fig 5. Three actions per alert, three different effects. Note logs a decision and keeps watching. Mute silences the page for a set time. Stop drops it from the list. Every action writes to the audit trail — and none of them touch your price.

Action 1: note (the most common)

Priya looks at the alert, decides how to respond, and wants to record it. She taps Note. A small Slack modal opens with a single free-text box and a couple of quick-pick chips — “holding price,” “will match,” “watching.” She types “holding — our reviews are stronger and margin is tight” and hits Save.

The Save button submits to a Function URL Lambda. Two things happen, in order. First, an action: note row is written to pm-audit with the user, timestamp, the alert that prompted it, and her text. Second, the live-alert flag for this move on this page is cleared, so the monitor keeps checking the page but won’t re-nag Priya about this same move — only a fresh move past the threshold will alert again.

What doesn’t happen is just as important. The note doesn’t change Priya’s price, doesn’t touch her store, and doesn’t feed back into any auto-pricing — there isn’t one. The note is a memory for the next time this competitor moves, and a record for whoever reviews pricing decisions later. If she decides to match, she goes and changes her price herself, the way she always would; the monitor just made sure she knew to.

Action 2: mute (the deferral)

Some competitors are noisy on purpose. A clearance specialist re-prices daily. A marketplace seller runs a sale every weekend. After the third alert in a week saying the same thing, the alerts stop being signal and start being noise. Priya isn’t ignoring the page — she just wants the monitor to be quiet about it for a while.

Mute opens a small modal asking for the number of days, with a 14-day default and a max of 90. On save, a row is written to pm-mute with (page_id, mute_until). The next check reads that row in the “page muted?” step from Part 3 and treats the page as steady until the mute ends. Crucially, the page is still checked and its history is still recorded the whole time — only the alerting is paused. When the mute ends, the monitor picks up where the history left off, so a price that moved during the mute is caught at the next check.

Mute is bounded by design. It always has an end date; there is no “mute forever” button, because a page muted forever is a page quietly lying to you. If a competitor really is no longer worth watching, the right action is stop, not an endless mute.

Action 3: stop (the “we’re done with this one”)

Sometimes a page just isn’t worth watching anymore. The competitor discontinued the product. They went out of business. You stopped selling that line. Keeping a dead page on the list means a daily check that can only ever fail or mislead.

Stop drops the page from active watching. The Function URL Lambda flags the row in the watch list as stopped via the Sheets API, and the next check skips it. The page’s history in pm-readings is kept — you might want to look back at what a discontinued competitor used to charge — but no new readings are taken. An action: stop row goes to pm-audit with the user and reason, so a later “why did we stop watching Acme?” has an answer.

Stop is reversible: the row is still in the sheet, just flagged. Un-flag it (edit the sheet, Lane 1 from Part 2) and the next check resumes watching from a fresh reading. Nothing is deleted, so a stop made in haste costs nothing to undo.

Every action is logged, and nothing touches your price

The pm-audit table records every note, mute, and stop with the user who took the action, the timestamp, and a snapshot of the relevant state before and after. Three months from now, when someone asks “why aren’t we getting alerts on that competitor?” or “did we ever decide whether to match their sale?”, the answer is one query away.

And it’s worth saying one more time, because it’s the design rule that shaped this whole system: there is no button, no modal, no background job that changes your own prices. The monitor watches competitor pages, notices real moves, and tells the right person with enough context to decide. The decision — match, hold, undercut, ignore — is always made by a human who can weigh things a threshold never could. That’s not a limitation; it’s the point.

Next post: the cost breakdown. The whole pipeline above runs in coffee-money territory at SMB volume; Part 6 explains exactly where the dollars go.

All posts