diff --git a/content/medusajs/plugins/available/index.mdx b/content/medusajs/plugins/available/index.mdx index a32581c..c8f59bc 100644 --- a/content/medusajs/plugins/available/index.mdx +++ b/content/medusajs/plugins/available/index.mdx @@ -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. | \ No newline at end of file diff --git a/content/medusajs/plugins/statistics/get-started/index.mdx b/content/medusajs/plugins/statistics/get-started/index.mdx new file mode 100644 index 0000000..c68f31d --- /dev/null +++ b/content/medusajs/plugins/statistics/get-started/index.mdx @@ -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** | | +| **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 { + 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 { + 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 \ No newline at end of file