From claude-ecom
Analyzes D2C ecommerce order CSV data across 30d/90d/365d periods to generate KPI trees, health signals, structured findings, and action plans.
npx claudepluginhub takechanman1228/claude-ecom --plugin claude-ecomThis skill is limited to using the following tools:
D2C ecommerce analytics system. The Python backend computes KPIs, runs
Queries Wix orders via REST API with filters for date ranges, payment/fulfillment status, value; supports revenue, trend, cohort analysis.
Transforms CSVs, Google Sheets, or databases into executive reports with visualizations, metrics, trends, and recommendations. Use for spreadsheet-to-board-report conversion.
Generates marketing performance reports with executive summaries, key metrics tables, trend analysis, wins/misses, and prioritized optimizations for campaigns or channels.
Share bugs, ideas, or general feedback.
D2C ecommerce analytics system. The Python backend computes KPIs, runs health checks, and scores performance from order transaction data; you (Claude) interpret the numbers and write the human-readable report.
Input: Order transaction data only (CSV).
| Command | What it does | Output |
|---|---|---|
| /ecom review | Full business review (auto-selects periods from data) | REVIEW.md |
| /ecom review 30d | Focused on the last 30 days | REVIEW_30D.md |
| /ecom review 90d | Focused on the last 90 days | REVIEW_90D.md |
| /ecom review 365d | Focused on the last 365 days | REVIEW_365D.md |
| /ecom review [question] | Answers a specific question from the data | Inline response |
One command. Two modes: full report or focused answer.
Triggered when: no natural-language question in the user's input. Output: REVIEW.md (or REVIEW_{PERIOD}.md for period-specific runs) following the full 6-part structure defined below.
Examples: /ecom review, /ecom review 30d, /ecom review 365d
Triggered when: user's input includes a natural-language question or topic. Output: inline conversational response (no file creation).
Examples:
| Query pattern | Data source |
|---|---|
| last 30 days | --period 30d |
| last 3 months / last 90 days | --period 90d |
| last year / this year | --period 365d |
| last month / specific month name | full run, extract from monthly_trend |
| Q1-Q4 / specific quarter | full run, extract from monthly_trend |
Calendar-month questions ("last month", "January") use the 365d monthly_trend, NOT a 30d trailing window. Use --period 30d only when the user explicitly asks for "last 30 days".
Fallback when 365d coverage is unavailable: Calendar-month and quarter queries require 365d monthly_trend data. If 365d coverage is missing (data < 400 days):
monthly_trend limitation: no year-over-year comparison by month/quarter monthly_trend covers only the most recent 12 months. Comparing "Q4 this year vs Q4 last year" is not possible. Instead:
If the query doesn't map to a clear period, run full (no --period flag) and answer from the most relevant data.
Total: 10-30 lines. Headings, KPI tree, and Finding format are NOT required. Use whatever structure best fits the answer. For example, "what's the new vs returning split?" is clearest as a partial KPI tree. Apply the same data rules: all numbers from review.json only, match user's language. Do NOT create a REVIEW.md file.
Order transaction data (CSV). Each row = one order or line item.
Required columns:
~/.claude/skills/ecom/bin/ecom review orders.csv --output <output-dir>
~/.claude/skills/ecom/bin/ecom review orders.csv --period 90d --output <output-dir>
~/.claude/skills/ecom/bin/ecom review orders.csv --output <output-dir>
The engine internally:
Output: review.json (or review_{period}.json for period-specific runs). See Schema section below.
review.json (or review_{period}.json for period-specific runs)REVIEW_{PERIOD}.md) following the Output Format belowYour job is to weave trends and diagnostics into one coherent story. Period analysis tells you where things are heading. Health checks tell you what's broken right now. The report combines both.
This is the data contract between Python and Claude. Every field below is guaranteed to exist in the output. Claude reads this structure; Claude does NOT invent data that isn't here.
{
"version": "0.1.0",
// --- Metadata ---
"metadata": {
"generated_at": "2026-03-05T18:00:00Z",
"data_start": "2025-01-01",
"data_end": "2025-12-31",
"total_orders": 5784,
"total_customers": 2765,
"total_revenue": 1383651,
"currency": "USD",
"revenue_definition": "Net sales after discounts, before tax and shipping"
},
// --- Data quality warnings (empty array = no issues) ---
"data_quality": [
// Example entries (only present when issues detected):
// { "type": "partial_period", "period": "2026-02", "days_with_data": 3,
// "message": "Latest month (2026-02) has only 3 days of data. MoM comparisons use prior complete months." }
// { "type": "short_data_span", "days": 45, "message": "Data spans only 45 days..." }
// { "type": "limited_data_span", "days": 200, "message": "Data spans 200 days (<1 year)..." }
],
// --- Data coverage: which periods are available ---
"data_coverage": {
"30d": true, // true if >=45 days of data exist
"90d": true, // true if >=120 days of data exist
"365d": true // true if >=400 days of data exist
},
// --- Period metrics (one block per available period) ---
"periods": {
"30d": {
"summary": {
"revenue": 98000,
"revenue_change": -0.003, // vs prior 30d
"orders": 412,
"orders_change": -0.03,
"aov": 238,
"aov_change": -0.001,
"customers": 287,
"customers_change": -0.05
},
"kpi_tree": {
"new_customer_revenue": 38000,
"new_customer_revenue_share": 0.388,
"new_customers": 95,
"new_customers_change": -0.08,
"new_customer_aov": 400,
"returning_customer_revenue": 60000,
"returning_customer_revenue_share": 0.612,
"returning_customers": 192,
"returning_customers_change": -0.03,
"returning_customer_aov": 312
},
"drivers": {
"aov_effect": 1200, // revenue change attributable to AOV
"volume_effect": -1500, // revenue change attributable to order count
"mix_effect": 0 // revenue change attributable to new/returning mix shift
}
},
"90d": { /* same structure */ },
"365d": {
/* same structure as 30d (summary, kpi_tree, drivers) plus: */
"repeat_purchase_rate": 0.38, // only in 365d block
"monthly_trend": [
{ "month": "2025-01", "revenue": 95000, "orders": 420, "aov": 226, "customers": 310, "new_customers": 180, "returning_customers": 130, "days_with_data": 31 },
// ... only months with actual data (no zero-fill for future months)
{ "month": "2025-12", "revenue": 12000, "orders": 45, "aov": 267, "customers": 38, "new_customers": 10, "returning_customers": 28, "days_with_data": 3, "partial": true }
]
}
},
// --- Health checks (powers 🟢/🟡/🔴 markers) ---
"health": {
"checks": [
{
"id": "monthly_revenue_trend", // internal only, never expose
"category": "revenue",
"severity": "high",
"result": "watch", // pass | watch | fail
"message": "MoM revenue growth: -3.8%",
"value": -0.038,
"threshold": 0.0
}
// ... more checks
],
"top_issues": [
// Pre-sorted by severity * impact. Max 10.
{
"id": "multi_item_order_rate",
"category": "product",
"severity": "high",
"result": "fail",
"message": "Multi-item order rate: 0.0%",
"estimated_annual_impact": 77573
}
// ...
]
},
// --- Pre-computed action candidates ---
"action_candidates": [
{
"action": "Introduce product bundles to increase multi-item orders",
"source_check": "multi_item_order_rate", // internal reference
"severity": "high",
"estimated_annual_impact": 77573,
"timeline": "this_month"
}
// ... max 10 candidates, sorted by impact
]
}
periods only contains keys for periods where data_coverage is true_change fields are proportional change vs prior period (e.g., 0.08 = +8%)health.checks contains every check result; health.top_issues is a
filtered/sorted subset (fail and watch only, max 10, sorted by severity × impact)action_candidates are suggestions from Python; Claude refines, merges, and
rewrites them in business language for the reportmonthly_trend contains only months with actual order data (no zero-fill for future months)monthly_trend entries with "partial": true have less than half the month's days with datadata_quality is non-empty, mention relevant warnings in Data NotesLoad on-demand -- do NOT load all at startup.
Path:
references/
review-narratives.md -- Narrative templates by health level and growth trajectory, finding templates, period-specific guidance. Always load.finding-clusters.md -- Cluster model for grouping related issues into themes. Load to identify themes.recommended-actions.md -- Actionable recommendations per check with timeline and impact range. Load for watch/fail checks.impact-formulas.md -- Revenue impact formulas with worked examples. Load when estimating impact.health-checks.md -- Check definitions (R/C/P) with thresholds and interpretation.benchmarks.md -- D2C ecommerce KPI benchmarks.The following structure applies to Full Review mode only. See Response Modes for Focused Query.
One report. Three parts. Target: ~150 lines. Tighter is better.
Before writing, verify your report contains ALL sections in this exact order. Missing or reordered sections are a format violation.
Structural rules:
Synthesize across all available periods. Structure:
[North Star result + trend across periods]
[What's working: 1-2 strengths confirmed by data -- 80/20 rule]
[What needs attention: the key tension/risk, with data]
[Most important action, with timeline]
Example:
Revenue reached $1.38M for the year (+25.7% YoY), but growth is decelerating -- the last 90 days grew only 8% vs prior 90 days, and last month was flat (+0.3%). Growth depends on existing customer AOV increases (+14.8%), while new customer acquisition has stalled (share: 42.3%, unchanged). Reallocate 20% of retention budget to acquisition channels by end of this month, targeting CPA below $XX.
30d Pulse 90d Momentum 365d Structure
Revenue $98K (= flat) $340K (+ 8%) $1.38M (+ 26%)
Orders 412 (- 3%) 1,280 (+ 5%) 5,784 (+ 10%)
AOV $238 (= flat) $266 (+ 12%) $239 (+ 15%)
Customers 287 (- 5%) 812 (+ 3%) 2,765 (+ 10%)
+ improving, - deteriorating, = stable.
Only show periods that data supports.
CRITICAL: Each period gets its own heading and its own KPI tree. Do NOT merge periods into thematic sections.
All periods use the same skeleton. But they are not equal length:
| Period | Depth | Findings cap | Role |
|---|---|---|---|
| 30d Pulse | Shallow -- KPI tree + 1-2 sentences + max 1 finding | 1 | Flag fires only |
| 90d Momentum | Medium -- KPI tree + drivers + max 2 findings | 2 | Main analytical body |
| 365d Structure | Deep -- KPI tree + drivers + max 3 findings | 3 | Strategic narrative |
If only one period is available, give it the full depth (3 findings).
The total across all periods must not exceed 5-7 findings. If a theme appears in multiple periods, state it once at the most structural level and reference supporting signals from shorter periods.
KPI Tree:
Revenue $X (vs prior period: +X%)
|-- 🟢 New Customer Revenue $X (X% of total)
| |-- New Customers: X (+X%)
| |-- New Customer AOV: $X (+X%)
|-- 🟡 Existing Customer Revenue $X (X% of total)
|-- Returning Customers: X (+X%)
|-- Returning AOV: $X (+X%)
|-- Repeat Purchase Rate: X% -- first-to-second purchase conversion (365d only)
🟢 healthy / 🟡 watch / 🔴 problem (driven by health check results).
Growth Drivers (1-2 sentences, 90d and 365d only):
Was the change volume-driven or price-driven? Connect to KPI tree nodes.
Findings (within period cap):
Each follows Finding Quality Standards. Findings should weave trend data and health check diagnostics together, not present them separately. Use this format:
What is: [1 sentence, quantitative fact]
Why it matters: [Data-backed tension with "however"/"despite"/"but"]
What to do: [Direction only — 1 sentence. Details go in Action Plan.]
Hard cap: 5 action items. Exceeding 5 is a format violation.
Action Plan is the single source of truth for deadlines and success metrics. Findings point to the problem and direction; Action Plan specifies the execution.
One list synthesizing across all periods. Group by time horizon:
Immediate (from 30d signals)
1. ...
This Month (from 90d findings)
2. ...
This Quarter (from 365d insights)
3. ...
For each item:
End with (REQUIRED -- omitting Guardrails is a format violation):
Guardrails: [2-3 metrics that must not deteriorate while executing above actions]
Example: AOV must stay above $X | Repeat purchase rate must not drop below X% | Discount rate must stay under X%
Always include:
metadata.revenue_definition)Every finding follows: What is → Why it matters → What to do
Good:
What is: Annual revenue grew 25.7% YoY.
Why it matters: However, despite a 25.4% reduction in discount rate, new customer
revenue share remains at 42.3% -- growth depends entirely on
existing customer AOV increases (+14.8%).
What to do: Reallocate retention budget toward acquisition channels to diversify growth sources.
Bad (PROHIBITED):
What is: Revenue grew 25.7%.
Why it matters: Rapid growth must be validated. <-- no data, no tension
What to do: Consider improving acquisition. <-- banned verb, no deadline
data_quality array is non-empty, mention relevant warnings in Data NotesEach check returns pass / watch / fail. These power the 🟢🟡🔴 KPI tree markers. Check definitions in
references/health-checks.md. Do NOT use numeric scores, letter grades, or percentage-based health ratings.
The skill uses a local Python runtime installed in ~/.claude/skills/ecom/.venv/.
Use the wrapper command:
~/.claude/skills/ecom/bin/ecom review orders.csv --output <output-dir>
~/.claude/skills/ecom/bin/ecom review orders.csv --period 90d --output <output-dir>
Modules: loader, metrics, decomposition, cohort, product,
checks, report, review_engine, config, normalize, periods.