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:

FieldTypeDescription
revenueKpiValueTotal revenue with period comparison
ordersKpiValueOrder count with period comparison
avg_order_valueKpiValueAverage order value with period comparison
inventory_healthobjectCurrent stock health snapshot
top_productsarrayTop-selling products for the period
fulfillmentobjectFulfillment method breakdown
top_customersarrayTop 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:

FieldTypeDescription
revenueKpiValueTotal revenue with period comparison
ordersKpiValueOrder count with period comparison
sales_over_timearrayDaily revenue series for the period
sales_by_sourcearrayRevenue split by source system (POS, web, dashboard)
sales_by_fulfillmentarrayRevenue split by fulfillment method
sales_by_paymentarrayRevenue 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:

FieldTypeDescription
top_productsarrayTop-selling products ranked by revenue
category_performancearrayRevenue and units sold per category
brand_performancearrayRevenue 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:

FieldTypeDescription
pending_pickupsarrayPickupSchedule rows with status pending or ready
in_transit_shipmentsarrayShipment rows with status shipped or in_transit
pending_transactionsarraySaleTransaction rows with status pending or partially_paid
open_returnsarrayReturn 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:

FieldTypeDescription
inventory_healthobjectStock-level health (in_stock, low_stock, out_of_stock counts)
movements_summaryarrayInventory movement activity for the period
dead_stockarrayItems with no movement for an extended period

GET /api/analytics/operations/fulfillment/

Fulfillment and returns summary.

Query parameters: start_date, end_date, store_id

Response data fields:

FieldTypeDescription
fulfillmentobjectFulfillment method breakdown and completion rates
returnsobjectReturn 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:

FieldTypeDescription
procurementobjectPurchase order summary for the period
supplier_performancearrayPer-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:

FieldTypeDescription
customer_summaryobjectNew vs. returning customers, average spend
top_customersarrayTop 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:

FieldTypeDescription
campaign_summaryobjectActive campaign counts and overall usage
promo_codesarrayPer-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:

FieldTypeDescription
total_appliedintegerNumber of transactions where at least one automatic promotion fired
total_discountstringSum of appliedPromotionDiscount across all matching transactions
promotionsarrayPer-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.


Was this page helpful?