medusa-analytics
v0.0.25
Published
A starter for Medusa plugins.
Maintainers
Readme
medusa-analytics
Medusa v2 admin analytics extension that adds orders and customers dashboards with custom admin APIs.
Plugin Overview
medusa-analytics adds an Analytics extension page to the Medusa Admin with:
- Orders KPIs (total orders, revenue, AOV, pending/cancelled/delivered, returns, exchanges, fulfillment time)
- Orders time-series charts (7 days, 30 days, 12 months)
- Customer KPIs (guest, registered, total, deleted accounts)
- Customer time-series charts (registered vs guest over time)
It solves the need for a lightweight, in-admin analytics dashboard without external BI tools.
Medusa Compatibility
- Built for Medusa v2
- Package versions indicate Medusa
2.12.4compatibility (@medusajs/framework,@medusajs/medusa)
Installation & Setup
1) Install
npm install medusa-analyticsyarn add medusa-analytics2) Register plugin in medusa-config.ts / medusa-config.js
import { defineConfig } from "@medusajs/framework"
export default defineConfig({
plugins: [
{
resolve: "medusa-analytics",
options: {},
},
],
})3) Build and run
npx medusa plugin:build
npx medusa develop4) Migrations
This plugin does not define custom models or migrations. No plugin-specific migration step is required.
Configuration (config.ts / plugin options)
The plugin currently does not read or enforce runtime plugin options in source code.
| Option | Type | Required | Default | Description | |---|---|---|---|---| | None implemented | - | - | - | No custom option parsing is present in the plugin code. |
Example registration:
{
resolve: "medusa-analytics",
options: {}
}⚠️ Note: If you plan to add configurable chart limits (for example
takesize, currency, or timezone), define and document them in typed plugin options.
Environment Variables
No runtime environment variables are consumed by the implemented analytics code.
| Variable | Required | Purpose | Example | |---|---|---|---| | None in implementation | - | - | - |
⚠️ Note:
src/modules/README.mdcontains generic starter examples usingprocess.env, but those are documentation snippets, not active plugin logic.
REST APIs / Routes
All implemented custom APIs are admin routes under /admin/analytics/*.
1) GET /admin/analytics/orders-summary
Returns orders KPI cards data and status counts (pending, cancelled, delivered) for a selected day range.
Auth requirement: Admin authenticated request (admin route context)
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| days | string \| number | No | Supports all (default), 0 (today), or integer day ranges (clamped between 1 and 365). |
Response Schema
| Field | Type | Description |
|---|---|---|
| totalOrders | number | Total orders in range. |
| totalRevenue | number | Revenue sum excluding cancelled orders. |
| aov | number | Average order value excluding cancelled orders. |
| ordersToday | number | Orders created today. |
| pendingOrders | number | Pending orders count. |
| cancelledOrders | number | Cancelled orders count. |
| deliveredOrders | number | Delivered orders count (based on fulfillments.delivered_at). |
| exchangeOrders | number | Exchange order changes in range. |
| returnOrders | number | Returns in range. |
| avgFulfillmentTimeHours | number \| null | Average created_at -> first shipped_at duration. |
| statusCounts | { pending?: number; cancelled?: number; delivered?: number } | Status breakdown used by charts/cards. |
Example
curl -X GET "http://localhost:9000/admin/analytics/orders-summary?days=30" \
-H "Authorization: Bearer <ADMIN_TOKEN>"2) GET /admin/analytics/orders-over-time
Returns orders time-series for charting.
Auth requirement: Admin authenticated request (admin route context)
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| period | string | No | one_week (default), one_month, 12_months, or one_year. |
Response Schema
| Field | Type | Description |
|---|---|---|
| dailyOrders | Array<{ date: string; orders_count: number; label?: string }> | Time-series points; monthly modes include optional month label. |
Example
curl -X GET "http://localhost:9000/admin/analytics/orders-over-time?period=one_year" \
-H "Authorization: Bearer <ADMIN_TOKEN>"3) GET /admin/analytics/customers-summary
Returns customer summary cards (guest, registered, total, deleted).
Auth requirement: Admin authenticated request (admin route context)
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| days | string \| number | No | Supports all (default), 0, or integer day ranges (clamped between 1 and 365). |
Response Schema
| Field | Type | Description |
|---|---|---|
| guestCount | number | Customers without account in range. |
| registeredCount | number | Customers with account in range. |
| totalCount | number | Total customers in range. |
| deletedAccountsCount | number | Count of soft-deleted customer accounts (withDeleted: true). |
Example
curl -X GET "http://localhost:9000/admin/analytics/customers-summary?days=90" \
-H "Authorization: Bearer <ADMIN_TOKEN>"4) GET /admin/analytics/customers-over-time
Returns customer time-series split by registered vs guest.
Auth requirement: Admin authenticated request (admin route context)
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| period | string | No | one_week (default), one_month, 12_months, or one_year. |
Response Schema
| Field | Type | Description |
|---|---|---|
| series | Array<{ date: string; label?: string; registered_count: number; guest_count: number }> | Time-series rows for dual-line chart rendering. |
Example
curl -X GET "http://localhost:9000/admin/analytics/customers-over-time?period=one_month" \
-H "Authorization: Bearer <ADMIN_TOKEN>"Services
No custom service classes are implemented in this plugin.
The routes query Medusa data directly via:
ContainerRegistrationKeys.REMOTE_QUERY(RemoteQueryFunction)- Core modules from
Modules.ORDERandModules.CUSTOMER
Workflows & Steps (Medusa v2)
No custom workflows or steps are implemented in source code.
Subscribers / Event Hooks
No event subscribers are implemented in source code.
Admin UI / Widgets
This plugin ships a custom Admin route extension (not widget-zone injection).
Route: Analytics page
- Location: Extensions sidebar as
Analytics(ChartBar icon) - File:
src/admin/routes/analytics/page.tsx - What it renders: Module switcher with two dashboards: Orders and Customers
- Interactions: Tab/button switch between modules
- Data consumed: Internal fetches from all 4 custom admin analytics APIs
Orders dashboard
- File:
src/admin/routes/analytics/components/OrdersDashboard.tsx - Renders:
- KPI cards (orders, revenue, AOV, orders today, pending, cancelled, delivered, exchange, return)
- Pie chart for order status
- Pie chart for returns vs exchanges
- Line chart for orders over time
- Interactions:
- Summary period selector (
all,0,7,30,90) - Over-time period selector (
one_week,one_month,one_year) - Clear filter action
- Summary period selector (
- Data consumed:
/admin/analytics/orders-summary/admin/analytics/orders-over-time
Customers dashboard
- File:
src/admin/routes/analytics/components/CustomersDashboard.tsx - Renders:
- KPI cards (guest, registered, overall, deleted accounts)
- Dual-line chart (registered vs guest over time)
- Interactions:
- Count period selector (
all,0,7,30,90) - Graph period selector (
one_week,one_month,one_year) - Clear filter action
- Count period selector (
- Data consumed:
/admin/analytics/customers-summary/admin/analytics/customers-over-time
Models & Entities
No custom entities/models are defined by this plugin.
It reads existing Medusa entities through query/module APIs:
orderfulfillment(via order fulfillments fields)returnorder_changecustomer
Use Cases & Examples
Track order health in admin
- Use
/admin/analytics/orders-summary?days=30to monitor pending, delivered, and cancelled distribution.
- Use
Visualize order demand trends
- Use
/admin/analytics/orders-over-time?period=one_yearfor monthly trendline analysis.
- Use
Monitor customer acquisition mix
- Use
/admin/analytics/customers-over-time?period=one_monthto compare guest vs registered growth.
- Use
Operational return/exchange visibility
- Use
exchangeOrdersandreturnOrdersfrom/admin/analytics/orders-summaryto track post-purchase operations.
- Use
Review account lifecycle signals
- Use
/admin/analytics/customers-summaryto compare total/registered/guest counts and deleted accounts.
- Use
Troubleshooting
Analytics page does not appear in Admin
- Ensure plugin is registered in
medusa-config.ts. - Rebuild plugin:
npx medusa plugin:build. - Restart backend and hard refresh admin.
401/403 on analytics APIs
- These are
/admin/*routes; call with valid admin auth token/session.
Empty charts or zero counts
- Confirm store has orders/customers in selected range.
- Try broader ranges (
days=all,period=one_year).
Slow response with large datasets
- Current implementation fetches up to
take: 50000records per query. - If needed, customize aggregation strategy/pagination for very large stores.
"Failed to fetch ..." API errors
- Check backend logs for the route-specific error messages.
- Verify module availability and that core services (
ORDER,CUSTOMER) resolve correctly.
