@ak--47/dungeon-master 1.1.0 → 1.2.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.
Files changed (72) hide show
  1. package/dungeons/technical/ad-spend-schema.json +2 -2
  2. package/dungeons/technical/ad-spend.js +16 -5
  3. package/dungeons/technical/anonymous-users-schema.json +4 -3
  4. package/dungeons/technical/anonymous-users.js +16 -6
  5. package/dungeons/technical/array-of-object-lookup-schema.json +1 -1
  6. package/dungeons/technical/array-of-object-lookup.js +22 -6
  7. package/dungeons/technical/experiments-schema.json +25 -19
  8. package/dungeons/technical/experiments.js +24 -6
  9. package/dungeons/technical/foobar.js +29 -13
  10. package/dungeons/technical/group-analytics-schema.json +92 -0
  11. package/dungeons/technical/group-analytics.js +16 -6
  12. package/dungeons/technical/mirror-strategies-schema.json +4 -4
  13. package/dungeons/technical/mirror-strategies.js +16 -6
  14. package/dungeons/technical/nested-objects.js +16 -5
  15. package/dungeons/technical/retention-cadence.js +14 -9
  16. package/dungeons/technical/sanity-schema.json +22 -22
  17. package/dungeons/technical/sanity.js +26 -6
  18. package/dungeons/technical/scale-test.js +16 -5
  19. package/dungeons/technical/scd-schema.json +230 -33
  20. package/dungeons/technical/scd.js +25 -5
  21. package/dungeons/technical/simple-schema.json +132 -48
  22. package/dungeons/technical/simple.js +21 -6
  23. package/dungeons/technical/simplest-schema.json +168 -79
  24. package/dungeons/technical/simplest.js +24 -7
  25. package/dungeons/technical/text-generation-schema.json +7 -4
  26. package/dungeons/technical/text-generation.js +23 -8
  27. package/dungeons/user/.gitkeep +0 -0
  28. package/dungeons/user/shalini.js +847 -0
  29. package/dungeons/vertical/community-schema.json +71 -49
  30. package/dungeons/vertical/community.js +57 -30
  31. package/dungeons/vertical/devtools-schema.json +69 -48
  32. package/dungeons/vertical/devtools.js +58 -31
  33. package/dungeons/vertical/ecommerce-schema.json +126 -108
  34. package/dungeons/vertical/ecommerce.js +32 -8
  35. package/dungeons/vertical/education-schema.json +5261 -272
  36. package/dungeons/vertical/education.js +45 -22
  37. package/dungeons/vertical/fintech-schema.json +165 -98
  38. package/dungeons/vertical/fintech.js +43 -11
  39. package/dungeons/vertical/fitness-schema.json +69 -47
  40. package/dungeons/vertical/fitness.js +56 -24
  41. package/dungeons/vertical/food-delivery-schema.json +36237 -187
  42. package/dungeons/vertical/food-delivery.js +67 -15
  43. package/dungeons/vertical/gaming-schema.json +104 -60
  44. package/dungeons/vertical/gaming.js +61 -16
  45. package/dungeons/vertical/healthcare-schema.json +70 -48
  46. package/dungeons/vertical/healthcare.js +77 -42
  47. package/dungeons/vertical/insurance-application-schema.json +66 -47
  48. package/dungeons/vertical/insurance-application.js +34 -10
  49. package/dungeons/vertical/logistics-schema.json +60 -38
  50. package/dungeons/vertical/logistics.js +77 -43
  51. package/dungeons/vertical/marketplace-schema.json +65 -43
  52. package/dungeons/vertical/marketplace.js +52 -21
  53. package/dungeons/vertical/media-schema.json +4085 -123
  54. package/dungeons/vertical/media.js +65 -18
  55. package/dungeons/vertical/rpg-schema.json +1984 -147
  56. package/dungeons/vertical/rpg.js +47 -11
  57. package/dungeons/vertical/sass-schema.json +2622 -147
  58. package/dungeons/vertical/sass.js +40 -10
  59. package/dungeons/vertical/social-schema.json +146 -78
  60. package/dungeons/vertical/social.js +39 -10
  61. package/dungeons/vertical/travel-schema.json +57 -35
  62. package/dungeons/vertical/travel.js +58 -21
  63. package/index.js +4 -1
  64. package/lib/core/config-validator.js +13 -2
  65. package/lib/core/context.js +9 -0
  66. package/lib/core/storage.js +2 -0
  67. package/lib/generators/events.js +3 -5
  68. package/lib/orchestrators/user-loop.js +24 -1
  69. package/lib/utils/utils.js +129 -9
  70. package/package.json +1 -1
  71. package/scripts/extract-dungeon-schema.mjs +64 -18
  72. package/types.d.ts +8 -3
