Explainable customer value analytics for MoonBit event data.
moon test
moon run cmd/main///|
test "README example" {
let report = @FineRain-OI/moonbit-customer.analyze(
[
@FineRain-OI/moonbit-customer.Event::new("alice", 10, 120),
@FineRain-OI/moonbit-customer.Event::new("alice", 20, 80),
],
30,
)
inspect(report.customers[0].frequency, content="2")
debug_inspect(report.customers[0].segment, content="Loyal")
}benchmark: cases=1200, customers=240, value=301680, retention_rows=1080
benchmark checksum: 312524015moon check --deny-warn
moon test --deny-warn
moon test --target native --deny-warnpub struct AllocationLine {
campaign : String
customers : Int
spend : Int
expected_value : Int
expected_roi_percent : Int
}pub struct AllocationPlan {
lines : Array[AllocationLine]
customers : Int
spend : Int
expected_value : Int
remaining_budget : Int
}pub struct AllocationRequest {
campaign : String
audience : Int
cost_per_customer : Int
expected_value_per_customer : Int
priority : Int
}fn AllocationRequest::new(campaign : String, audience : Int, cost_per_customer : Int, expected_value_per_customer : Int, priority : Int) -> AllocationRequestpub struct BenchmarkCase {
customer_id : String
day : Int
amount : Int
channel : String
}pub struct CampaignExposure {
campaign : String
customer_id : String
day : Int
cost : Int
}fn CampaignExposure::new(campaign : String, customer_id : String, day : Int, cost : Int) -> CampaignExposurepub struct CampaignOutcome {
customer_id : String
day : Int
value : Int
}pub struct CampaignResult {
campaign : String
exposed_customers : Int
converted_customers : Int
conversion_percent : Int
attributed_value : Int
cost : Int
roi_percent : Int
average_value : Int
}pub struct ChannelCredit {
channel : String
touches : Int
credited_value : Int
cost : Int
roi_percent : Int
}pub struct CohortRow {
cohort_day : Int
period : Int
cohort_size : Int
active_customers : Int
retention_percent : Int
}pub struct CustomerInsight {
customer_id : String
scores : ScoreVector
segment : Segment
churn : ChurnScore
lifetime : ValueEstimate
priority : Int
actions : Array[String]
}pub struct CustomerMetrics {
customer_id : String
first_day : Int
last_day : Int
recency : Int
frequency : Int
monetary : Int
r_score : Int
f_score : Int
m_score : Int
segment : Segment
explanation : String
}pub struct DailyValue {
day : Int
orders : Int
customers : Int
value : Int
average_order : Int
}pub struct Event {
customer_id : String
day : Int
amount : Int
}pub struct ExperimentArm {
experiment : String
arm : String
customers : Int
conversions : Int
value : Int
}fn ExperimentArm::new(experiment : String, arm : String, customers : Int, conversions : Int, value : Int) -> ExperimentArmpub struct ExperimentResult {
experiment : String
arm : String
conversion_percent : Int
average_value : Int
lift_percent : Int
is_winner : Bool
}pub struct ForecastConfig {
window : Int
horizon : Int
safety_percent : Int
}pub struct ForecastPoint {
period : Int
prediction : Int
lower_bound : Int
upper_bound : Int
}pub struct ForecastScore {
mean_absolute_error : Int
bias : Int
observations : Int
}pub struct FunnelRow {
name : String
entered : Int
conversion_percent : Int
drop_off : Int
}pub struct JourneySnapshot {
customer_id : String
stage : JourneyStage
day : Int
value : Int
reason : String
}pub struct NumericSummary {
count : Int
total : Int
minimum : Int
maximum : Int
mean : Int
median : Int
lower_quartile : Int
upper_quartile : Int
}pub struct Playbook {
code : String
priority : Int
max_recency : Int
min_frequency : Int
action : String
rationale : String
}pub struct ProductEvent {
customer_id : String
product_id : String
day : Int
amount : Int
quantity : Int
}fn ProductEvent::new(customer_id : String, product_id : String, day : Int, amount : Int, quantity : Int) -> ProductEventpub struct ProductMetric {
product_id : String
customers : Int
orders : Int
revenue : Int
units : Int
repeat_rate : Int
average_order : Int
}pub struct ProductPair {
left : String
right : String
shared_customers : Int
support_percent : Int
}pub struct QualityReport {
accepted : Array[Event]
findings : Array[QualityFinding]
unique_customers : Int
total_value : Int
}pub struct ReactivationCandidate {
customer_id : String
recency : Int
frequency : Int
monetary : Int
priority : Int
reason : String
}pub struct RetentionPoint {
period : Int
cohort_size : Int
active_customers : Int
retention_percent : Int
value : Int
}pub struct RetentionSummary {
points : Array[RetentionPoint]
starting_value : Int
ending_value : Int
value_change_percent : Int
retained_customers : Int
}pub struct ScoreVector {
recency : Int
frequency : Int
monetary : Int
composite : Int
}pub struct ScoringConfig {
at_risk_days : Int
dormant_days : Int
repeat_bonus : Int
high_value_threshold : Int
}pub struct Touchpoint {
customer_id : String
channel : String
day : Int
cost : Int
}pub struct TrendSummary {
direction : TrendDirection
first_value : Int
last_value : Int
change_percent : Int
}pub struct ValueChange {
baseline : Int
current : Int
absolute : Int
percent : Int
direction : TrendDirection
}pub struct ValueEstimate {
average_order : Int
repeat_interval : Int
expected_orders : Int
estimated_value : Int
}fn allocate_budget(requests : Array[AllocationRequest], budget : Int, max_customers : Int) -> AllocationPlanfn analyze_attribution(events : Array[Event], touches : Array[Touchpoint], model : AttributionModel) -> AttributionReportfn benchmark_checksum() -> Intfn customers_in_stage(snapshots : Array[JourneySnapshot], stage : JourneyStage) -> Array[JourneySnapshot]fn evaluate_campaign(campaign : String, exposures : Array[CampaignExposure], outcomes : Array[CampaignOutcome], window : Int) -> CampaignResultfn evaluate_campaigns(campaigns : Array[String], exposures : Array[CampaignExposure], outcomes : Array[CampaignOutcome], window : Int) -> Array[CampaignResult]fn evaluate_experiment(control : ExperimentArm, treatments : Array[ExperimentArm]) -> Array[ExperimentResult]fn journey_transitions(before : Array[JourneySnapshot], after : Array[JourneySnapshot]) -> Array[JourneyTransition]fn reactivation_candidates(report : Report, as_of : Int, minimum_recency : Int) -> Array[ReactivationCandidate]fn run_benchmark_workload() -> (Int, Int, Int, Int)fn value_retention_curve(events : Array[Event], cohort_day : Int, period_width : Int, periods : Int) -> RetentionSummaryInstall
Download zipExplainable customer value analytics for MoonBit event data.