Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions content/medusajs/plugins/available/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ sidebarTitle: Available plugins
| [Notifications](/medusajs/plugins/notifications/get-started) | Codee Team | Reviewed | Transactional notifications with template system, admin builder, and rendering workflows for email and Slack |
| [Reorder](/medusajs/plugins/reorder/get-started) | Reorder | In Review | Subscription management plugin — billing cycles, automated renewals, dunning, retention flows, and analytics |
| [Avalara](/medusajs/plugins/avalara/get-started) | Avalara | In Review | Official Avalara-certified tax automation plugin for Medusa — real-time tax calculations, order transaction management, and address validation powered by AvaTax API. |
| [Statistics](/medusajs/plugins/statistics/get-started) | tax1driver | In Review | Flexible statistics and analytics plugin for Medusa. |
325 changes: 325 additions & 0 deletions content/medusajs/plugins/statistics/get-started/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
---
title: Get started
sidebarTitle: Get started
---

# medusa-stats

Flexible statistics and analytics plugin for Medusa with pluggable providers, composable charts, and alerting.

| Field | Details |
|-------|---------|
| **Status** | In Review |
| **Repository** | [github.com/tax1driver/medusa-stats](https://github.com/tax1driver/medusa-stats) |
| **Version** | <StarterVersion repo="tax1driver/medusa-stats" fallback="1.0.10" /> |
| **Author** | [tax1driver](https://github.com/tax1driver) |

## Features

- **Pluggable Statistics Providers** — Define and register custom providers for domain-specific metrics
- **Views and Chart Composition** — Organize metrics into configurable dashboards
- **Composite Statistics** — Build statistics that depend on other statistic outputs
- **Alerting System** — Configure threshold/comparative alerts with event emission
- **Admin Interface** — Manage views, options, and lifecycle operations from Medusa Admin
- **Caching Support** — Improve performance with cached statistic results

## Compatibility

- **Medusa Version**: `>= v2.11.2`
- **Node Version**: `>= 20`

## Installation

### 1. Install the package

```bash
npm install medusa-stats
# or
yarn add medusa-stats
```

### 2. Register the plugin and module

Add the plugin and statistics module to your `medusa-config.ts`:

```typescript
modules: [
{
resolve: "medusa-stats/modules/statistics",
dependencies: [ContainerRegistrationKeys.QUERY], // Query dependency is required for provider injection
options: {
providers: [
{
resolve: "medusa-stats/providers/common",
},
],
},
},
],
plugins: [
"medusa-stats"
]
```

### 3. Configure providers

Start with the built-in `common` provider, then add your own providers as needed. See [Providers](#providers) for examples.

## Overview

`medusa-stats` is a flexible statistics module for Medusa that supports custom metric definitions, chart-oriented organization, composable/stat-transform calculations, and configurable alert workflows.

## Basic Usage
The plugin provides a framework for defining and calculating statistics as well as an admin interface for their management and visualization. The primary goal of the module is to provide a flexible way to create custom statistics and views that suit your business needs, without being limited to predefined metrics.

The module can also be used out-of-the-box with pre-defined statistics providers and the admin interface.

### Views
Views are collections of related statistics visualizations. They allow you to organize statistics in any way that suits your needs. Every chart in a view can display multiple statistical measurements, each based on a different statistic option.

![Views Image](https://github.com/tax1driver/medusa-stats/blob/master/docs/static/view.png)

### Options
Options are instances of statistics that are calculated with specific parameters. By changing an option's parameters, you can adjust the underlying statistic calculation.

![Options Parameters Image](https://github.com/tax1driver/medusa-stats/blob/master/docs/static/params.png)

When editing, options can also be configured in terms of their visualization (chart type, dimensions, etc.), cache settings and other parameters.

![Visualization Settings Image](https://github.com/tax1driver/medusa-stats/blob/master/docs/static/visualizations.png)

## Providers

Providers define what statistics are available and how they are calculated.

### Add provider to project

Register your provider in `medusa-config.ts` under the `medusa-stats` module:

```typescript
modules: [
{
resolve: "medusa-stats",
options: {
providers: [
{ resolve: "medusa-stats/providers/common" },
{ resolve: "medusa-stats/providers/composite" },
{ resolve: "./src/providers/statistics/my-provider" },
],
},
},
]
```
### Included providers

`medusa-stats` includes two built-in providers:

- `medusa-stats/providers/common`
- General commerce statistics (orders, carts, sales, channels, regions, and related aggregates).
- `medusa-stats/providers/composite`
- Composite/stat-transform statistics that consume other statistic outputs.
- Included statistics: `moving_average`, `rate_of_change`.


### Creating a Statistics Provider

Create a provider class by extending `AbstractStatisticsProvider`, expose available statistics in `getAvailableStatistics`, and implement calculation logic in `calculateStatistic`.

Example: a `total_cart_value` statistic (available in the Common Statistics Provider) with filters for currency and cart status.

```typescript
import { ModuleProvider } from "@medusajs/framework/utils"
import {
AbstractStatisticsProvider,
StatBuilder,
createTimeSeries,
sum,
type AvailableStatistic,
type CalculateStatisticInput,
type StatisticResult,
} from "medusa-stats"

class MyStatisticsProvider extends AbstractStatisticsProvider {
static identifier = "my-statistics"
static displayName = "My Statistics Provider"

async getAvailableStatistics(): Promise<AvailableStatistic[]> {
return [
new StatBuilder("total_cart_value", "Total Cart Value")
.description("Total value of all carts over time")
.field({
name: "currency_code",
label: "Currency",
description: "Filter by currency code",
schema: z.string().optional(),
fieldType: "text",
placeholder: "USD"
})
.chart("line")
.dimension("time")
.build(),
]
}

async calculateStatistic(input: CalculateStatisticInput): Promise<StatisticResult> {
const { id, parameters, periodStart, periodEnd, interval } = input;

switch(id) {
case "total_cart_value": {
const currencyCode = parameters.currency_code;

const filters: any = {
created_at: { $gte: periodStart, $lte: periodEnd }
};

if (currencyCode) {
filters.currency_code = currencyCode;
}

const { data: carts } = await this.query.graph({
entity: "cart",
fields: ["id", "created_at", "total"],
filters
});

const timeSeries = createTimeSeries( // helper function for time series creation
carts,
periodStart,
periodEnd,
interval,
sum('total') // helper accumulator function
);

return {
value: timeSeries,
metadata: { totalCarts: carts.length }
};
}
}
}
}

export default ModuleProvider("statistics", {
services: [MyStatisticsProvider],
})
```



## Composite Statistics

Composite statistics allow one statistic option to use another option's output as an input.

### Admin Usage
A stat option can be configured to receive another statistic's output by settings its value in the Dependecnies section when editing a stat instance in the admin dashboard.

![Dependencies Image](https://github.com/tax1driver/medusa-stats/blob/master/docs/static/composite.png)

### Using composite fields in providers

To make a statistic composable, define a provider parameter with `fieldType: "stat"`.
At runtime, that parameter receives dependency output data and can be processed like any other input.

```typescript
import { z } from "zod"
import { StatBuilder } from "medusa-stats"

new StatBuilder("moving_average", "Moving Average")
.description("Smooth a time series by averaging values over a rolling window")
.field(
{
name: "input_series",
label: "Input Series",
description: "Dependency result to analyze",
fieldType: "stat",
schema: TimeSeriesSchema
}
)
.field(
{
name: "window_size",
label: "Window Size",
fieldType: "number",
schema: z.number().int().min(2).max(365).default(7),
},
7 // initial value
)
.build()
```

## Alerts

Alerts can be configured per option to trigger when conditions are met.

### Features

- Absolute and comparative conditions
- Alert logs
- Scheduled evaluation job
- Event emission for custom handling

### Emitted Events
To handle the alert triggers, register a subscriber for the `statistics.alert` event type.

```typescript
type StatisticsAlertEventData = {
alert_id: string
alert_name: string
severity: "info" | "warning" | "critical"
option_id: string
current_value: number
reference_value: number | null
compare_value: number | [number, number]
operator: "lt" | "gt" | "lte" | "gte" | "eq" | "neq" | "between"
comparison_type: string
}
```

## Caching
In order to optimize performance, statistic results are cached for a configurable amount of time. When a statistic is requested, the module first checks if a valid cached result exists and returns it if available. If not, it calculates the statistic, stores the result in the cache, and then returns it.

### Cache Configuration
To use caching, `CachingModule` must be enabled in the Medusa project.

```typescript
{
resolve: "@medusajs/medusa/caching",
options: {
providers: [
{
resolve: "@medusajs/caching-redis",
id: "caching-redis",
is_default: true,
options: {
redisUrl: process.env.CACHE_REDIS_URL,
},
},
],
},
},
```

The CachingModule's feature flag needs to be enabled as well:

*in `.env` file:*
```env
MEDUSA_FF_CACHING=true
```

or

*in `medusa-config.ts`:*
```typescript
featureFlags: {
caching: true,
}
```

## Planned features and improvements
- More built-in chart types and visualization options
- Visualization providers for custom chart types and UI components
- Visualization on entities' details pages (e.g. product statistics on product page)


## License
MIT