@@ -1,3 +1,13 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "dm4-nested-objects";
3
+ const num_days = 30;
4
+ const num_users = 500;
5
+ const avg_events_per_user = 60;
6
+ let token = "your-mixpanel-token";
7
+
8
+ // ── env overrides ──
9
+ if (process.env.MP_TOKEN) token = process.env.MP_TOKEN;
10
+
1
11
  import Chance from 'chance';
2
12
  let chance = new Chance();
3
13
  import dayjs from "dayjs";
@@ -6,6 +16,7 @@ dayjs.extend(utc);
6
16
  import { uid, comma } from 'ak-tools';
7
17
  import { weighNumRange, date, integer, weighChoices } from "../../lib/utils/utils.js";
8
18
 
19
+ /** @typedef {import("../../types").Dungeon} Config */
9
20
  /**
10
21
  * ═══════════════════════════════════════════════════════════════
11
22
  * TECHNICAL TEST: Nested Objects & High Cardinality
@@ -29,11 +40,12 @@ const countries = ["US", "UK", "JP", "DE", "AU", "CA", "FR", "IN", "KR", "MX", "
29
40
 
30
41
  /** @type {import('../../types').Dungeon} */
31
42
  const config = {
32
- seed: "nested objects test",
43
+ token,
44
+ seed: SEED,
33
45
  name: "nested-objects",
34
- numDays: 30,
35
- numEvents: 30_000,
36
- numUsers: 500,
46
+ numDays: num_days,
47
+ numEvents: num_users * avg_events_per_user,
48
+ numUsers: num_users,
37
49
  format: 'json',
38
50
  region: "US",
39
51
  hasAnonIds: false,
@@ -48,7 +60,6 @@ const config = {
48
60
  isAnonymous: false,
49
61
  alsoInferFunnels: false,
50
62
  concurrency: 1,
51
- batchSize: 500_000,
52
63
  writeToDisk: false,
53
64
 
54
65
  events: [
@@ -1,4 +1,13 @@
1
+ // ── TWEAK THESE ──
1
2
  const SEED = "kurby-retention";
3
+ const num_days = 360;
4
+ const num_users = 100;
5
+ const avg_events_per_user = 50;
6
+ let token = "your-mixpanel-token";
7
+
8
+ // ── env overrides ──
9
+ if (process.env.MP_TOKEN) token = process.env.MP_TOKEN;
10
+
2
11
  import dayjs from 'dayjs';
3
12
  import utc from 'dayjs/plugin/utc.js';
4
13
  dayjs.extend(utc);
@@ -6,10 +15,7 @@ import * as u from "../../lib/utils/utils.js";
6
15
  import * as v from 'ak-tools';
7
16
  const chance = u.initChance(SEED);
8
17
 
9
- const num_users = 100;
10
- const days = 360;
11
-
12
- /** @typedef {import("../types.js").Dungeon} Config */
18
+ /** @typedef {import("../../types").Dungeon} Config */
13
19
 
14
20
  /**
15
21
  * ═══════════════════════════════════════════════════════════════
@@ -101,10 +107,10 @@ function generateCadencedEvents(behaviorName, cadence, startTime, endTime, churn
101
107
 
102
108
  /** @type {Config} */
103
109
  const config = {
104
- token: "",
105
- seed: "lets go",
106
- numDays: days,
107
- numEvents: num_users * 50,
110
+ token,
111
+ seed: SEED,
112
+ numDays: num_days,
113
+ numEvents: num_users * avg_events_per_user,
108
114
  numUsers: num_users,
109
115
  hasAnonIds: false,
110
116
  hasSessionIds: false,
@@ -119,7 +125,6 @@ const config = {
119
125
  isAnonymous: false,
120
126
  hasAdSpend: false,
121
127
  hasAvatar: false,
122
- batchSize: 5_500_000,
123
128
  concurrency: 1,
124
129
  writeToDisk: false,
125
130
  percentUsersBornInDataset: 100,
@@ -41,6 +41,27 @@
41
41
  "event": "yak"
42
42
  }
43
43
  ],
44
+ "funnels": [
45
+ {
46
+ "sequence": [
47
+ "qux",
48
+ "garply",
49
+ "durtle",
50
+ "linny",
51
+ "fonk",
52
+ "crumn",
53
+ "yak"
54
+ ]
55
+ },
56
+ {
57
+ "sequence": [
58
+ "foo",
59
+ "bar",
60
+ "baz"
61
+ ],
62
+ "isFirstFunnel": true
63
+ }
64
+ ],
44
65
  "superProps": {
45
66
  "color": [
46
67
  "red",
@@ -160,26 +181,5 @@
160
181
  "jewel beetle",
161
182
  "tortoise beetle"
162
183
  ]
163
- },
164
- "funnels": [
165
- {
166
- "sequence": [
167
- "qux",
168
- "garply",
169
- "durtle",
170
- "linny",
171
- "fonk",
172
- "crumn",
173
- "yak"
174
- ]
175
- },
176
- {
177
- "sequence": [
178
- "foo",
179
- "bar",
180
- "baz"
181
- ],
182
- "isFirstFunnel": true
183
- }
184
- ]
184
+ }
185
185
  }
@@ -1,3 +1,13 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "foo bar";
3
+ const num_days = 90;
4
+ const num_users = 500;
5
+ const avg_events_per_user = 100;
6
+ let token = "your-mixpanel-token";
7
+
8
+ // ── env overrides ──
9
+ if (process.env.MP_TOKEN) token = process.env.MP_TOKEN;
10
+
1
11
  import Chance from 'chance';
2
12
  const chance = new Chance();
3
13
  import dayjs from 'dayjs';
@@ -5,6 +15,7 @@ import utc from 'dayjs/plugin/utc.js';
5
15
  dayjs.extend(utc);
6
16
  import { weighNumRange, integer } from "../../lib/utils/utils.js";
7
17
 
18
+ /** @typedef {import("../../types").Dungeon} Config */
8
19
  /**
9
20
  * ═══════════════════════════════════════════════════════════════
10
21
  * DATASET OVERVIEW
@@ -29,11 +40,11 @@ import { weighNumRange, integer } from "../../lib/utils/utils.js";
29
40
 
30
41
  /** @type {import('../types.js').Dungeon} */
31
42
  const config = {
32
- token: "",
33
- seed: "foo bar",
34
- numDays: 90, //how many days worth of data
35
- numEvents: 50_000, //how many events
36
- numUsers: 500, //how many users
43
+ token,
44
+ seed: SEED,
45
+ numDays: num_days,
46
+ numEvents: num_users * avg_events_per_user,
47
+ numUsers: num_users,
37
48
  format: 'json', //csv or json
38
49
  region: "US",
39
50
  hasAnonIds: false, //if true, anonymousIds are created for each user
@@ -112,7 +123,10 @@ const config = {
112
123
  title: chance.profession.bind(chance),
113
124
  luckyNumber: weighNumRange(42, 420),
114
125
  userTier: ["regular"],
115
- spiritAnimal: ["duck", "dog", "otter", "penguin", "cat", "elephant", "lion", "cheetah", "giraffe", "zebra", "rhino", "hippo", "whale", "dolphin", "shark", "octopus", "squid", "jellyfish", "starfish", "seahorse", "crab", "lobster", "shrimp", "clam", "snail", "slug", "butterfly", "moth", "bee", "wasp", "ant", "beetle", "ladybug", "caterpillar", "centipede", "millipede", "scorpion", "spider", "tarantula", "tick", "mite", "mosquito", "fly", "dragonfly", "damselfly", "grasshopper", "cricket", "locust", "mantis", "cockroach", "termite", "praying mantis", "walking stick", "stick bug", "leaf insect", "lacewing", "aphid", "cicada", "thrips", "psyllid", "scale insect", "whitefly", "mealybug", "planthopper", "leafhopper", "treehopper", "flea", "louse", "bedbug", "flea beetle", "weevil", "longhorn beetle", "leaf beetle", "tiger beetle", "ground beetle", "lady beetle", "firefly", "click beetle", "rove beetle", "scarab beetle", "dung beetle", "stag beetle", "rhinoceros beetle", "hercules beetle", "goliath beetle", "jewel beetle", "tortoise beetle"]
126
+ spiritAnimal: ["duck", "dog", "otter", "penguin", "cat", "elephant", "lion", "cheetah", "giraffe", "zebra", "rhino", "hippo", "whale", "dolphin", "shark", "octopus", "squid", "jellyfish", "starfish", "seahorse", "crab", "lobster", "shrimp", "clam", "snail", "slug", "butterfly", "moth", "bee", "wasp", "ant", "beetle", "ladybug", "caterpillar", "centipede", "millipede", "scorpion", "spider", "tarantula", "tick", "mite", "mosquito", "fly", "dragonfly", "damselfly", "grasshopper", "cricket", "locust", "mantis", "cockroach", "termite", "praying mantis", "walking stick", "stick bug", "leaf insect", "lacewing", "aphid", "cicada", "thrips", "psyllid", "scale insect", "whitefly", "mealybug", "planthopper", "leafhopper", "treehopper", "flea", "louse", "bedbug", "flea beetle", "weevil", "longhorn beetle", "leaf beetle", "tiger beetle", "ground beetle", "lady beetle", "firefly", "click beetle", "rove beetle", "scarab beetle", "dung beetle", "stag beetle", "rhinoceros beetle", "hercules beetle", "goliath beetle", "jewel beetle", "tortoise beetle"],
127
+ color: ["red", "orange", "yellow", "green", "blue", "indigo", "violet"],
128
+ number: integer,
129
+ engagement_score: [0],
116
130
  },
117
131
  hook: function (record, type, meta) {
118
132
  // --- user hook: tag power users based on luckyNumber ---
@@ -137,6 +151,12 @@ const config = {
137
151
 
138
152
  // --- everything hook: low-activity users lose their last few events (churn simulation) ---
139
153
  if (type === "everything") {
154
+ const profile = meta.profile;
155
+ record.forEach(e => {
156
+ e.color = profile.color;
157
+ e.number = profile.number;
158
+ // engagement_score intentionally varies per event (set by event hook)
159
+ });
140
160
  if (record.length > 3 && record.length < 8) {
141
161
  // users with few events lose the tail end — simulates churn
142
162
  return record.slice(0, Math.ceil(record.length * 0.6));
@@ -1,3 +1,13 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "scale test";
3
+ const num_days = 365;
4
+ const num_users = 10_000;
5
+ const avg_events_per_user = 50;
6
+ let token = "your-mixpanel-token";
7
+
8
+ // ── env overrides ──
9
+ if (process.env.MP_TOKEN) token = process.env.MP_TOKEN;
10
+
1
11
  import Chance from 'chance';
2
12
  let chance = new Chance();
3
13
  import dayjs from "dayjs";
@@ -6,6 +16,7 @@ dayjs.extend(utc);
6
16
  import { uid, comma } from 'ak-tools';
7
17
  import { weighNumRange, date, integer, weighChoices } from "../../lib/utils/utils.js";
8
18
 
19
+ /** @typedef {import("../../types").Dungeon} Config */
9
20
  /**
10
21
  * ═══════════════════════════════════════════════════════════════
11
22
  * TECHNICAL TEST: Scale & Performance
@@ -23,14 +34,14 @@ import { weighNumRange, date, integer, weighChoices } from "../../lib/utils/util
23
34
 
24
35
  /** @type {import('../../types').Dungeon} */
25
36
  const config = {
26
- seed: "scale test",
37
+ token,
38
+ seed: SEED,
27
39
  name: "scale-test",
28
- numDays: 365,
29
- numEvents: 500_000,
30
- numUsers: 10_000,
40
+ numDays: num_days,
41
+ numEvents: num_users * avg_events_per_user,
42
+ numUsers: num_users,
31
43
  format: 'json',
32
44
  gzip: true,
33
- batchSize: 500_000,
34
45
  concurrency: 1,
35
46
  region: "US",
36
47
  hasAnonIds: false,
@@ -64,8 +64,8 @@
64
64
  false
65
65
  ],
66
66
  "itemCategory": [
67
- "Art",
68
67
  "Pet",
68
+ "Art",
69
69
  "Handmade",
70
70
  "Garden",
71
71
  "Beauty",
@@ -82,17 +82,21 @@
82
82
  "weight": 10,
83
83
  "properties": {
84
84
  "page": [
85
- "/watch",
86
- "/product",
87
85
  "/",
88
86
  "/help",
89
- "/listen"
87
+ "/account",
88
+ "/watch",
89
+ "/listen",
90
+ "/product",
91
+ "/people",
92
+ "/peace"
90
93
  ],
91
94
  "utm_source": [
92
- "linkedin",
93
95
  "$organic",
96
+ "google",
94
97
  "facebook",
95
- "google"
98
+ "twitter",
99
+ "linkedin"
96
100
  ]
97
101
  }
98
102
  },
@@ -101,12 +105,12 @@
101
105
  "weight": 8,
102
106
  "properties": {
103
107
  "videoCategory": [
104
- "travel",
105
- "DIY",
106
- "gaming",
107
- "funny",
108
- "news",
109
- "educational"
108
+ "cooking",
109
+ "inspirational",
110
+ "music",
111
+ "sports",
112
+ "educational",
113
+ "DIY"
110
114
  ],
111
115
  "isFeaturedItem": [
112
116
  true,
@@ -114,8 +118,8 @@
114
118
  ],
115
119
  "watchTimeSec": {
116
120
  "$range": [
117
- 130,
118
- 469
121
+ 131,
122
+ 467
119
123
  ]
120
124
  },
121
125
  "quality": [
@@ -150,12 +154,12 @@
150
154
  false
151
155
  ],
152
156
  "itemCategory": [
153
- "Games",
154
157
  "Handmade",
158
+ "Baby",
159
+ "Wedding",
155
160
  "Electronics",
156
- "Music",
157
- "Books",
158
- "Movies"
161
+ "Industrial",
162
+ "Pet"
159
163
  ],
160
164
  "dateItemListed": {
161
165
  "$type": "string"
@@ -171,13 +175,13 @@
171
175
  false
172
176
  ],
173
177
  "itemCategory": [
174
- "Food",
175
- "Movies",
176
- "Handmade",
177
- "Art",
178
+ "Games",
178
179
  "Electronics",
179
- "Kids",
180
- "Baby"
180
+ "Books",
181
+ "Entertainment",
182
+ "Outdoors",
183
+ "Pet",
184
+ "Computers"
181
185
  ],
182
186
  "dateItemListed": {
183
187
  "$type": "string"
@@ -219,10 +223,11 @@
219
223
  },
220
224
  {
221
225
  "event": "cart_abandoned",
226
+ "isStrictEvent": true,
222
227
  "properties": {
223
228
  "amount": {
224
229
  "$range": [
225
- 110,
230
+ 114,
226
231
  397
227
232
  ]
228
233
  }
@@ -248,23 +253,215 @@
248
253
  },
249
254
  "luckyNumber": {
250
255
  "$range": [
251
- 117,
252
- 344
256
+ 115,
257
+ 326
253
258
  ]
254
259
  },
255
260
  "spiritAnimal": [
256
- "bee",
261
+ "duck",
262
+ "dog",
263
+ "otter",
264
+ "penguin",
265
+ "cat",
266
+ "elephant",
267
+ "lion",
268
+ "cheetah",
269
+ "giraffe",
270
+ "zebra",
271
+ "rhino",
272
+ "hippo",
273
+ "whale",
274
+ "dolphin",
275
+ "shark",
257
276
  "octopus",
258
- "moth",
277
+ "squid",
278
+ "jellyfish",
279
+ "starfish",
280
+ "seahorse",
281
+ "crab",
282
+ "lobster",
283
+ "shrimp",
284
+ "clam",
285
+ "snail",
286
+ "slug",
259
287
  "butterfly",
260
- "aphid",
261
- "dragonfly",
288
+ "moth",
289
+ "bee",
290
+ "wasp",
262
291
  "ant",
263
- "lobster",
264
- "slug"
292
+ "beetle",
293
+ "ladybug",
294
+ "caterpillar",
295
+ "centipede",
296
+ "millipede",
297
+ "scorpion",
298
+ "spider",
299
+ "tarantula",
300
+ "tick",
301
+ "mite",
302
+ "mosquito",
303
+ "fly",
304
+ "dragonfly",
305
+ "damselfly",
306
+ "grasshopper",
307
+ "cricket",
308
+ "locust",
309
+ "mantis",
310
+ "cockroach",
311
+ "termite",
312
+ "praying mantis",
313
+ "walking stick",
314
+ "stick bug",
315
+ "leaf insect",
316
+ "lacewing",
317
+ "aphid",
318
+ "cicada",
319
+ "thrips",
320
+ "psyllid",
321
+ "scale insect",
322
+ "whitefly",
323
+ "mealybug",
324
+ "planthopper",
325
+ "leafhopper",
326
+ "treehopper",
327
+ "flea",
328
+ "louse",
329
+ "bedbug",
330
+ "flea beetle",
331
+ "weevil",
332
+ "longhorn beetle",
333
+ "leaf beetle",
334
+ "tiger beetle",
335
+ "ground beetle",
336
+ "lady beetle",
337
+ "firefly",
338
+ "click beetle",
339
+ "rove beetle",
340
+ "scarab beetle",
341
+ "dung beetle",
342
+ "stag beetle",
343
+ "rhinoceros beetle",
344
+ "hercules beetle",
345
+ "goliath beetle",
346
+ "jewel beetle",
347
+ "tortoise beetle"
265
348
  ],
266
349
  "spendTier": [
267
350
  "budget"
268
351
  ]
352
+ },
353
+ "groupKeys": [
354
+ {
355
+ "key": "company_id",
356
+ "count": 1000
357
+ }
358
+ ],
359
+ "groupProps": {
360
+ "company_id": {
361
+ "name": {
362
+ "$type": "string"
363
+ },
364
+ "email": [
365
+ "CSM: AK",
366
+ "CSM: Deepak",
367
+ "CSM: Hans",
368
+ "CSM: Justin",
369
+ "CSM: Kaan",
370
+ "CSM: Katie",
371
+ "CSM: Neha",
372
+ "CSM: Rajiv",
373
+ "CSM: Somya",
374
+ "CSM: Tony"
375
+ ],
376
+ "industry": [
377
+ "technology",
378
+ "education",
379
+ "finance",
380
+ "healthcare",
381
+ "retail",
382
+ "manufacturing",
383
+ "transportation",
384
+ "entertainment",
385
+ "media",
386
+ "real estate",
387
+ "construction",
388
+ "hospitality",
389
+ "energy",
390
+ "utilities",
391
+ "agriculture",
392
+ "other"
393
+ ],
394
+ "segment": [
395
+ "SMB",
396
+ "Mid Market",
397
+ "Enterprise"
398
+ ],
399
+ "# active users": [
400
+ 17
401
+ ]
402
+ }
403
+ },
404
+ "scdProps": {
405
+ "role": {
406
+ "type": "user",
407
+ "frequency": "week",
408
+ "timing": "fuzzy",
409
+ "max": 10,
410
+ "values": [
411
+ "admin",
412
+ "collaborator",
413
+ "user",
414
+ "view only",
415
+ "no access"
416
+ ]
417
+ },
418
+ "NPS": {
419
+ "type": "user",
420
+ "frequency": "day",
421
+ "timing": "fuzzy",
422
+ "max": 10,
423
+ "values": {
424
+ "$range": [
425
+ 1,
426
+ 10
427
+ ]
428
+ }
429
+ },
430
+ "MRR": {
431
+ "type": "company_id",
432
+ "frequency": "month",
433
+ "timing": "fixed",
434
+ "max": 10,
435
+ "values": {
436
+ "$range": [
437
+ 2240,
438
+ 7836
439
+ ]
440
+ }
441
+ },
442
+ "AccountHealthScore": {
443
+ "type": "company_id",
444
+ "frequency": "week",
445
+ "timing": "fixed",
446
+ "max": 40,
447
+ "values": {
448
+ "$range": [
449
+ 3,
450
+ 8
451
+ ]
452
+ }
453
+ },
454
+ "plan": {
455
+ "type": "company_id",
456
+ "frequency": "month",
457
+ "timing": "fixed",
458
+ "max": 10,
459
+ "values": [
460
+ "free",
461
+ "basic",
462
+ "premium",
463
+ "enterprise"
464
+ ]
465
+ }
269
466
  }
270
467
  }
@@ -1,3 +1,13 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "simple is best";
3
+ const num_days = 30;
4
+ const num_users = 500;
5
+ const avg_events_per_user = 100;
6
+ let token = "your-mixpanel-token";
7
+
8
+ // ── env overrides ──
9
+ if (process.env.MP_TOKEN) token = process.env.MP_TOKEN;
10
+
1
11
  import Chance from 'chance';
2
12
  const chance = new Chance();
3
13
  import dayjs from "dayjs";
@@ -6,6 +16,7 @@ dayjs.extend(utc);
6
16
  import { uid, comma } from 'ak-tools';
7
17
  import { pickAWinner, weighNumRange, date, integer, weighChoices } from "../../lib/utils/utils.js";
8
18
 
19
+ /** @typedef {import("../../types").Dungeon} Config */
9
20
  const itemCategories = ["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"];
10
21
 
11
22
  const videoCategories = ["funny", "educational", "inspirational", "music", "news", "sports", "cooking", "DIY", "travel", "gaming"];
@@ -50,11 +61,11 @@ const videoCategories = ["funny", "educational", "inspirational", "music", "news
50
61
 
51
62
  /** @type {import('../../types').Dungeon} */
52
63
  const config = {
53
- token: "",
54
- seed: "simple is best",
55
- numDays: 30, //how many days worth1 of data
56
- numEvents: 50000, //how many events
57
- numUsers: 500, //how many users
64
+ token,
65
+ seed: SEED,
66
+ numDays: num_days,
67
+ numEvents: num_users * avg_events_per_user,
68
+ numUsers: num_users,
58
69
  format: 'csv', //csv or json
59
70
  region: "US",
60
71
  hasAnonIds: false, //if true, anonymousIds are created for each user
@@ -166,6 +177,8 @@ const config = {
166
177
  luckyNumber: weighNumRange(42, 420, .3),
167
178
  spiritAnimal: ["duck", "dog", "otter", "penguin", "cat", "elephant", "lion", "cheetah", "giraffe", "zebra", "rhino", "hippo", "whale", "dolphin", "shark", "octopus", "squid", "jellyfish", "starfish", "seahorse", "crab", "lobster", "shrimp", "clam", "snail", "slug", "butterfly", "moth", "bee", "wasp", "ant", "beetle", "ladybug", "caterpillar", "centipede", "millipede", "scorpion", "spider", "tarantula", "tick", "mite", "mosquito", "fly", "dragonfly", "damselfly", "grasshopper", "cricket", "locust", "mantis", "cockroach", "termite", "praying mantis", "walking stick", "stick bug", "leaf insect", "lacewing", "aphid", "cicada", "thrips", "psyllid", "scale insect", "whitefly", "mealybug", "planthopper", "leafhopper", "treehopper", "flea", "louse", "bedbug", "flea beetle", "weevil", "longhorn beetle", "leaf beetle", "tiger beetle", "ground beetle", "lady beetle", "firefly", "click beetle", "rove beetle", "scarab beetle", "dung beetle", "stag beetle", "rhinoceros beetle", "hercules beetle", "goliath beetle", "jewel beetle", "tortoise beetle"],
168
179
  spendTier: ["budget"],
180
+ platform: ["web", "mobile", "web", "mobile", "web", "web", "kiosk", "smartTV"],
181
+ currentTheme: weighChoices(["light", "dark", "custom", "light", "dark"]),
169
182
  },
170
183
  scdProps: {
171
184
  role: {
@@ -258,6 +271,13 @@ const config = {
258
271
 
259
272
  // --- everything hook: simulate cart abandonment ---
260
273
  if (type === "everything") {
274
+ // stamp superProps from profile for consistency
275
+ const profile = meta.profile;
276
+ record.forEach(e => {
277
+ e.platform = profile.platform;
278
+ e.currentTheme = profile.currentTheme;
279
+ });
280
+
261
281
  const hasAddToCart = record.some(e => e.event === "add to cart");
262
282
  const hasCheckout = record.some(e => e.event === "checkout");
263
283
  // users who added to cart but never checked out: remove checkout events (if any slipped through)