Wiki · Workflow companion

Monthly margin review

First of every month at 07:00 ET: aggregate margins by customer / brand / category for the prior month, compare against trailing 3-month average, surface compressions >5pp, stage propose_price_change proposals for outliers, and deliver an executive summary.

Mixed · Some steps live, others stubbed
What this is

Monthly margin review

Monthly margin review is the recurring health check that keeps the platform honest about whether pricing decisions are landing where they should. It runs on the first of every month at 07:00 ET, so Mike sees the prior month's margin state with his morning coffee.

The cascade aggregates margin by customer × brand × category, compares against the trailing 3-month average, and surfaces compressions greater than 5 percentage points. Each outlier gets a propose_margin_target_pricing row in Mike's queue.

Risk level 3 (medium). Nothing pushes to NS directly — every proposed change still flows through the standard bid_price_update or vendor_cost_update path with its own HITL gate.

When to use it

Trigger conditions

Heuristic

The compression_threshold_pp input defaults to 5pp. Tighter thresholds (3pp) generate noisier queues; looser (8pp) miss real compressions. The default has held for 6+ months of monthly cycles.

Step-by-step what happens

The 3 beats

  1. 01

    Stage price proposals for compressed lines

    For each customer × brand × category where this month's margin dropped >5pp vs trailing 3-mo, a proposed_actions row stages with action_type=propose_margin_target_pricing. Mike approves or rejects per line.

    Writes proposed_actions
    Time ~80ms per outlier
    Kind stage_proposed_action
    Status real
  2. 02

    Render executive summary

    POST /api/digest/email-now with payload=monthly_margin_summary. Generates a PDF or HTML artifact summarizing the month, top compressions, top expansions, and the staged proposals.

    Writes R2 + email body
    Time ~5s
    Kind http_call
    Status stub
  3. 03

    Deliver summary to Mike

    A draft email to Mike with the summary as attachment / inline body, status=pending_review. Mike approves to confirm-receive (and sometimes forwards to the leadership team).

    Writes outbound_email_log
    Time ~80ms
    Kind hitl_email_draft
    Status stub
    Note target · mike
Outcomes

What's different after the workflow runs

Margin pass
Monthly
0 7 1 * *
Outliers staged
Variable
one_per compression
Threshold
5pp default
configurable
Summary
Delivered
PDF/email artifact
Failure modes

What can go wrong and how to recover

Pricing data stale (>7d)

Precondition warns. Likely a sync_log issue — check /admin-dashboard sync status. The review still runs but flags the staleness in the summary.

No compressions found

A clean month. The summary email still sends so Mike sees the all-clear; reflexion logs it as a no-op tick.

Summary render times out

Browser Rendering occasionally stretches. The proposals still stage; only the summary artifact is delayed. Manual re-render: POST /api/digest/email-now?type=margin_summary.

Excessive outliers (signal spike)

If the count exceeds the historical mean by 3σ, Mike gets a heads-up note in the summary. Often signals a vendor cost spike or a margin-rule misconfiguration.

Related

Adjacent workflows + diagrams

For developers

Code paths + invariants

ConcernWhere
Workflow contractworkflow_definitions WHERE workflow_type='monthly_margin_review'
Cron0 7 1 * * America/New_York
Compression threshold5pp default (input override)
Aggregation viewv_pricing_with_brand
Summary endpoint/api/digest/email-now
Reflexion tagmonthly_margin_review
Risk level3
Expected duration~60 min
Triggercron · 0 7 1 * * (America/New_York)
// Compression detection const compressions = lastMonth.filter(m => { const trailing = trailing3mo.get(m.key); return (trailing.avg_margin - m.avg_margin) >= 5; }); // One propose row per compression for (const c of compressions) stageAction('propose_margin_target_pricing', c);