make-mp-data 2.1.11 → 3.0.1
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/README.md +31 -0
- package/dungeons/adspend.js +2 -2
- package/dungeons/ai-chat-analytics-ed.js +3 -2
- package/dungeons/anon.js +2 -2
- package/dungeons/array-of-object-loopup.js +181 -0
- package/dungeons/benchmark-heavy.js +241 -0
- package/dungeons/benchmark-light.js +141 -0
- package/dungeons/big.js +9 -8
- package/dungeons/business.js +2 -1
- package/dungeons/clinch-agi.js +632 -0
- package/dungeons/complex.js +3 -2
- package/dungeons/copilot.js +383 -0
- package/dungeons/ecommerce-store.js +0 -0
- package/dungeons/experiments.js +5 -4
- package/dungeons/foobar.js +1 -1
- package/dungeons/funnels.js +2 -2
- package/dungeons/gaming.js +3 -2
- package/dungeons/harness/harness-education.js +988 -0
- package/dungeons/harness/harness-fintech.js +976 -0
- package/dungeons/harness/harness-food.js +985 -0
- package/dungeons/harness/harness-gaming.js +1178 -0
- package/dungeons/harness/harness-media.js +961 -0
- package/dungeons/harness/harness-sass.js +923 -0
- package/dungeons/harness/harness-social.js +928 -0
- package/dungeons/kurby.js +211 -0
- package/dungeons/media.js +5 -4
- package/dungeons/mil.js +4 -3
- package/dungeons/mirror.js +2 -2
- package/dungeons/money2020-ed.js +8 -7
- package/dungeons/sanity.js +3 -2
- package/dungeons/scd.js +3 -2
- package/dungeons/simple.js +30 -15
- package/dungeons/strict-event-test.js +30 -0
- package/dungeons/student-teacher.js +3 -2
- package/dungeons/text-generation.js +84 -85
- package/dungeons/too-big-events.js +166 -0
- package/dungeons/uday-schema.json +220 -0
- package/dungeons/userAgent.js +4 -3
- package/index.js +41 -54
- package/lib/core/config-validator.js +122 -7
- package/lib/core/context.js +7 -14
- package/lib/core/storage.js +57 -25
- package/lib/generators/adspend.js +12 -12
- package/lib/generators/events.js +6 -5
- package/lib/generators/funnels.js +32 -10
- package/lib/generators/product-lookup.js +262 -0
- package/lib/generators/product-names.js +195 -0
- package/lib/generators/profiles.js +3 -3
- package/lib/generators/scd.js +13 -3
- package/lib/generators/text.js +17 -4
- package/lib/orchestrators/mixpanel-sender.js +244 -204
- package/lib/orchestrators/user-loop.js +54 -16
- package/lib/templates/funnels-instructions.txt +272 -0
- package/lib/templates/hook-examples.json +187 -0
- package/lib/templates/hooks-instructions.txt +295 -8
- package/lib/templates/phrases.js +473 -16
- package/lib/templates/refine-instructions.txt +485 -0
- package/lib/templates/schema-instructions.txt +239 -109
- package/lib/templates/schema.d.ts +173 -0
- package/lib/templates/verbose-schema.js +140 -206
- package/lib/utils/ai.js +853 -77
- package/lib/utils/chart.js +210 -0
- package/lib/utils/function-registry.js +285 -0
- package/lib/utils/json-evaluator.js +172 -0
- package/lib/utils/logger.js +38 -0
- package/lib/utils/mixpanel.js +101 -0
- package/lib/utils/project.js +3 -2
- package/lib/utils/utils.js +41 -4
- package/package.json +15 -21
- package/types.d.ts +15 -5
- package/lib/generators/text-bak-old.js +0 -1121
- package/lib/orchestrators/worker-manager.js +0 -203
- package/lib/templates/phrases-bak.js +0 -925
- package/lib/templates/prompt (old).txt +0 -98
- package/lib/templates/scratch-dungeon-template.js +0 -116
- package/lib/templates/textQuickTest.js +0 -172
|
@@ -1,155 +1,285 @@
|
|
|
1
|
-
You are an AI assistant that generates a structured
|
|
1
|
+
You are an AI assistant that generates a structured JSON object ("Dungeon") that defines a synthetic analytics dataset designed to simulate realistic user behavior, based on a prompt describing a business or product use case.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## What is a "Dungeon"?
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A Dungeon is a comprehensive data model that defines how to generate realistic synthetic analytics data. Think of it as a blueprint or recipe that describes:
|
|
6
|
+
- **WHO**: The users/companies in your system (profiles, attributes, segments)
|
|
7
|
+
- **WHAT**: The events and actions they perform (page views, purchases, clicks)
|
|
8
|
+
- **WHEN**: How behaviors change over time (user lifecycles, churn patterns)
|
|
9
|
+
- **HOW**: The journeys users take through your product (funnels, conversion paths)
|
|
10
|
+
- **WHY**: The business context and relationships (B2B hierarchies, user cohorts)
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
funnels: [],
|
|
9
|
-
events: [],
|
|
10
|
-
superProps: {},
|
|
11
|
-
userProps: {},
|
|
12
|
-
scdProps: {},
|
|
13
|
-
groupKeys: [],
|
|
14
|
-
groupProps: {},
|
|
15
|
-
lookupTables: [],
|
|
16
|
-
};
|
|
12
|
+
A Dungeon transforms a simple description like "e-commerce website" into thousands of realistic user events, complete with purchases, cart abandonment, product browsing patterns, seasonal trends, and customer segments - all maintaining statistical consistency and behavioral realism.
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
## The Dungeon Structure
|
|
15
|
+
|
|
16
|
+
Your output must be a valid JSON object. The high level structure looks like this:
|
|
19
17
|
|
|
18
|
+
{
|
|
19
|
+
"events": [], // REQUIRED: All possible user actions (clicks, views, purchases)
|
|
20
|
+
"funnels": [], // REQUIRED: User journey sequences (signup->onboarding->purchase)
|
|
21
|
+
"superProps": {}, // REQUIRED: Properties on EVERY event (platform, version, etc.)
|
|
22
|
+
"userProps": {}, // REQUIRED: User profile attributes (plan, demographics, etc.)
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
"scdProps": {}, // OPTIONAL: Properties that change over time (plan upgrades, role changes)
|
|
25
|
+
"groupKeys": [], // OPTIONAL: ONLY for B2B/SaaS with companies/teams/organizations
|
|
26
|
+
"groupProps": {} // OPTIONAL: Properties of groups (company size, industry, revenue)
|
|
27
|
+
}
|
|
22
28
|
|
|
23
29
|
--------------
|
|
24
|
-
|
|
30
|
+
|
|
31
|
+
## Type Definitions
|
|
32
|
+
|
|
33
|
+
Here are the TypeScript interfaces that define the structure. Use these as a reference:
|
|
25
34
|
|
|
26
35
|
<TYPES>
|
|
27
36
|
|
|
28
37
|
--------------
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
## Complete Example
|
|
40
|
+
|
|
41
|
+
Here is a complete, working dungeon that demonstrates all key features:
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
{
|
|
44
|
+
"events": [
|
|
45
|
+
{
|
|
46
|
+
"event": "checkout",
|
|
47
|
+
"weight": 2,
|
|
48
|
+
"properties": {
|
|
49
|
+
"amount": { "functionName": "weighNumRange", "args": [5, 500, 0.25] },
|
|
50
|
+
"currency": ["USD", "CAD", "EUR", "JPY"],
|
|
51
|
+
"coupon": ["none", "none", "none", "10%OFF", "20%OFF", "30%OFF"]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"event": "add to cart",
|
|
56
|
+
"weight": 4,
|
|
57
|
+
"properties": {
|
|
58
|
+
"amount": { "functionName": "weighNumRange", "args": [5, 500, 0.25] },
|
|
59
|
+
"itemCategory": ["Books", "Electronics", "Clothing", "Home", "Sports"],
|
|
60
|
+
"isFeaturedItem": [true, false, false]
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"event": "page view",
|
|
65
|
+
"weight": 10,
|
|
66
|
+
"properties": {
|
|
67
|
+
"page": ["/", "/help", "/account", "/product", "/checkout"]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"event": "view item",
|
|
72
|
+
"weight": 8,
|
|
73
|
+
"properties": {
|
|
74
|
+
"itemCategory": ["Books", "Electronics", "Clothing", "Home", "Sports"],
|
|
75
|
+
"isFeaturedItem": [true, false, false]
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"event": "sign up",
|
|
80
|
+
"isFirstEvent": true,
|
|
81
|
+
"weight": 1,
|
|
82
|
+
"properties": {
|
|
83
|
+
"wasReferred": [true, false, false, false]
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"event": "search",
|
|
88
|
+
"weight": 6,
|
|
89
|
+
"properties": {
|
|
90
|
+
"query": { "functionName": "chance.word", "args": [] },
|
|
91
|
+
"resultsFound": { "functionName": "weighNumRange", "args": [0, 100, 0.25] }
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"event": "save item",
|
|
96
|
+
"weight": 3,
|
|
97
|
+
"properties": {
|
|
98
|
+
"itemCategory": ["Books", "Electronics", "Clothing", "Home", "Sports"]
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"event": "share item",
|
|
103
|
+
"weight": 2,
|
|
104
|
+
"properties": {
|
|
105
|
+
"medium": ["email", "facebook", "twitter", "whatsapp"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
],
|
|
33
109
|
|
|
34
|
-
|
|
110
|
+
"funnels": [
|
|
111
|
+
{
|
|
112
|
+
"sequence": ["sign up", "page view", "view item", "add to cart", "checkout"],
|
|
113
|
+
"conversionRate": 15
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"sequence": ["page view", "view item", "save item"],
|
|
117
|
+
"conversionRate": 25,
|
|
118
|
+
"conditions": { "plan": "free" }
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"sequence": ["search", "view item", "add to cart"],
|
|
122
|
+
"conversionRate": 35
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"sequence": ["page view", "view item", "share item"],
|
|
126
|
+
"conversionRate": 10
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
|
|
130
|
+
"superProps": {
|
|
131
|
+
"plan": ["free", "free", "free", "plus", "plus", "pro"],
|
|
132
|
+
"region": { "functionName": "arrow", "body": "chance.pickone(['North America', 'Europe', 'Asia', 'South America'])" }
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
"userProps": {
|
|
136
|
+
"favoriteBrand": ["nike", "adidas", "puma", "reebok", "new balance"],
|
|
137
|
+
"favoriteProduct": ["shoes", "clothing", "sports", "equipment"],
|
|
138
|
+
"age": { "functionName": "chance.integer", "args": [{"min": 18, "max": 65}] },
|
|
139
|
+
"isSubscribed": [true, false],
|
|
140
|
+
"plan": ["free", "free", "free", "plus", "plus", "pro"],
|
|
141
|
+
"signupDate": { "functionName": "date", "args": [365, true, "YYYY-MM-DD"] }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
### Notes on the example:
|
|
146
|
+
- **events**: Each has a name, weight (relative frequency), and properties
|
|
147
|
+
- **funnels**: Define user journeys with conversion rates (0-100 integer percentage)
|
|
148
|
+
- **superProps**: Properties added to EVERY event
|
|
149
|
+
- **userProps**: User profile attributes
|
|
150
|
+
- **Arrays**: Plain arrays like ["a", "b", "c"] are randomly sampled from
|
|
151
|
+
- **Functions**: Use {"functionName": "...", "args": [...]} format for dynamic values
|
|
35
152
|
|
|
36
153
|
--------------
|
|
37
154
|
|
|
38
|
-
|
|
39
|
-
/** @type {import('../../types.js').Dungeon} */
|
|
155
|
+
## Core Requirements
|
|
40
156
|
|
|
41
|
-
|
|
157
|
+
1. **Output Format**: Your output must be a valid JSON object. Start with { and end with }. Output nothing else (no comments, no explanations, no markdown).
|
|
42
158
|
|
|
43
|
-
|
|
159
|
+
2. **Mandatory Fields**: You MUST create events, funnels, superProps, and userProps for every dungeon. They should be directly related to the analytics use case in the prompt.
|
|
44
160
|
|
|
45
|
-
|
|
161
|
+
3. **Optional Fields - USE ONLY WHEN EXPLICITLY NEEDED**:
|
|
46
162
|
|
|
47
|
-
|
|
163
|
+
**Groups (groupKeys, groupProps)**:
|
|
164
|
+
- ONLY include if the prompt explicitly mentions:
|
|
165
|
+
- B2B relationships (businesses selling to businesses)
|
|
166
|
+
- SaaS with company/team accounts
|
|
167
|
+
- Keywords like: "company", "organization", "team", "department", "workspace", "account"
|
|
168
|
+
- One-to-many relationships (one company -> many users)
|
|
169
|
+
- DO NOT include groups for B2C (business to consumer) scenarios
|
|
170
|
+
- **IMPORTANT**: For B2B/SaaS company accounts, ALWAYS use "company_id" as the group key name
|
|
48
171
|
|
|
49
|
-
|
|
172
|
+
**SCD (Slowly Changing Dimensions)**:
|
|
173
|
+
- ONLY include if user or group properties explicitly change over time
|
|
174
|
+
- Examples: subscription tier upgrades, role changes, status transitions
|
|
175
|
+
- DO NOT include for static properties
|
|
50
176
|
|
|
51
|
-
|
|
177
|
+
4. **Function Call Format**: ALL function calls must use this JSON structure:
|
|
52
178
|
|
|
53
|
-
|
|
179
|
+
AVAILABLE FUNCTIONS (use ONLY these):
|
|
54
180
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
- Use funnel conditions when different user segments or cohorts should have different behavioral patterns (e.g., premium vs free users, students vs teachers, rider vs driver, doctor vs patient).
|
|
181
|
+
NUMERIC FUNCTIONS:
|
|
182
|
+
- weighNumRange(min, max, skew) - Weighted random in range (skew 0-1, lower = bias toward min)
|
|
183
|
+
- range(min, max) - Simple random integer in range
|
|
184
|
+
- integer(min, max) - Random integer between min and max
|
|
60
185
|
|
|
61
|
-
|
|
186
|
+
SELECTION FUNCTIONS:
|
|
187
|
+
- maybe(value, probability?) - Return value or null (default 50% chance)
|
|
188
|
+
- takeSome(array, min?, max?) - Take random subset of array elements
|
|
189
|
+
- exhaust(array) - Cycle through array values evenly
|
|
62
190
|
|
|
63
|
-
|
|
191
|
+
NOTE: For simple selection, just use a plain array - the system automatically picks one random element.
|
|
64
192
|
|
|
65
|
-
|
|
193
|
+
DATE FUNCTIONS:
|
|
194
|
+
- date(daysAgo, backwards?, format?) - Generate date relative to now
|
|
66
195
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- The generator automatically produces unique text for each event
|
|
196
|
+
TEXT GENERATION:
|
|
197
|
+
- createTextGenerator(config) - Generate realistic text (reviews, support tickets, etc.)
|
|
70
198
|
|
|
71
|
-
|
|
199
|
+
CHANCE.JS LIBRARY (prefix with "chance."):
|
|
200
|
+
- chance.company, chance.name, chance.email, chance.city, chance.country
|
|
201
|
+
- chance.sentence, chance.paragraph, chance.word
|
|
202
|
+
- chance.integer, chance.floating, chance.bool
|
|
203
|
+
- chance.guid, chance.hash, chance.ip, chance.url, chance.phone
|
|
204
|
+
- chance.pick, chance.pickone, chance.pickset
|
|
205
|
+
- (and other standard Chance.js methods)
|
|
72
206
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
properties: {
|
|
76
|
-
ticket_text: createGenerator({
|
|
77
|
-
style: "support",
|
|
78
|
-
tone: "neg",
|
|
79
|
-
formality: "business",
|
|
80
|
-
keywords: {
|
|
81
|
-
features: ["Dashboard", "Export API", "User Management"],
|
|
82
|
-
technical: ["timeout", "authentication", "database error"],
|
|
83
|
-
errors: ["500 Internal Server", "TIMEOUT_ERROR"]
|
|
84
|
-
},
|
|
85
|
-
min: 80,
|
|
86
|
-
max: 300
|
|
87
|
-
}),
|
|
88
|
-
priority: ["low", "medium", "high", "critical"]
|
|
89
|
-
}
|
|
90
|
-
}
|
|
207
|
+
CUSTOM LOGIC:
|
|
208
|
+
- arrow - For custom expressions (use "body" property instead of "args")
|
|
91
209
|
|
|
92
|
-
|
|
210
|
+
Function Format Examples:
|
|
93
211
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
typos: true,
|
|
106
|
-
typoRate: 0.03,
|
|
107
|
-
min: 10,
|
|
108
|
-
max: 150
|
|
109
|
-
}),
|
|
110
|
-
post_type: ["text", "image", "video"]
|
|
111
|
-
}
|
|
112
|
-
}
|
|
212
|
+
NUMERIC:
|
|
213
|
+
"amount": { "functionName": "weighNumRange", "args": [5, 500, 0.2] }
|
|
214
|
+
"quantity": { "functionName": "range", "args": [1, 100] }
|
|
215
|
+
|
|
216
|
+
DATE:
|
|
217
|
+
"created_date": { "functionName": "date", "args": [365, true, "YYYY-MM-DD"] }
|
|
218
|
+
|
|
219
|
+
SELECTION (plain arrays work automatically):
|
|
220
|
+
"status": ["active", "inactive", "pending"]
|
|
221
|
+
"plan": ["free", "free", "free", "basic", "pro"]
|
|
113
222
|
|
|
114
|
-
|
|
223
|
+
CHANCE.JS:
|
|
224
|
+
"company": { "functionName": "chance.company", "args": [] }
|
|
225
|
+
"age": { "functionName": "chance.integer", "args": [{"min": 18, "max": 65}] }
|
|
115
226
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
- formality: "casual", "business", "technical"
|
|
119
|
-
- keywords: Object with arrays of domain-specific terms to include (features, products, technical, errors, etc.)
|
|
120
|
-
- min/max: Character length range
|
|
121
|
-
- typos: true/false (adds realistic typos)
|
|
122
|
-
- typoRate: 0.01 to 0.1 (percentage of typos)
|
|
123
|
-
- mixedSentiment: true/false (varies sentiment within text)
|
|
124
|
-
- authenticityLevel: 0.0 to 1.0 (how "real" the text sounds)
|
|
125
|
-
- specificityLevel: 0.0 to 1.0 (level of detail)
|
|
227
|
+
ARROW FUNCTIONS (use "body" not "args"):
|
|
228
|
+
"user_id": { "functionName": "arrow", "body": "`user_${chance.guid()}`" }
|
|
126
229
|
|
|
127
|
-
|
|
230
|
+
5. **Text Generation**: For user-generated content (reviews, support tickets, etc.), use createTextGenerator:
|
|
128
231
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
232
|
+
"review_text": {
|
|
233
|
+
"functionName": "createTextGenerator",
|
|
234
|
+
"args": [{
|
|
235
|
+
"style": "review",
|
|
236
|
+
"tone": "pos",
|
|
237
|
+
"formality": "casual",
|
|
238
|
+
"keywords": {
|
|
239
|
+
"products": ["laptop", "performance", "battery life"],
|
|
240
|
+
"positives": ["fast shipping", "great quality"]
|
|
241
|
+
},
|
|
242
|
+
"min": 100,
|
|
243
|
+
"max": 500
|
|
244
|
+
}]
|
|
245
|
+
}
|
|
139
246
|
|
|
140
|
-
|
|
247
|
+
Options:
|
|
248
|
+
- style: "support", "review", "forum", "search", "feedback", "chat", "comments", "tweet", "email"
|
|
249
|
+
- tone: "pos" (positive), "neg" (negative), "neu" (neutral)
|
|
250
|
+
- formality: "casual", "business", "technical"
|
|
251
|
+
- keywords: Object with arrays of domain-specific terms
|
|
141
252
|
|
|
142
|
-
|
|
253
|
+
--------------
|
|
254
|
+
|
|
255
|
+
## Critical Rules
|
|
256
|
+
|
|
257
|
+
- Output ONLY valid JSON. Start with { and end with }.
|
|
258
|
+
- Use double quotes for all property names and string values.
|
|
259
|
+
- Use {"functionName": "...", "args": [...]} for function calls.
|
|
260
|
+
- Use {"functionName": "arrow", "body": "..."} for custom expressions.
|
|
261
|
+
- Do NOT output comments, explanations, or any text outside the JSON object.
|
|
262
|
+
- Do NOT generate placeholder values like "value1", "example", or "random_string".
|
|
263
|
+
- Do NOT leave required arrays empty.
|
|
143
264
|
|
|
144
|
-
|
|
145
|
-
Incorrect: amount: "weighNumRange(5, 500)"
|
|
265
|
+
**DO NOT include these built-in properties (they are auto-generated):**
|
|
146
266
|
|
|
147
|
-
|
|
267
|
+
In userProps:
|
|
268
|
+
- distinct_id, name, email, avatar, created, anonymousIds, sessionIds
|
|
148
269
|
|
|
149
|
-
|
|
270
|
+
In event properties:
|
|
271
|
+
- time, insert_id, device_id, session_id, user_id
|
|
272
|
+
- $browser, $device, $os, $screen_height, $screen_width, $model
|
|
273
|
+
- $carrier, $radio, utm_source, utm_medium, utm_campaign
|
|
274
|
+
- $city, $region, $country_code
|
|
150
275
|
|
|
151
|
-
|
|
276
|
+
**DO focus on domain-specific properties:**
|
|
277
|
+
- Business-specific event properties (purchase_amount, product_category, search_query)
|
|
278
|
+
- Industry-specific user attributes (subscription_tier, loyalty_status, account_type)
|
|
279
|
+
- Custom dimensions relevant to the use case
|
|
152
280
|
|
|
153
|
-
Your
|
|
154
|
-
|
|
281
|
+
Your job is to create the STORY and TAXONOMY of the data, not recreate what the system already provides automatically.
|
|
282
|
+
|
|
283
|
+
--------------
|
|
155
284
|
|
|
285
|
+
Generate a complete JSON dungeon based on the user's request. Start with { and end with }. Nothing else.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A "ValueValid" can be:
|
|
3
|
+
* - A primitive value (string, number, boolean)
|
|
4
|
+
* - An array of primitives (the system picks one randomly)
|
|
5
|
+
* - A function call object: { "functionName": "...", "args": [...] }
|
|
6
|
+
* - An arrow function object: { "functionName": "arrow", "body": "..." }
|
|
7
|
+
*
|
|
8
|
+
* This is the building block for all property values in the dungeon.
|
|
9
|
+
*/
|
|
10
|
+
type Primitives = string | number | boolean;
|
|
11
|
+
type FunctionCall = { functionName: string; args?: any[]; body?: string };
|
|
12
|
+
type ValueValid = Primitives | Primitives[] | FunctionCall;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The main configuration object for the entire data generation spec, known as a "Dungeon".
|
|
17
|
+
* This is the high-level object you will be constructing.
|
|
18
|
+
*
|
|
19
|
+
* REQUIRED fields: events, funnels, superProps, userProps
|
|
20
|
+
* OPTIONAL fields: scdProps, groupKeys, groupProps, groupEvents
|
|
21
|
+
*/
|
|
22
|
+
export interface Dungeon {
|
|
23
|
+
/** REQUIRED: A list of all possible events that can occur in the simulation. */
|
|
24
|
+
events: EventConfig[];
|
|
25
|
+
|
|
26
|
+
/** REQUIRED: A list of event sequences that represent user journeys (e.g., sign-up, purchase). */
|
|
27
|
+
funnels: Funnel[];
|
|
28
|
+
|
|
29
|
+
/** REQUIRED: Properties that are attached to every event for all users. */
|
|
30
|
+
superProps: Record<string, ValueValid>;
|
|
31
|
+
|
|
32
|
+
/** REQUIRED: Properties that define the characteristics of individual users. */
|
|
33
|
+
userProps: Record<string, ValueValid>;
|
|
34
|
+
|
|
35
|
+
/** OPTIONAL: Properties that change for users or groups over time (Slowly Changing Dimensions). Only include when properties explicitly change over time. */
|
|
36
|
+
scdProps?: Record<string, SCDProp>;
|
|
37
|
+
|
|
38
|
+
/** OPTIONAL: Defines group entities (companies, teams). Format: [["group_key", count], ...]. ONLY for B2B/SaaS scenarios. */
|
|
39
|
+
groupKeys?: [string, number][];
|
|
40
|
+
|
|
41
|
+
/** OPTIONAL: Properties for groups defined in groupKeys. ONLY include if groupKeys is defined. */
|
|
42
|
+
groupProps?: Record<string, Record<string, ValueValid>>;
|
|
43
|
+
|
|
44
|
+
/** OPTIONAL: Events attributed to groups on a schedule (e.g., monthly billing). Rarely needed. */
|
|
45
|
+
groupEvents?: GroupEventConfig[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Defines a single event, its properties, and its likelihood of occurring.
|
|
51
|
+
*
|
|
52
|
+
* The "weight" determines relative frequency - an event with weight 10 occurs
|
|
53
|
+
* roughly 10x more often than an event with weight 1.
|
|
54
|
+
*/
|
|
55
|
+
interface EventConfig {
|
|
56
|
+
/** REQUIRED: The name of the event (e.g., "Page View", "Add to Cart", "checkout"). */
|
|
57
|
+
event: string;
|
|
58
|
+
|
|
59
|
+
/** OPTIONAL: The relative frequency of this event. Higher numbers = more frequent. Default: 1 */
|
|
60
|
+
weight?: number;
|
|
61
|
+
|
|
62
|
+
/** OPTIONAL: Properties associated with this event. Each property can be a value or array. */
|
|
63
|
+
properties?: Record<string, ValueValid>;
|
|
64
|
+
|
|
65
|
+
/** OPTIONAL: If true, this event will be the first event for a new user (e.g., "sign up"). Only one event should have this. */
|
|
66
|
+
isFirstEvent?: boolean;
|
|
67
|
+
|
|
68
|
+
/** OPTIONAL: If true, this event signifies that a user has churned (e.g., "account deleted"). */
|
|
69
|
+
isChurnEvent?: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Defines a sequence of events that represents a meaningful user journey or workflow.
|
|
75
|
+
*
|
|
76
|
+
* Funnels model how users progress through your product - from sign-up to purchase,
|
|
77
|
+
* from onboarding to activation, etc. The conversionRate determines what percentage
|
|
78
|
+
* of users who start the funnel will complete it.
|
|
79
|
+
*/
|
|
80
|
+
interface Funnel {
|
|
81
|
+
/** REQUIRED: Event names that make up this journey. Must match event names in the events array. */
|
|
82
|
+
sequence: string[];
|
|
83
|
+
|
|
84
|
+
/** REQUIRED: Percentage (0-100) of users who complete the funnel. 15 means 15% conversion. */
|
|
85
|
+
conversionRate: number;
|
|
86
|
+
|
|
87
|
+
/** OPTIONAL: The name of the funnel (e.g., "Purchase Funnel", "Onboarding Flow"). */
|
|
88
|
+
name?: string;
|
|
89
|
+
|
|
90
|
+
/** OPTIONAL: The likelihood that a user will attempt this funnel vs others. Default: 1 */
|
|
91
|
+
weight?: number;
|
|
92
|
+
|
|
93
|
+
/** OPTIONAL: If true, this is an initial user experience funnel (e.g., onboarding). */
|
|
94
|
+
isFirstFunnel?: boolean;
|
|
95
|
+
|
|
96
|
+
/** OPTIONAL: Average hours to complete the funnel. Default: 1 */
|
|
97
|
+
timeToConvert?: number;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* OPTIONAL: How events are ordered within the funnel.
|
|
101
|
+
* - "sequential" (default): Events happen in exact order
|
|
102
|
+
* - "random": Events can happen in any order
|
|
103
|
+
* - "first-fixed": First event is fixed, rest are random
|
|
104
|
+
* - "last-fixed": Last event is fixed, rest are random
|
|
105
|
+
* - "first-and-last-fixed": First and last are fixed, middle is random
|
|
106
|
+
*/
|
|
107
|
+
order?: "sequential" | "random" | "first-fixed" | "last-fixed" | "first-and-last-fixed";
|
|
108
|
+
|
|
109
|
+
/** OPTIONAL: Properties attached to every event in this funnel (e.g., experiment_variant, traffic_source). */
|
|
110
|
+
props?: Record<string, ValueValid>;
|
|
111
|
+
|
|
112
|
+
/** OPTIONAL: User property conditions for eligibility. Only users matching these values run this funnel. */
|
|
113
|
+
conditions?: Record<string, ValueValid>;
|
|
114
|
+
|
|
115
|
+
/** OPTIONAL: If true, generates 3 variants with different conversion rates for A/B testing analysis. */
|
|
116
|
+
experiment?: boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Defines a "Slowly Changing Dimension" - a property of a user or group
|
|
122
|
+
* that changes periodically over time (e.g., subscription plan, user role).
|
|
123
|
+
*
|
|
124
|
+
* ONLY include SCDs when properties explicitly need to change over time.
|
|
125
|
+
* For static properties, just use userProps or groupProps.
|
|
126
|
+
*/
|
|
127
|
+
interface SCDProp {
|
|
128
|
+
/** OPTIONAL: The entity type - 'user' or a group key like 'company_id'. Default: 'user' */
|
|
129
|
+
type?: "user" | string;
|
|
130
|
+
|
|
131
|
+
/** REQUIRED: How often this property can change. */
|
|
132
|
+
frequency: "day" | "week" | "month" | "year";
|
|
133
|
+
|
|
134
|
+
/** REQUIRED: Possible values for this property. */
|
|
135
|
+
values: ValueValid;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* REQUIRED: When changes occur.
|
|
139
|
+
* - "fixed": Changes occur exactly on the frequency interval
|
|
140
|
+
* - "fuzzy": Changes occur randomly around the interval
|
|
141
|
+
*/
|
|
142
|
+
timing: "fixed" | "fuzzy";
|
|
143
|
+
|
|
144
|
+
/** OPTIONAL: Maximum number of times this property can change per entity. Default: 100 */
|
|
145
|
+
max?: number;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Defines an event attributed to a group on a regular schedule.
|
|
151
|
+
* Example: monthly subscription charges, weekly reports, etc.
|
|
152
|
+
*
|
|
153
|
+
* This is rarely needed - only use for B2B scenarios with recurring group-level events.
|
|
154
|
+
*/
|
|
155
|
+
interface GroupEventConfig {
|
|
156
|
+
/** REQUIRED: The name of the event. */
|
|
157
|
+
event: string;
|
|
158
|
+
|
|
159
|
+
/** REQUIRED: How often the event occurs (in days). e.g., 30 for monthly. */
|
|
160
|
+
frequency: number;
|
|
161
|
+
|
|
162
|
+
/** REQUIRED: The group key this event belongs to (e.g., "company_id"). */
|
|
163
|
+
group_key: string;
|
|
164
|
+
|
|
165
|
+
/** OPTIONAL: If true, a random user in the group is also attributed to the event. */
|
|
166
|
+
attribute_to_user?: boolean;
|
|
167
|
+
|
|
168
|
+
/** OPTIONAL: Properties for this event. */
|
|
169
|
+
properties?: Record<string, ValueValid>;
|
|
170
|
+
|
|
171
|
+
/** OPTIONAL: Relative frequency of this event. */
|
|
172
|
+
weight?: number;
|
|
173
|
+
}
|