Analytics - Views Documentation
Location: api/nextango/apps/analytics/views.py
Last Updated: 2026-03-06
Overview
All analytics views are function-based (@api_view(['GET'])). They accept AllowAny permission while the auth layer is being finalized. Each view assembles data from one or more domain services and returns a {meta, data} envelope.
URL Prefix
All routes mount under /api/analytics/:
GET /api/analytics/commerce/overview/
GET /api/analytics/commerce/sales/
GET /api/analytics/commerce/products/
GET /api/analytics/commerce/hourly-traffic/
GET /api/analytics/active-orders/
GET /api/analytics/operations/inventory/
GET /api/analytics/operations/fulfillment/
GET /api/analytics/operations/procurement/
GET /api/analytics/people/customers/
GET /api/analytics/people/team/
GET /api/analytics/growth/promotions/
GET /api/analytics/system/infrastructure/
Commerce Views
GET /api/analytics/commerce/overview/
Assembles a full commerce summary for a date range.
Query parameters: start_date, end_date, store_id, compare_to
Response data fields:
| Field | Type | Description |
|---|---|---|
revenue | KpiValue | Total revenue with period comparison |
orders | KpiValue | Order count with period comparison |
avg_order_value | KpiValue | Average order value with period comparison |
inventory_health | object | Current stock health snapshot |
top_products | array | Top-selling products for the period |
fulfillment | object | Fulfillment method breakdown |
top_customers | array | Top customers by spend for the period |
Source: TransactionAnalyticsService.get_sales_summary (current + comparison), InventoryAnalyticsService.get_inventory_health, ProductAnalyticsService.get_top_products, TransactionAnalyticsService.get_fulfillment_summary, CustomerAnalyticsService.get_top_customers.
GET /api/analytics/commerce/sales/
Detailed sales breakdown with time-series data.
Query parameters: start_date, end_date, store_id, compare_to
Response data fields:
| Field | Type | Description |
|---|---|---|
revenue | KpiValue | Total revenue with period comparison |
orders | KpiValue | Order count with period comparison |
sales_over_time | array | Daily revenue series for the period |
sales_by_source | array | Revenue split by source system (POS, web, dashboard) |
sales_by_fulfillment | array | Revenue split by fulfillment method |
sales_by_payment | array | Revenue split by payment method |
GET /api/analytics/commerce/products/
Product performance for a date range.
Query parameters: start_date, end_date, store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
top_products | array | Top-selling products ranked by revenue |
category_performance | array | Revenue and units sold per category |
brand_performance | array | Revenue and units sold per brand |
GET /api/analytics/commerce/hourly-traffic/
Today's transaction count per hour. Always today-scoped, no date parameters.
Query parameters: store_id
Returns exactly 24 rows (one per hour, 00–23), even for hours with zero transactions.
Response data: array of {hour: 0–23, count: N} objects.
Active Orders
GET /api/analytics/active-orders/
Live operational queue. Always real-time, no date parameters.
Query parameters: store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
pending_pickups | array | PickupSchedule rows with status pending or ready |
in_transit_shipments | array | Shipment rows with status shipped or in_transit |
pending_transactions | array | SaleTransaction rows with status pending or partially_paid |
open_returns | array | Return rows with status pending |
Pending transactions shape:
{
"id": "uuid",
"transaction_id": "TXN-001",
"status": "pending",
"total_amount": "49.99",
"expires_at": "2026-03-06T14:00:00Z",
"timestamp": "2026-03-06T13:45:00Z"
}
expires_at is null for counter-sale transactions (it applies to layaway and pay-at-pickup orders).
Store scoping: The store_id parameter accepts either the store's Django UUID or its Sanity document ID.
Operations Views
GET /api/analytics/operations/inventory/
Current inventory health and movement summary.
Query parameters: start_date, end_date, store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
inventory_health | object | Stock-level health (in_stock, low_stock, out_of_stock counts) |
movements_summary | array | Inventory movement activity for the period |
dead_stock | array | Items with no movement for an extended period |
inventory_health and dead_stock are store-scoped but not date-scoped — they reflect the current state, not a historical snapshot.
GET /api/analytics/operations/fulfillment/
Fulfillment and returns summary.
Query parameters: start_date, end_date, store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
fulfillment | object | Fulfillment method breakdown and completion rates |
returns | object | Return counts, reasons, and refund totals |
GET /api/analytics/operations/procurement/
Procurement and supplier performance. Requires the procurement app.
Query parameters: start_date, end_date
Response data fields:
| Field | Type | Description |
|---|---|---|
procurement | object | Purchase order summary for the period |
supplier_performance | array | Per-supplier delivery and quality metrics |
If the procurement app is not installed, both fields return empty ({} and []).
People Views
GET /api/analytics/people/customers/
Customer activity summary.
Query parameters: start_date, end_date, store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
customer_summary | object | New vs. returning customers, average spend |
top_customers | array | Top customers ranked by total spend |
GET /api/analytics/people/team/
Team analytics stub. Returns {"status": "not_implemented"}.
Growth Views
GET /api/analytics/growth/promotions/
Promotional campaign and promo code performance. Requires the promotions app.
Query parameters: start_date, end_date, store_id
Response data fields:
| Field | Type | Description |
|---|---|---|
campaign_summary | object | Active campaign counts and overall usage |
promo_codes | array | Per-code usage, discount total, and revenue attributed |
If the promotions app is not installed, both fields return empty.
GET /api/analytics/growth/auto-promotions/
Automatic (codeless) promotion performance via PromotionAnalyticsService.get_auto_promotion_performance(). Added v0.73.0.
Query parameters: start_date, end_date, store_id
Permission: AllowAny (consistent with other analytics growth endpoints)
Response data fields:
| Field | Type | Description |
|---|---|---|
total_applied | integer | Number of transactions where at least one automatic promotion fired |
total_discount | string | Sum of appliedPromotionDiscount across all matching transactions |
promotions | array | Per-promotion breakdown: promotion_id, name, applied_count, total_discount |
System Views
GET /api/analytics/system/infrastructure/
Sync pipeline health and system component status.
Query parameters: ?days=N (integer, 7–365, default 30)
Values below 7 are clamped to 7; values above 365 are clamped to 365.
Response data shape:
{
"webhook": {
"stats": {
"total_received": 1240,
"processed": 1228,
"failed": 12,
"retrying": 0,
"avg_processing_ms": 145.3
},
"hourly_throughput": [
{"hour": "2026-03-05", "inbound": 42, "outbound": 18, "failed": 1}
]
},
"sync": {
"inbound": {"total": 1240, "completed": 1228, "failed": 12},
"outbound": {"total": 320, "completed": 318, "failed": 2},
"combined": {"total": 1560, "failed": 14}
},
"health": {
"db": {"status": "ok"},
"redis": {"status": "ok"},
"celery": {"status": "ok", "worker_count": 2}
}
}
webhook.stats covers inbound Sanity→Django traffic only (WebhookEvent model). sync covers both directions via SyncAuditLog. hourly_throughput rows are keyed by date string (YYYY-MM-DD), named hour for frontend chart compatibility.
Celery worker_count is null and status is "unknown" when the inspect call times out or no workers respond.