ecommerce-sales-dashboard
Read-only sales dashboard for the merchant's Shopify store — GMV / Total sales / AOV / repeat-customer rate with period-over-period (PoP) trends, plus list/delist suggestions from per-product sales velocity.
name: ecommerce-sales-dashboard description: Read-only sales dashboard for the merchant's Shopify store — GMV / Total sales / AOV / repeat-customer rate with period-over-period (PoP) trends, plus list/delist suggestions from per-product sales velocity. tags: [internal, ops, requires-yepai-tools] license: MIT-0
Ecommerce Sales Dashboard
Turns real Shopify order data into an operator "cockpit": how fast we're selling, how efficiently, and whether buyers come back — then suggests what to keep listed and what to review for delisting. Read-only.
Core KPI framework (the three questions)
- Velocity — how much are we selling now vs. the prior period? (GMV, orders, units)
- Efficiency — AOV and Conversion Rate.
- Retention — new vs. returning customers.
Metrics & formulas
| Metric | Formula | Benchmark (DTC) |
|---|---|---|
| GMV | Σ subtotals + discounts (gross, before discounts) | — |
| Total sales | Σ subtotals — every order that was paid for | > 85% of GMV |
| AOV | Total sales / orders | industry-dependent |
| Conversion Rate | conversions / sessions × 100 | 2.5–4.0% |
| Returning-customer rate | returning / total customers × 100 | 20–30% |
| Refunds | what has come back on this period's own orders, so far | — |
| Refund rate | refunds / GMV × 100 | 3–8% healthy, >15% danger, <2% elite |
🔴 Refunds are NOT subtracted from any sales figure (changed 2026-09-08). Every sales number counts every order the store took money for, whatever has been refunded since; refunds are their own row. So: no day can read negative, AOV is over the same orders the sales figure counts, and the refund rate divides one set of orders by itself.
Two things to say when it matters, and never to guess at:
- This is deliberately NOT Shopify Analytics' "Total sales", which IS net of returns. A merchant comparing the two sees ours higher by the refunds amount. If they ask why, that is the answer — do not suggest a data problem.
- A closed period's refunds keep growing — but ONLY where the figure is re-read. A
refund belongs to the period that SOLD the order, so it counts toward that period
whenever the money actually goes back.
SALES_DASHBOARDre-reads the store on every call, so its refunds row and refund rate are "so far", not final: never present either as the last word, and never explain a change in them as a correction. ⚠️ The weekly report is a FROZEN snapshot — generated once, never recomputed. Its refunds line is what had come back as of its own "data as of" moment, and it does NOT rise afterwards. So do not tell a merchant that an old weekly report will update, and do not reconcile a dashboard figure against an old report's: the dashboard has later refunds the report cannot have. If they differ, that is the reason — say it.
Both figures come off the subtotal — line items after discounts, before tax and shipping. Tax and shipping are money the merchant collects and hands on, not revenue. Quote Total sales, not GMV, when the merchant asks 销售额 / "total sales": GMV is gross before discounts and appears on no other surface.
Run: SALES_DASHBOARD (one call, one view)
Call SALES_DASHBOARD with a window (see below), and view:
view="kpi"— KPI scorecard (GMV / Total sales / AOV / units / refund rate / returning-customer rate, each with PoP).view="recs"— per-product Keep / Watch / Delist recommendations.view="chart"— daily-sales line (the platform renders the chart card). It plots Σ subtotals per day, which is why it is no longer called a GMV line: GMV adds discounts back and this does not. No bar can be negative.
It pulls real orders, customers (new vs returning) and the catalog, tenant-scoped —
no shop domain or keys. The result also reports orders_in_window, directional
(small sample), test_orders_excluded, and two separate floor flags — relay these
caveats:
sales_read_truncated— the SALES read ran out of pages, so the money figures and the order count are floors ("at least"). Their PoP changes, AOV and refund rate are then withheld, because a figure computed from a floor is neither a floor nor a ceiling.order_read_truncated— the LOCAL order walk ran out, so units sold is a floor and the retention rate is withheld. It says nothing about the money figures.
Do not merge the two into one sentence: they are budgeted independently and govern different rows.
The window: days for rolling, period for the calendar
A calendar period is a different question from a rolling one, and it gives a different number. On a Wednesday, "this week" is three days; "the last 7 days" reaches back into last week. Answering one with the other is wrong even though both are "about a week".
- Rolling —
days(default 30), compared against the prior equal window. Use for "last 7 days", "past month", "最近30天", or when no period is named. - Calendar —
period, one oftoday·yesterday·this_week·last_week·this_month·last_month. Use whenever the merchant names one: "this week", "本周", "这周", "esta semana", "cette semaine", "last month", "上个月", "今天", "昨天". Weeks start Monday, in the store's own timezone. Leavedaysalone when you pass it.
A part-finished period (this_week, this_month, today) is compared against the same
number of days of the period before, never against a whole one — so "this week" on a
Tuesday reads as two days vs two days, not as a collapse. The result carries window
(from / to / label / compared_with); if the merchant's follow-up is about a
different span, call again rather than reusing the last answer.
Language. The block's title and labels are English whatever language the merchant used — they are the tool's verbatim data (SOUL.md), so quote them as-is inside your own prose rather than translating them. Write your prose in the merchant's language as usual.
One view per ask (these map to separate product screens — don't emit all three):
"dashboard / KPI / sales overview" → kpi · "list-delist / ops recommendations / keep-or-cut" → recs · "trend / daily sales"
→ chart. Emit more than one only if the merchant explicitly asks for a full
report / all of them. Never re-type the block — 1–3 sentences of interpretation only.
Signal vs. noise (how to read it)
- ±20% rule — daily/PoP swings within ±20% of trend are usually noise; don't react.
- Conversion drop >30% in 24h without a traffic spike = signal of a technical issue (checkout bug, broken discount). (Needs sessions — see honesty.)
- AOV spike — any single order >10× AOV is flagged: usually wholesale or fraud, audit it.
Operations recommendations — Keep / Watch / Delist (ops report)
Each ACTIVE product is classified from current-vs-prior-period units:
- Keep — sales stable or up (≥ −30% / rising) → maintain.
- Watch — units down ≥30% vs prior period → consider repricing or replacing.
- Delist? — zero sales this period → review for delisting (weigh with margin + how long it's been live; give new listings a fair exposure window first).
- AI Insight — the report surfaces the single most-need-attention product (lowest- units Watch/Delist) with a concrete next action — dynamic, never hardcoded.
- The report also shows an overview (active-product count · total units over the last N days · trend rating Good/Below average).
- The
recsview's table has columns: product / sub-category / cumulative units / units over last N days / trend / recommendation / reason — recent = current window vs prior, cumulative = all-time within the fetched orders. Pairs withUNLIST_PRODUCTto unlist a reviewed item (gated, merchant OK), andMARGIN_ANALYZEfor delist economics.
Honesty (SOUL)
- Conversion Rate = N/A unless GA4 / Shopify Analytics sessions are connected — shown as N/A, never guessed.
- Small order volume → directional: with few orders, KPIs and benchmarks are indicative, not statistical — the report says so.
- Refund lag: refunds land 7–14 days after a sale. Since 2026-09-08 that does NOT make recent revenue "read high" — sales never had refunds taken off them, so the sales figure will not fall later. What lags is the REFUNDS row of the period that sold those orders: a recent period's refunds and refund rate are the lowest they will ever be, and both rise as the returns arrive on the live dashboard; a frozen weekly report keeps the figure it was generated with. Say that, not the old sentence — telling a merchant their revenue will settle downward is now simply false.
Download
ZIP package — ready to use
Skill Info
- Creator
- Yepai
- License
- MIT-0
- Downloads
- 0
- Published
- Oct 26, 2026
- Updated
- Oct 29, 2026