Reporting Service
The Reporting Service (/reporting/) provides read-only analytical views for promotion performance, budget utilization, coupon analytics, and A/B test results.
Overview
| Property | Value |
|---|---|
| Base Path | /reporting/ |
| Protocol | OData V4 |
| Operations | Read-only (GET only) |
| Auth | Admin, PromotionManager, or BudgetManager role |
| CSV Export | Supported via exportCsv action |
Report Entities
PromotionPerformance
Aggregated promotion KPIs from calculation logs.
GET /reporting/PromotionPerformance
GET /reporting/PromotionPerformance(<promotionId>)
| Field | Type | Description |
|---|---|---|
| promotionId | UUID | Promotion identifier |
| promotionName | String | Promotion name |
| promotionStatus | String | Current status |
| promotionType | String | Promotion type |
| applicationsCount | Integer | Number of times applied |
| totalDiscountGiven | Decimal | Total discount amount |
| avgDiscountPerTx | Decimal | Average discount per transaction |
| firstAppliedAt | DateTime | First application timestamp |
| lastAppliedAt | DateTime | Last application timestamp |
StakeholderCostBreakdown
Cost share attributed to each stakeholder per budget.
GET /reporting/StakeholderCostBreakdown
| Field | Type | Description |
|---|---|---|
| stakeholderId | UUID | Stakeholder identifier |
| budgetId | UUID | Budget identifier |
| stakeholderName | String | Stakeholder name |
| stakeholderType | String | Stakeholder type |
| budgetName | String | Budget name |
| sharePercentage | Decimal | Cost share percentage |
| totalBudgetCost | Decimal | Total budget cost |
| stakeholderCost | Decimal | Stakeholder's cost portion |
| contributionsTotal | Decimal | Total contributions made |
| netBalance | Decimal | Net balance |
| linkedPromotions | String | Associated promotions |
BudgetUtilization
Consumption vs total for each budget with burn rate projections.
GET /reporting/BudgetUtilization
GET /reporting/BudgetUtilization(<budgetId>)
| Field | Type | Description |
|---|---|---|
| budgetId | UUID | Budget identifier |
| budgetName | String | Budget name |
| status | String | Budget status |
| totalAmount | Decimal | Total budget amount |
| consumedAmount | Decimal | Amount consumed |
| remainingAmount | Decimal | Amount remaining |
| currency | String | Currency code |
| utilizationPct | Decimal | Utilization percentage |
| dailyBurnRate | Decimal | Average daily consumption |
| projectedExhaustion | DateTime | Projected exhaustion date |
| transactionCount | Integer | Number of transactions |
| linkedPromotions | Integer | Number of linked promotions |
CouponAnalytics
Per-coupon-type analytics.
GET /reporting/CouponAnalytics
GET /reporting/CouponAnalytics(<couponTypeId>)
| Field | Type | Description |
|---|---|---|
| couponTypeId | UUID | Coupon type identifier |
| couponTypeName | String | Coupon type name |
| totalIssued | Integer | Total codes issued |
| totalActive | Integer | Currently active codes |
| totalReserved | Integer | Currently reserved codes |
| totalRedeemed | Integer | Total redeemed codes |
| totalExpired | Integer | Expired codes |
| totalCancelled | Integer | Cancelled codes |
| redemptionRate | Decimal | Redemption rate percentage |
ABTestResults
Compares control and experiment groups for A/B test promotions across two metrics, each with its own significance test:
- Revenue per basket (headline metric, owner decision 2026-06-12) — average basket value, uplift, and a Welch t-test (
revenueTStatistic,revenuePValue,revenueIsSignificant). - Conversion rate (secondary context) — control vs experiment conversion rate, uplift, and a chi-squared test (
chiSquared,pValue,isSignificant).
GET /reporting/ABTestResults
GET /reporting/ABTestResults(<promotionId>)
| Field | Type | Description |
|---|---|---|
| promotionId | UUID | Promotion identifier |
| promotionName | String | Promotion name |
| controlAvgBasket | Decimal | Control group average revenue per basket |
| experimentAvgBasket | Decimal | Experiment group average revenue per basket |
| revenueUplift | Decimal | Revenue-per-basket uplift (experiment vs control) — headline metric |
| revenueTStatistic | Decimal | Welch t-test statistic for the revenue-per-basket difference |
| revenuePValue | Decimal | Welch t-test p-value for revenue per basket |
| revenueIsSignificant | Boolean | Whether the revenue-per-basket uplift is statistically significant (Welch t-test) |
| controlConversionRate | Decimal | Control group conversion rate |
| experimentConversionRate | Decimal | Experiment group conversion rate |
| uplift | Decimal | Conversion-rate uplift (experiment vs control) |
| chiSquared | Decimal | Chi-squared statistic for the conversion-rate difference |
| pValue | Decimal | Chi-squared p-value for conversion rate |
| isSignificant | Boolean | Whether the conversion-rate uplift is statistically significant (chi-squared) |
Detail Chart Entities
Pre-aggregated data for promotion performance charts:
| Entity | Description |
|---|---|
PromotionUsageByDay | Daily application counts and discounts |
PromotionUsageByHour | Hourly application counts |
PromotionUsageByDayOfWeek | Day-of-week application patterns |
PromotionDiscountDistribution | Discount amount distribution buckets |
PromotionTopPosGroups | Top-performing POS groups per promotion |
PromotionTopArticles | Top articles per promotion |
Killer-Feature ROI Entities
The service exposes per-feature ROI projections (emission count vs conversion count) backing the Killer Feature ROI dashboard.
| Entity | Feature |
|---|---|
ThresholdGapROI | Threshold-gap nudge |
NearMissROI | Near-miss |
SavingsSummaryROI | Savings summary |
ProgressiveNudgesROI | Progressive nudges |
ABTestROI | A/B testing |
AggregatorRuns | KFROI aggregator run log (read-only) |
Per-feature daily aggregates are also queryable as first-class OData entities:
DailyThresholdGapAggregates, DailyNearMissAggregates,
DailySavingsSummaryAggregates, DailyNudgesAggregates,
DailyABTestAggregates, DailyFreeItemAggregates.
GET /reporting/ThresholdGapROI
GET /reporting/AggregatorRuns
GET /reporting/DailyThresholdGapAggregates
Post-Mortem Analytics
Curated KPI projections surfaced after a promotion ends — they drive the post-mortem dashboards the user guide Phase 5 relies on.
| Entity | Description |
|---|---|
PromotionUpliftAnalysis | In-promo daily revenue minus a baseline (uplift absolute + percentage) |
PromotionPostMortemTopStores | Top 10 POS groups by total discount |
PromotionPostMortemTopArticles | Top 10 articles by total discount |
PromotionHourOfDay | Hour-of-day x day-of-week heatmap (168 buckets) |
PromotionAbComparison | A/B comparison (one row for A/B promotions, else empty) |
PilotComparisonReports | Pilot vs control comparison report (revenue, basket size, tx count) |
GET /reporting/PromotionUpliftAnalysis(<promotionId>)
GET /reporting/PromotionPostMortemTopStores?$filter=promotion_ID eq <promotionId>
Audit Trail
Read-only access to transaction calculation logs:
GET /reporting/CalculationLogs
GET /reporting/CalculationLogs(<ID>)
GET /reporting/CalculationLogs(<ID>)/items
GET /reporting/CalculationLogs(<ID>)/promotions
CSV Export
POST /reporting/exportCsv
Request:
{
"reportType": "promotionPerformance",
"dateFrom": "2026-01-01T00:00:00Z",
"dateTo": "2026-03-31T23:59:59Z",
"promotionId": "uuid (optional)",
"stakeholderId": "uuid (optional)"
}
Supported reportType values: promotionPerformance, stakeholderCost, budgetUtilization, couponAnalytics, abTestResults
Response:
{
"filename": "promotion-performance.csv",
"contentType": "text/csv",
"data": "promotionId,promotionName,..."
}
The filename is fixed per report type (kebab-case, no date suffix): promotion-performance.csv, stakeholder-cost.csv, budget-utilization.csv, coupon-analytics.csv, ab-test-results.csv.
Authorization
| Role | Access |
|---|---|
| Admin | Full read access to all reports |
| PromotionManager | Read access to all reports |
| BudgetManager | Read access to all reports |