make-mp-data 3.0.2 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dungeons/adspend.js +13 -26
- package/dungeons/anon.js +1 -1
- package/dungeons/array-of-object-lookup.js +1 -2
- package/dungeons/benchmark-heavy.js +5 -6
- package/dungeons/benchmark-light.js +13 -28
- package/dungeons/big.js +3 -3
- package/dungeons/business.js +11 -12
- package/dungeons/complex.js +1 -2
- package/dungeons/copilot.js +8 -6
- package/dungeons/education.js +21 -22
- package/dungeons/experiments.js +4 -5
- package/dungeons/fintech.js +25 -26
- package/dungeons/foobar.js +1 -1
- package/dungeons/food.js +24 -25
- package/dungeons/funnels.js +2 -2
- package/dungeons/gaming.js +39 -40
- package/dungeons/media.js +30 -31
- package/dungeons/mil.js +17 -18
- package/dungeons/mirror.js +2 -3
- package/dungeons/retention-cadence.js +1 -2
- package/dungeons/rpg.js +42 -43
- package/dungeons/sanity.js +1 -2
- package/dungeons/sass.js +32 -33
- package/dungeons/scd.js +3 -4
- package/dungeons/simple.js +13 -14
- package/dungeons/social.js +27 -28
- package/dungeons/soup-test.js +52 -0
- package/dungeons/streaming.js +17 -18
- package/dungeons/student-teacher.js +0 -1
- package/dungeons/text-generation.js +0 -1
- package/dungeons/user-agent.js +1 -2
- package/index.js +18 -6
- package/lib/core/config-validator.js +22 -33
- package/lib/core/context.js +6 -3
- package/lib/generators/events.js +13 -10
- package/lib/generators/funnels.js +7 -4
- package/lib/generators/scd.js +29 -17
- package/lib/generators/text.js +18 -12
- package/lib/orchestrators/mixpanel-sender.js +26 -38
- package/lib/orchestrators/user-loop.js +68 -15
- package/lib/templates/phrases.js +8 -5
- package/lib/utils/function-registry.js +17 -0
- package/lib/utils/utils.js +15 -84
- package/package.json +3 -1
- package/types.d.ts +86 -19
- package/lib/templates/verbose-schema.js +0 -272
- package/lib/utils/chart.js +0 -210
package/types.d.ts
CHANGED
|
@@ -12,75 +12,123 @@ export type ValueValid = Primitives | ValueValid[] | (() => ValueValid);
|
|
|
12
12
|
* main config object for the entire data generation
|
|
13
13
|
*/
|
|
14
14
|
export interface Dungeon {
|
|
15
|
-
//
|
|
15
|
+
// ── Core Parameters ──
|
|
16
|
+
/** Mixpanel project token. If provided, data will be imported to Mixpanel after generation. */
|
|
16
17
|
token?: string;
|
|
18
|
+
/** RNG seed for reproducible output. Same seed + concurrency=1 = identical data. */
|
|
17
19
|
seed?: string;
|
|
20
|
+
/** Number of days the dataset spans (from "now" looking backward). Default: 30 */
|
|
18
21
|
numDays?: number;
|
|
22
|
+
/** Explicit start of dataset window (unix seconds). Alternative to numDays. */
|
|
19
23
|
epochStart?: number;
|
|
24
|
+
/** Explicit end of dataset window (unix seconds). Defaults to FIXED_NOW. */
|
|
20
25
|
epochEnd?: number;
|
|
26
|
+
/** Target total number of events to generate across all users. */
|
|
21
27
|
numEvents?: number;
|
|
28
|
+
/** Number of unique users to generate. */
|
|
22
29
|
numUsers?: number;
|
|
30
|
+
/** Output format for files written to disk. */
|
|
23
31
|
format?: "csv" | "json" | "parquet" | string;
|
|
32
|
+
/** Mixpanel data residency region. */
|
|
24
33
|
region?: "US" | "EU";
|
|
34
|
+
/** User generation concurrency. Default: 1. Values > 1 break seed reproducibility and provide no performance benefit (CPU-bound). */
|
|
25
35
|
concurrency?: number;
|
|
36
|
+
/** Number of records before auto-flushing to disk. Prevents OOM for large datasets. Default: 1,000,000 */
|
|
26
37
|
batchSize?: number;
|
|
27
38
|
|
|
39
|
+
// ── Mixpanel Import Credentials (for SCD import) ──
|
|
28
40
|
serviceAccount?: string;
|
|
29
41
|
serviceSecret?: string;
|
|
30
42
|
projectId?: string;
|
|
31
43
|
|
|
32
|
-
//
|
|
44
|
+
// ── Identifiers ──
|
|
45
|
+
/** Dataset name prefix for output files. Auto-generated if not set. */
|
|
33
46
|
name?: string;
|
|
34
47
|
|
|
35
|
-
//
|
|
48
|
+
// ── Feature Switches ──
|
|
49
|
+
/** If true, users have no distinct_id (anonymous-only tracking). */
|
|
36
50
|
isAnonymous?: boolean;
|
|
51
|
+
/** If true, user profiles include avatar URLs. */
|
|
37
52
|
hasAvatar?: boolean;
|
|
53
|
+
/** If true, events include geo properties (city, region, country, lat/lng). */
|
|
38
54
|
hasLocation?: boolean;
|
|
55
|
+
/** If true, events include UTM campaign properties. */
|
|
39
56
|
hasCampaigns?: boolean;
|
|
57
|
+
/** If true, generates ad spend data (impressions, clicks, cost). */
|
|
40
58
|
hasAdSpend?: boolean;
|
|
59
|
+
/** If true, device pool includes iOS devices. */
|
|
41
60
|
hasIOSDevices?: boolean;
|
|
61
|
+
/** If true, device pool includes Android devices. */
|
|
42
62
|
hasAndroidDevices?: boolean;
|
|
63
|
+
/** If true, device pool includes desktop devices. */
|
|
43
64
|
hasDesktopDevices?: boolean;
|
|
65
|
+
/** If true, events include browser properties. */
|
|
44
66
|
hasBrowser?: boolean;
|
|
67
|
+
/** If true (default), writes output files to ./data/. Can also be a directory path string. */
|
|
45
68
|
writeToDisk?: boolean | string;
|
|
69
|
+
/** If true, gzip-compresses output files. */
|
|
46
70
|
gzip?: boolean;
|
|
71
|
+
/** If true, prints progress to stdout during generation. */
|
|
47
72
|
verbose?: boolean;
|
|
73
|
+
/** If true, users get anonymous device IDs in addition to distinct_id. */
|
|
48
74
|
hasAnonIds?: boolean;
|
|
75
|
+
/** If true, users get session IDs attached to events. */
|
|
49
76
|
hasSessionIds?: boolean;
|
|
77
|
+
/** If true, auto-generates funnels from the events array in addition to any explicit funnels. */
|
|
50
78
|
alsoInferFunnels?: boolean;
|
|
51
|
-
|
|
79
|
+
/** Restrict all location data to a single country (e.g., "US", "GB"). */
|
|
52
80
|
singleCountry?: string;
|
|
81
|
+
/** If true, stops generation at exactly numEvents (forces concurrency=1). Without this, event count is approximate. */
|
|
53
82
|
strictEventCount?: boolean;
|
|
83
|
+
/** Internal flag for UI-triggered jobs (affects SCD credential handling). */
|
|
54
84
|
isUIJob?: boolean;
|
|
55
85
|
|
|
56
|
-
//
|
|
57
|
-
|
|
86
|
+
// ── Data Models ──
|
|
87
|
+
/** Event definitions: names, weights, properties, and behavioral flags. */
|
|
88
|
+
events?: EventConfig[];
|
|
89
|
+
/** Properties that appear on EVERY event (e.g., platform, app_version). */
|
|
58
90
|
superProps?: Record<string, ValueValid>;
|
|
91
|
+
/** Funnel definitions: conversion sequences, rates, ordering strategies. */
|
|
59
92
|
funnels?: Funnel[];
|
|
93
|
+
/** User profile properties set once per user. */
|
|
60
94
|
userProps?: Record<string, ValueValid>;
|
|
95
|
+
/** Slowly Changing Dimension properties: time-series mutations of user/group attributes. */
|
|
61
96
|
scdProps?: Record<string, SCDProp>;
|
|
97
|
+
/** Mirror dataset definitions: create transformed copies of event data. */
|
|
62
98
|
mirrorProps?: Record<string, MirrorProps>;
|
|
63
|
-
|
|
99
|
+
/** Group analytics keys. Format: [key, numGroups] or [key, numGroups, [associatedEvents]]. */
|
|
100
|
+
groupKeys?: [string, number][] | [string, number, string[]][];
|
|
101
|
+
/** Properties for each group key's entities. */
|
|
64
102
|
groupProps?: Record<string, Record<string, ValueValid>>;
|
|
103
|
+
/** Group-level events (stub — not yet implemented). */
|
|
65
104
|
groupEvents?: GroupEventConfig[];
|
|
105
|
+
/** Lookup table definitions for dimension tables. */
|
|
66
106
|
lookupTables?: LookupTableSchema[];
|
|
107
|
+
/** TimeSoup configuration: controls the temporal distribution of events (peaks, deviation, mean). */
|
|
67
108
|
soup?: soup;
|
|
109
|
+
/** Hook function called on every data point. The primary mechanism for engineering deliberate trends and patterns. */
|
|
68
110
|
hook?: Hook<any>;
|
|
69
111
|
|
|
70
|
-
|
|
112
|
+
/** Allow arbitrary additional properties on the config. */
|
|
71
113
|
[key: string]: any;
|
|
72
114
|
|
|
73
|
-
//
|
|
115
|
+
// ── Distribution Controls ──
|
|
116
|
+
/** Percentage of users whose account creation falls within the dataset window (vs. pre-existing). Default: 15 */
|
|
74
117
|
percentUsersBornInDataset?: number;
|
|
75
118
|
/** Bias toward recent birth dates for users born in dataset (0 = uniform, 1 = heavily recent). Default: 0.3 */
|
|
76
119
|
bornRecentBias?: number;
|
|
77
120
|
}
|
|
78
121
|
|
|
79
122
|
export type SCDProp = {
|
|
123
|
+
/** Entity type this SCD applies to. "user" for user profiles; use a group key (e.g., "company_id") for group SCDs. Default: "user" */
|
|
80
124
|
type?: string | "user" | "company_id" | "team_id" | "department_id";
|
|
125
|
+
/** How often the property mutates. Default: "day" */
|
|
81
126
|
frequency?: "day" | "week" | "month" | "year";
|
|
127
|
+
/** Array of possible values, or a function that returns values. */
|
|
82
128
|
values: ValueValid;
|
|
129
|
+
/** "fixed" = mutations at clean boundaries (start of day/week/month/year). "fuzzy" = mutations at any time. Default: "fuzzy" */
|
|
83
130
|
timing?: "fixed" | "fuzzy";
|
|
131
|
+
/** Maximum number of mutations per entity. Default: 10 */
|
|
84
132
|
max?: number;
|
|
85
133
|
};
|
|
86
134
|
|
|
@@ -88,13 +136,25 @@ export type SCDProp = {
|
|
|
88
136
|
* the soup is a set of parameters that determine the distribution of events over time
|
|
89
137
|
*/
|
|
90
138
|
type soup = {
|
|
139
|
+
/** Controls clustering tightness. Higher = tighter peaks. Default: 2 */
|
|
91
140
|
deviation?: number;
|
|
141
|
+
/** Number of time clusters to distribute events across. Default: dynamic (numDays/7, minimum 5) */
|
|
92
142
|
peaks?: number;
|
|
143
|
+
/** Offset for the normal distribution center within each peak. Default: 0 */
|
|
93
144
|
mean?: number;
|
|
94
145
|
};
|
|
95
146
|
|
|
96
147
|
/**
|
|
97
|
-
*
|
|
148
|
+
* Hook types and when they fire (in order per user):
|
|
149
|
+
* - "user" — user profile object (mutate in-place, return ignored)
|
|
150
|
+
* - "scd-pre" — array of SCD entries (mutate in-place OR return new array to replace)
|
|
151
|
+
* - "funnel-pre" — funnel config object (mutate conversionRate, timeToConvert, etc. in-place)
|
|
152
|
+
* - "event" — single event with FLAT properties (return value replaces event)
|
|
153
|
+
* - "funnel-post" — array of generated funnel events (mutate in-place, splice to inject)
|
|
154
|
+
* - "everything" — array of ALL events for one user (return array to replace; meta.profile available)
|
|
155
|
+
*
|
|
156
|
+
* Storage-only hooks (fire during hookPush, not in generators):
|
|
157
|
+
* - "ad-spend", "group", "mirror", "lookup"
|
|
98
158
|
*/
|
|
99
159
|
export type hookTypes =
|
|
100
160
|
| "event"
|
|
@@ -113,7 +173,10 @@ export type hookTypes =
|
|
|
113
173
|
| "";
|
|
114
174
|
|
|
115
175
|
/**
|
|
116
|
-
*
|
|
176
|
+
* A hook function that receives every piece of data as it flows through the pipeline.
|
|
177
|
+
* @param record - The data being processed (event, profile, array of events, etc.)
|
|
178
|
+
* @param type - Which hook type is firing
|
|
179
|
+
* @param meta - Contextual metadata (varies by type; "everything" includes meta.profile and meta.scd)
|
|
117
180
|
*/
|
|
118
181
|
export type Hook<T> = (record: any, type: hookTypes, meta: any) => T;
|
|
119
182
|
|
|
@@ -199,6 +262,7 @@ export interface Context {
|
|
|
199
262
|
FIXED_NOW: number;
|
|
200
263
|
FIXED_BEGIN?: number;
|
|
201
264
|
TIME_SHIFT_SECONDS: number;
|
|
265
|
+
MAX_TIME: number;
|
|
202
266
|
|
|
203
267
|
// State update methods
|
|
204
268
|
incrementOperations(): void;
|
|
@@ -223,14 +287,24 @@ export interface Context {
|
|
|
223
287
|
* how we define events and their properties
|
|
224
288
|
*/
|
|
225
289
|
export interface EventConfig {
|
|
290
|
+
/** The event name (e.g., "page viewed", "purchase completed"). */
|
|
226
291
|
event?: string;
|
|
292
|
+
/** Relative frequency weight (1-10). Higher = more likely to be selected. Used for both standalone event selection and funnel sequence building. Default: 1 */
|
|
227
293
|
weight?: number;
|
|
294
|
+
/** Properties to attach to this event type. Values can be arrays (random pick), functions, or primitives. */
|
|
228
295
|
properties?: Record<string, ValueValid>;
|
|
296
|
+
/** If true, this is the user's first-ever event (e.g., "sign up"). Used to create onboarding funnels. */
|
|
229
297
|
isFirstEvent?: boolean;
|
|
298
|
+
/** If true, generating this event signals the user has churned. The user stops producing further events unless returnLikelihood allows them to come back. */
|
|
230
299
|
isChurnEvent?: boolean;
|
|
300
|
+
/** Probability (0-1) that a churned user returns and continues generating events. 0 = permanent churn, 1 = always returns. Only used when isChurnEvent is true. Default: 0 */
|
|
301
|
+
returnLikelihood?: number;
|
|
302
|
+
/** If true, this event is automatically prepended 15 seconds before each funnel sequence (e.g., "$session_started"). */
|
|
231
303
|
isSessionStartEvent?: boolean;
|
|
304
|
+
/** Internal: timing offset in milliseconds (set by funnel system, not user-configured). */
|
|
232
305
|
relativeTimeMs?: number;
|
|
233
|
-
|
|
306
|
+
/** If true, this event is excluded from auto-generated funnels (inferFunnels and catch-all). Use for system events that shouldn't appear in conversion sequences. */
|
|
307
|
+
isStrictEvent?: boolean;
|
|
234
308
|
}
|
|
235
309
|
|
|
236
310
|
export interface GroupEventConfig extends EventConfig {
|
|
@@ -297,13 +371,6 @@ export interface Funnel {
|
|
|
297
371
|
| "interrupted"
|
|
298
372
|
| string;
|
|
299
373
|
|
|
300
|
-
/**
|
|
301
|
-
* todo: implement this
|
|
302
|
-
* if set, the funnel might be the last thing the user does
|
|
303
|
-
* ^ the numerical value is the likelihood that the user will churn
|
|
304
|
-
* todo: allow for users to be resurrected
|
|
305
|
-
*/
|
|
306
|
-
isChurnFunnel?: void | number;
|
|
307
374
|
/**
|
|
308
375
|
* the likelihood that a user will convert (0-100%)
|
|
309
376
|
*/
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview this is a highly verbose schema for a dungeon that shows all the options available
|
|
3
|
-
* and how they might be implemented with extensive comments so an AI can understand it
|
|
4
|
-
* it is not meant to be used as a template, but rather as a reference for how to create a dungeon
|
|
5
|
-
* it is also used as a test for the AI to see if it can generate a dungeon with the same structure
|
|
6
|
-
*
|
|
7
|
-
* IMPORTANT: This file uses the NEW JSON format for function calls with "functionName" and "args"
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import Chance from "chance";
|
|
13
|
-
const chance = new Chance();
|
|
14
|
-
import dayjs from "dayjs";
|
|
15
|
-
import utc from "dayjs/plugin/utc.js";
|
|
16
|
-
dayjs.extend(utc);
|
|
17
|
-
import "dotenv/config";
|
|
18
|
-
import { weighNumRange, range, date, initChance, exhaust, integer, decimal, odds } from "../utils/utils.js";
|
|
19
|
-
const { NODE_ENV = "unknown" } = process.env;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/** @type {import("../../types.js").Dungeon} */
|
|
23
|
-
//SPLIT HERE
|
|
24
|
-
const DUNGEON = {
|
|
25
|
-
/**
|
|
26
|
-
* ⚠️ IMPORTANT NOTE ABOUT THIS EXAMPLE:
|
|
27
|
-
* This is a comprehensive example showing ALL possible features.
|
|
28
|
-
* Most dungeons will NOT need all these features, especially:
|
|
29
|
-
* - Groups (groupKeys, groupProps) - ONLY for B2B/SaaS scenarios
|
|
30
|
-
* - SCDs - ONLY when properties change over time
|
|
31
|
-
*
|
|
32
|
-
* Focus on the REQUIRED fields: events, funnels, superProps, userProps
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* events are the core building blocks of the dungeon
|
|
37
|
-
* each event has a name, a weight, and properties
|
|
38
|
-
* the weight determines how often the event occurs relative to other events
|
|
39
|
-
* properties are the data associated with the event
|
|
40
|
-
* they can be simple values or functions that return a value
|
|
41
|
-
* we have a few built-in functions to help you generate data
|
|
42
|
-
* you MUST create events for every dungeon
|
|
43
|
-
*
|
|
44
|
-
* IMPORTANT: All function calls use the new JSON format with functionName and args
|
|
45
|
-
*/
|
|
46
|
-
events: [
|
|
47
|
-
{
|
|
48
|
-
event: "checkout",
|
|
49
|
-
weight: 2,
|
|
50
|
-
properties: {
|
|
51
|
-
amount: { "functionName": "weighNumRange", "args": [5, 500, 0.25] }, // weighted random number in range
|
|
52
|
-
currency: ["USD", "CAD", "EUR", "BTC", "ETH", "JPY"],
|
|
53
|
-
coupon: ["none", "none", "none", "none", "10%OFF", "20%OFF", "10%OFF", "20%OFF", "30%OFF", "40%OFF", "50%OFF"],
|
|
54
|
-
numItems: { "functionName": "weighNumRange", "args": [1, 10] },
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
event: "add to cart",
|
|
59
|
-
weight: 4,
|
|
60
|
-
properties: {
|
|
61
|
-
amount: { "functionName": "weighNumRange", "args": [5, 500, 0.25] },
|
|
62
|
-
rating: { "functionName": "weighNumRange", "args": [1, 5] },
|
|
63
|
-
reviews: { "functionName": "weighNumRange", "args": [0, 35] },
|
|
64
|
-
isFeaturedItem: [true, false, false],
|
|
65
|
-
itemCategory: ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"],
|
|
66
|
-
dateItemListed: { "functionName": "date", "args": [30, true, "YYYY-MM-DD"] } // date in the last 30 days
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
event: "page view",
|
|
71
|
-
weight: 10,
|
|
72
|
-
properties: {
|
|
73
|
-
page: ["/", "/", "/help", "/account", "/watch", "/listen", "/product", "/people", "/peace"],
|
|
74
|
-
utm_source: ["$organic", "$organic", "$organic", "$organic", "google", "google", "google", "facebook", "facebook", "twitter", "linkedin"],
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
event: "watch video",
|
|
79
|
-
weight: 8,
|
|
80
|
-
properties: {
|
|
81
|
-
videoCategory: ["funny", "educational", "inspirational", "music", "news", "sports", "cooking", "DIY", "travel", "gaming"],
|
|
82
|
-
isFeaturedItem: [true, false, false],
|
|
83
|
-
watchTimeSec: { "functionName": "weighNumRange", "args": [10, 600, 0.25] },
|
|
84
|
-
quality: ["2160p", "1440p", "1080p", "720p", "480p", "360p", "240p"],
|
|
85
|
-
format: ["mp4", "avi", "mov", "mpg"],
|
|
86
|
-
uploader_id: { "functionName": "chance.guid", "args": [] } // Using chance.js library with dot notation
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
event: "view item",
|
|
91
|
-
weight: 8,
|
|
92
|
-
properties: {
|
|
93
|
-
isFeaturedItem: [true, false, false],
|
|
94
|
-
itemCategory: ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"],
|
|
95
|
-
dateItemListed: { "functionName": "date", "args": [30, true, "YYYY-MM-DD"] }
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
event: "save item",
|
|
100
|
-
weight: 5,
|
|
101
|
-
properties: {
|
|
102
|
-
isFeaturedItem: [true, false, false],
|
|
103
|
-
itemCategory: ["Books", "Movies", "Music", "Games", "Electronics", "Computers", "Smart Home", "Home", "Garden", "Pet", "Beauty", "Health", "Toys", "Kids", "Baby", "Handmade", "Sports", "Outdoors", "Automotive", "Industrial", "Entertainment", "Art", "Food", "Appliances", "Office", "Wedding", "Software"],
|
|
104
|
-
dateItemListed: { "functionName": "date", "args": [30, true, "YYYY-MM-DD"] },
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
event: "sign up",
|
|
109
|
-
isFirstEvent: true,
|
|
110
|
-
weight: 1,
|
|
111
|
-
properties: {
|
|
112
|
-
wasReferred: [true, false, false, false],
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
event: "search",
|
|
117
|
-
weight: 6,
|
|
118
|
-
properties: {
|
|
119
|
-
query: { "functionName": "chance.word", "args": [] },
|
|
120
|
-
resultsFound: { "functionName": "weighNumRange", "args": [0, 100, 0.25] },
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
event: "remove from cart",
|
|
125
|
-
weight: 1,
|
|
126
|
-
properties: {
|
|
127
|
-
amount: { "functionName": "weighNumRange", "args": [5, 500, 0.25] },
|
|
128
|
-
reason: ["changed mind", "too expensive", "found better", "not needed"],
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
event: "share item",
|
|
133
|
-
weight: 2,
|
|
134
|
-
properties: {
|
|
135
|
-
medium: ["email", "facebook", "twitter", "whatsapp", "sms", "slack"],
|
|
136
|
-
recipient_count: { "functionName": "weighNumRange", "args": [1, 10] },
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
event: "session end",
|
|
141
|
-
weight: 1
|
|
142
|
-
}
|
|
143
|
-
],
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* superProps are properties that are added to EVERY event
|
|
147
|
-
* they can be simple values or functions that return a value
|
|
148
|
-
* the random values will be chosen for each event
|
|
149
|
-
* you MUST create superProps for every dungeon
|
|
150
|
-
*/
|
|
151
|
-
superProps: {
|
|
152
|
-
plan: ["free", "free", "free", "plus", "plus", "pro"], // arrays are randomly sampled from
|
|
153
|
-
// using arrow functions with the new format
|
|
154
|
-
region: { "functionName": "arrow", "body": "chance.pickone(['North America', 'Europe', 'Asia', 'South America', 'Africa', 'Oceania'])" }
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* userProps are properties that are associated with a user
|
|
159
|
-
* they can be simple values or functions that return a value
|
|
160
|
-
* this is the $set property on the user profile
|
|
161
|
-
* you MUST create userProps for every dungeon
|
|
162
|
-
*/
|
|
163
|
-
userProps: {
|
|
164
|
-
favoriteBrand: ["nike", "adidas", "puma", "reebok", "new balance", "asics", "vans", "converse"],
|
|
165
|
-
favoriteProduct: ["shoes", "clothing", "sports", "equipment"],
|
|
166
|
-
// Example using chance.integer with options
|
|
167
|
-
age: { "functionName": "chance.integer", "args": [{"min": 18, "max": 65}] },
|
|
168
|
-
isSubscribed: [true, false],
|
|
169
|
-
plan: ["free", "free", "free", "plus", "plus", "pro"],
|
|
170
|
-
signupDate: { "functionName": "date", "args": [365, true, "YYYY-MM-DD"] },
|
|
171
|
-
// Example using arrow function for complex expression
|
|
172
|
-
user_id: { "functionName": "arrow", "body": "`user_${chance.guid()}`" },
|
|
173
|
-
company: { "functionName": "chance.company", "args": [] },
|
|
174
|
-
email: { "functionName": "chance.email", "args": [] },
|
|
175
|
-
name: { "functionName": "chance.name", "args": [] }
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* funnels are sequences of events that represent a user journey
|
|
180
|
-
* each funnel has a sequence of events and a conversion rate
|
|
181
|
-
* the conversion rate determines how many users complete the funnel
|
|
182
|
-
* you can also add conditions to funnels to filter users based on properties
|
|
183
|
-
* you MUST create funnels for every dungeon
|
|
184
|
-
*/
|
|
185
|
-
funnels: [
|
|
186
|
-
{
|
|
187
|
-
sequence: ["sign up", "page view", "view item", "add to cart", "checkout"],
|
|
188
|
-
conversionRate: 15, // Integer 0-100 representing percentage
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
sequence: ["page view", "watch video"],
|
|
192
|
-
conversionRate: 65,
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
sequence: ["page view", "view item", "save item"],
|
|
196
|
-
conversionRate: 25,
|
|
197
|
-
conditions: { plan: "free" } // Conditions must be an object, not a string expression
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
sequence: ["search", "view item", "add to cart"],
|
|
201
|
-
conversionRate: 35
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
sequence: ["page view", "view item", "share item"],
|
|
205
|
-
conversionRate: 10
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* scdProps are Slowly Changing Dimensions properties
|
|
211
|
-
* these are properties that change over time for users or groups
|
|
212
|
-
* each SCD property has a type (user or group), frequency, values, timing, and max changes
|
|
213
|
-
* OPTIONAL: only include if your use case involves properties that change over time
|
|
214
|
-
*/
|
|
215
|
-
scdProps: {
|
|
216
|
-
role: {
|
|
217
|
-
type: "user",
|
|
218
|
-
frequency: "month", // how often the property changes
|
|
219
|
-
values: ["admin", "user", "viewer", "editor"],
|
|
220
|
-
timing: "fixed", // fixed or fuzzy
|
|
221
|
-
max: 5 // maximum number of changes per entity
|
|
222
|
-
},
|
|
223
|
-
subscription_tier: {
|
|
224
|
-
type: "user",
|
|
225
|
-
frequency: "month", // Changed from "quarter" - valid options are: day, week, month, year
|
|
226
|
-
values: ["free", "basic", "premium", "enterprise"],
|
|
227
|
-
timing: "fuzzy", // Changed from "random" - valid options are: fixed, fuzzy
|
|
228
|
-
max: 3
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* groupKeys define the types of groups in your data
|
|
234
|
-
* Each group key is a tuple of [groupName, numberOfGroups]
|
|
235
|
-
*
|
|
236
|
-
* ⚠️ IMPORTANT: Groups are OPTIONAL and should ONLY be included when:
|
|
237
|
-
* - The use case explicitly involves B2B relationships
|
|
238
|
-
* - You have SaaS with company/team accounts
|
|
239
|
-
* - There's a clear one-to-many relationship (one company → many users)
|
|
240
|
-
* - Keywords mentioned: "company", "organization", "team", "workspace", "account"
|
|
241
|
-
*
|
|
242
|
-
* DO NOT include for B2C (business to consumer) scenarios
|
|
243
|
-
* DO NOT include unless explicitly needed for group analytics
|
|
244
|
-
*/
|
|
245
|
-
groupKeys: [
|
|
246
|
-
["company_id", 1000], // 1000 companies
|
|
247
|
-
["team_id", 5000] // 5000 teams
|
|
248
|
-
],
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* groupProps are properties associated with groups
|
|
252
|
-
* Similar to userProps but for group entities
|
|
253
|
-
*
|
|
254
|
-
* ⚠️ IMPORTANT: ONLY include if you have groupKeys defined
|
|
255
|
-
* These represent attributes of the group entities (companies, teams, etc.)
|
|
256
|
-
*/
|
|
257
|
-
groupProps: {
|
|
258
|
-
company_id: {
|
|
259
|
-
name: { "functionName": "chance.company", "args": [] },
|
|
260
|
-
plan: ["startup", "growth", "enterprise"],
|
|
261
|
-
employees: { "functionName": "weighNumRange", "args": [1, 5000, 0.3] },
|
|
262
|
-
industry: { "functionName": "chance.pickone", "args": [["tech", "finance", "healthcare", "retail", "manufacturing"]] }
|
|
263
|
-
},
|
|
264
|
-
team_id: {
|
|
265
|
-
name: { "functionName": "arrow", "body": "`Team ${chance.word()}`" },
|
|
266
|
-
size: { "functionName": "weighNumRange", "args": [2, 50, 0.2] },
|
|
267
|
-
department: ["engineering", "sales", "marketing", "support", "product"]
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
|
|
272
|
-
export default DUNGEON;
|