@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
@@ -5,15 +5,18 @@
5
5
  "weight": 10,
6
6
  "properties": {
7
7
  "page": [
8
- "/blog",
9
8
  "/",
9
+ "/help",
10
+ "/account",
11
+ "/pricing",
12
+ "/product",
10
13
  "/about",
11
- "/help"
14
+ "/blog"
12
15
  ],
13
16
  "utm_source": [
14
- "facebook",
15
- "google",
16
17
  "$organic",
18
+ "google",
19
+ "facebook",
17
20
  "twitter",
18
21
  "linkedin"
19
22
  ]
@@ -54,8 +57,8 @@
54
57
  "properties": {
55
58
  "query_length": {
56
59
  "$range": [
57
- 8,
58
- 41
60
+ 7,
61
+ 45
59
62
  ]
60
63
  },
61
64
  "resultsReturned": {
@@ -65,14 +68,13 @@
65
68
  ]
66
69
  },
67
70
  "category": [
71
+ "Handmade",
72
+ "Sports",
68
73
  "Garden",
69
- "Automotive",
70
- "Home",
71
- "Outdoors",
74
+ "Baby",
72
75
  "Pet",
73
- "Books",
74
- "Handmade",
75
- "Toys"
76
+ "Music",
77
+ "Beauty"
76
78
  ]
77
79
  }
78
80
  },
@@ -85,14 +87,15 @@
85
87
  false
86
88
  ],
87
89
  "itemCategory": [
88
- "Toys",
89
- "Electronics",
90
- "Computers",
90
+ "Music",
91
+ "Kids",
91
92
  "Beauty",
92
- "Outdoors",
93
+ "Home",
93
94
  "Appliances",
94
- "Music",
95
- "Garden"
95
+ "Games",
96
+ "Office",
97
+ "Books",
98
+ "Entertainment"
96
99
  ],
97
100
  "price": {
98
101
  "$range": [
@@ -119,11 +122,11 @@
119
122
  ]
120
123
  },
121
124
  "itemCategory": [
122
- "Baby",
123
125
  "Wedding",
124
- "Outdoors",
125
126
  "Software",
126
- "Books"
127
+ "Home",
128
+ "Outdoors",
129
+ "Handmade"
127
130
  ],
128
131
  "numItems": {
129
132
  "$range": [
@@ -168,12 +171,12 @@
168
171
  "weight": 6,
169
172
  "properties": {
170
173
  "videoCategory": [
171
- "music",
172
174
  "news",
173
- "funny",
174
- "travel",
175
+ "educational",
175
176
  "inspirational",
176
- "educational"
177
+ "cooking",
178
+ "travel",
179
+ "music"
177
180
  ],
178
181
  "watchTimeSec": {
179
182
  "$range": [
@@ -218,15 +221,12 @@
218
221
  ]
219
222
  },
220
223
  "itemCategory": [
221
- "Food",
222
- "Wedding",
223
- "Office",
224
- "Outdoors",
225
- "Home",
224
+ "Baby",
226
225
  "Appliances",
227
- "Entertainment",
228
- "Health",
229
- "Software"
226
+ "Outdoors",
227
+ "Office",
228
+ "Software",
229
+ "Books"
230
230
  ],
231
231
  "hasReviewText": [
232
232
  true,
@@ -258,12 +258,12 @@
258
258
  "properties": {
259
259
  "itemCategory": [
260
260
  "Books",
261
- "Games",
262
- "Beauty",
263
261
  "Toys",
262
+ "Entertainment",
263
+ "Appliances",
264
+ "Food",
264
265
  "Software",
265
- "Movies",
266
- "Office"
266
+ "Computers"
267
267
  ],
268
268
  "price": {
269
269
  "$range": [
@@ -381,14 +381,15 @@
381
381
  "weight": 8,
382
382
  "properties": {
383
383
  "category": [
384
+ "Games",
384
385
  "Smart Home",
385
- "Electronics",
386
- "Pet",
387
- "Software",
388
- "Books",
389
- "Movies",
390
386
  "Computers",
391
- "Music"
387
+ "Outdoors",
388
+ "Home",
389
+ "Electronics",
390
+ "Entertainment",
391
+ "Health",
392
+ "Baby"
392
393
  ],
393
394
  "sortBy": [
394
395
  "popular",
@@ -420,14 +421,13 @@
420
421
  ]
421
422
  },
422
423
  "itemCategory": [
423
- "Wedding",
424
- "Art",
424
+ "Books",
425
+ "Games",
426
+ "Beauty",
427
+ "Toys",
425
428
  "Software",
426
429
  "Movies",
427
- "Electronics",
428
- "Toys",
429
- "Baby",
430
- "Appliances"
430
+ "Office"
431
431
  ]
432
432
  }
433
433
  },
@@ -486,41 +486,13 @@
486
486
  }
487
487
  }
488
488
  ],
489
- "superProps": {
490
- "theme": [
491
- "light",
492
- "dark",
493
- "custom"
494
- ]
495
- },
496
- "userProps": {
497
- "title": {
498
- "$type": "string"
499
- },
500
- "luckyNumber": {
501
- "$range": [
502
- 123,
503
- 346
504
- ]
505
- },
506
- "spiritAnimal": [
507
- "penguin",
508
- "otter",
509
- "elephant",
510
- "mite",
511
- "tick",
512
- "goliath beetle",
513
- "mosquito",
514
- "damselfly",
515
- "hercules beetle"
516
- ]
517
- },
518
489
  "funnels": [
519
490
  {
520
491
  "sequence": [
521
492
  "page view",
522
493
  "sign up"
523
494
  ],
495
+ "name": "Signup Funnel",
524
496
  "isFirstFunnel": true,
525
497
  "conversionRate": 55,
526
498
  "timeToConvert": 1,
@@ -533,6 +505,7 @@
533
505
  "add to cart",
534
506
  "checkout"
535
507
  ],
508
+ "name": "Purchase Funnel",
536
509
  "conversionRate": 35,
537
510
  "timeToConvert": 3,
538
511
  "weight": 8
@@ -543,6 +516,7 @@
543
516
  "watch video",
544
517
  "share content"
545
518
  ],
519
+ "name": "Content Engagement",
546
520
  "conversionRate": 40,
547
521
  "timeToConvert": 2,
548
522
  "weight": 6
@@ -552,6 +526,7 @@
552
526
  "view item",
553
527
  "rate item"
554
528
  ],
529
+ "name": "Review Funnel",
555
530
  "conversionRate": 25,
556
531
  "timeToConvert": 5,
557
532
  "weight": 3
@@ -563,6 +538,7 @@
563
538
  "compare items",
564
539
  "add to cart"
565
540
  ],
541
+ "name": "Browse to Cart",
566
542
  "conversionRate": 30,
567
543
  "timeToConvert": 3,
568
544
  "weight": 7
@@ -573,6 +549,7 @@
573
549
  "notification clicked",
574
550
  "view item"
575
551
  ],
552
+ "name": "Notification Engagement",
576
553
  "conversionRate": 45,
577
554
  "timeToConvert": 1,
578
555
  "weight": 4
@@ -585,6 +562,7 @@
585
562
  "add to cart",
586
563
  "checkout"
587
564
  ],
565
+ "name": "Wishlist to Purchase",
588
566
  "conversionRate": 20,
589
567
  "timeToConvert": 7,
590
568
  "weight": 2
@@ -595,6 +573,7 @@
595
573
  "leave review",
596
574
  "invite friend"
597
575
  ],
576
+ "name": "Post-Purchase Advocacy",
598
577
  "conversionRate": 15,
599
578
  "timeToConvert": 14
600
579
  },
@@ -606,6 +585,7 @@
606
585
  "apply coupon",
607
586
  "checkout"
608
587
  ],
588
+ "name": "Coupon Purchase Flow",
609
589
  "conversionRate": 30,
610
590
  "timeToConvert": 2,
611
591
  "weight": 9
@@ -617,6 +597,7 @@
617
597
  "notification clicked",
618
598
  "checkout"
619
599
  ],
600
+ "name": "Newsletter to Purchase",
620
601
  "conversionRate": 10,
621
602
  "timeToConvert": 14,
622
603
  "weight": 3
@@ -627,9 +608,117 @@
627
608
  "update profile",
628
609
  "checkout"
629
610
  ],
611
+ "name": "Support Recovery",
630
612
  "conversionRate": 20,
631
613
  "timeToConvert": 7,
632
614
  "weight": 10
633
615
  }
634
- ]
616
+ ],
617
+ "superProps": {
618
+ "theme": [
619
+ "light",
620
+ "dark",
621
+ "custom"
622
+ ]
623
+ },
624
+ "userProps": {
625
+ "title": {
626
+ "$type": "string"
627
+ },
628
+ "luckyNumber": {
629
+ "$range": [
630
+ 117,
631
+ 346
632
+ ]
633
+ },
634
+ "spiritAnimal": [
635
+ "duck",
636
+ "dog",
637
+ "otter",
638
+ "penguin",
639
+ "cat",
640
+ "elephant",
641
+ "lion",
642
+ "cheetah",
643
+ "giraffe",
644
+ "zebra",
645
+ "rhino",
646
+ "hippo",
647
+ "whale",
648
+ "dolphin",
649
+ "shark",
650
+ "octopus",
651
+ "squid",
652
+ "jellyfish",
653
+ "starfish",
654
+ "seahorse",
655
+ "crab",
656
+ "lobster",
657
+ "shrimp",
658
+ "clam",
659
+ "snail",
660
+ "slug",
661
+ "butterfly",
662
+ "moth",
663
+ "bee",
664
+ "wasp",
665
+ "ant",
666
+ "beetle",
667
+ "ladybug",
668
+ "caterpillar",
669
+ "centipede",
670
+ "millipede",
671
+ "scorpion",
672
+ "spider",
673
+ "tarantula",
674
+ "tick",
675
+ "mite",
676
+ "mosquito",
677
+ "fly",
678
+ "dragonfly",
679
+ "damselfly",
680
+ "grasshopper",
681
+ "cricket",
682
+ "locust",
683
+ "mantis",
684
+ "cockroach",
685
+ "termite",
686
+ "praying mantis",
687
+ "walking stick",
688
+ "stick bug",
689
+ "leaf insect",
690
+ "lacewing",
691
+ "aphid",
692
+ "cicada",
693
+ "thrips",
694
+ "psyllid",
695
+ "scale insect",
696
+ "whitefly",
697
+ "mealybug",
698
+ "planthopper",
699
+ "leafhopper",
700
+ "treehopper",
701
+ "flea",
702
+ "louse",
703
+ "bedbug",
704
+ "flea beetle",
705
+ "weevil",
706
+ "longhorn beetle",
707
+ "leaf beetle",
708
+ "tiger beetle",
709
+ "ground beetle",
710
+ "lady beetle",
711
+ "firefly",
712
+ "click beetle",
713
+ "rove beetle",
714
+ "scarab beetle",
715
+ "dung beetle",
716
+ "stag beetle",
717
+ "rhinoceros beetle",
718
+ "hercules beetle",
719
+ "goliath beetle",
720
+ "jewel beetle",
721
+ "tortoise beetle"
722
+ ]
723
+ }
635
724
  }
@@ -1,3 +1,13 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "simple is best";
3
+ const num_days = 100;
4
+ const num_users = 2_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
  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 { 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"];
@@ -33,11 +44,11 @@ const videoCategories = ["funny", "educational", "inspirational", "music", "news
33
44
 
34
45
  /** @type {import('../types.js').Dungeon} */
35
46
  const config = {
36
- token: "",
37
- seed: "simple is best",
38
- numDays: 100, //how many days worth1 of data
39
- numEvents: 250_000, //how many events
40
- numUsers: 2_500, //how many users
47
+ token,
48
+ seed: SEED,
49
+ numDays: num_days,
50
+ numEvents: num_users * avg_events_per_user,
51
+ numUsers: num_users,
41
52
  format: 'json', //csv or json
42
53
  region: "US",
43
54
  hasAnonIds: false, //if true, anonymousIds are created for each user
@@ -52,7 +63,6 @@ const config = {
52
63
  isAnonymous: false,
53
64
  alsoInferFunnels: false,
54
65
  concurrency: 1,
55
- batchSize: 2_500_000,
56
66
  writeToDisk: false,
57
67
 
58
68
  events: [
@@ -365,6 +375,7 @@ const config = {
365
375
  each key should be an array or function reference
366
376
  */
367
377
  userProps: {
378
+ theme: ["light", "dark", "custom", "light", "dark"],
368
379
  title: chance.profession.bind(chance),
369
380
  luckyNumber: weighNumRange(42, 420, .3),
370
381
  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"]
@@ -381,7 +392,13 @@ const config = {
381
392
  lookupTables: [],
382
393
  hook: function (record, type, meta) {
383
394
 
384
- // no hooks!
395
+ if (type === "everything") {
396
+ const profile = meta.profile;
397
+ record.forEach(e => {
398
+ e.theme = profile.theme;
399
+ });
400
+ }
401
+
385
402
  return record;
386
403
  }
387
404
  };
@@ -915,10 +915,12 @@
915
915
  "event": "api_discussion_thread",
916
916
  "properties": {
917
917
  "thread_messages": [
918
- "Re: API integration issues - so like Login problems actually trial period dashboard won't load",
919
- "Re: API integration issues - using the suite for work stuff. like response time does what it says i guess - actually forget what i said. caching layers does what it says i guess.",
920
- "System specs: Chrome 92, macOS Monterey Issue: Dashboard shows blank page Steps to reproduce: 1. Access mobile app 2. Attempt sync 3. Wait for completion 4. Sync fails Anyone else experiencing this?. (regarding the API integration issues)",
921
- "Billing questions speaking of which enterprise setup permissions are wrong. This is about the API integration issues."
918
+ "About the API integration issues: using the library for work stuff. Now, carousels does what it says i guess, it's a the infrastructure. timeout - like the integration exists",
919
+ "Re: API integration issues - Issue: Dashboard shows blank page Steps to reproduce: 1. Access mobile app 2. Attempt sync 3. Wait for completion 4. Sync fails Anyone else experiencing this?",
920
+ "basically Interface questions beta testing reports are empty also Is there an alternative? (regarding the API integration issues)",
921
+ "it's a the ML model. Well, wait actually. Now, using the software for work stuff. Still, actually forget what i said. Now, it's a the console. Now, the search is there. This is about the API integration issues.",
922
+ "Re: API integration issues - System specs: Chrome 92, macOS Monterey Issue: Sync fails with error 500 Steps to reproduce: 1. authentication - Access mobile app 2. Attempt sync 3. Wait for completion 4.",
923
+ "About the API integration issues: the deduplication is there, using the marketplace (I checked) for work stuff. That said, lots of issues to fix"
922
924
  ],
923
925
  "api_version": [
924
926
  "v1",
@@ -946,6 +948,7 @@
946
948
  },
947
949
  {
948
950
  "event": "satisfaction_survey_triggered",
951
+ "isStrictEvent": true,
949
952
  "properties": {
950
953
  "survey_type": [
951
954
  "quarterly_nps"
@@ -1,16 +1,23 @@
1
+ // ── TWEAK THESE ──
2
+ const SEED = "SUPER DUPER DANGEROUS BROOO";
3
+ const num_days = 92;
4
+ const num_users = 8_000;
5
+ const avg_events_per_user = 120;
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 dayjs from "dayjs";
2
12
  import utc from "dayjs/plugin/utc.js";
3
13
  import "dotenv/config";
4
14
  import { weighNumRange, range, date, initChance, exhaust, choose, integer } from "../../lib/utils/utils.js";
5
15
  import { createTextGenerator, generateBatch } from "../../lib/generators/text.js";
6
16
 
7
- const SEED = "SUPER DUPER DANGEROUS BROOO";
8
17
  dayjs.extend(utc);
9
18
  const chance = initChance(SEED);
10
- const num_users = 8_000;
11
- const days = 92;
12
19
 
13
- /** @typedef {import("../types.js").Dungeon} Dungeon */
20
+ /** @typedef {import("../../types").Dungeon} Dungeon */
14
21
 
15
22
  /*
16
23
  * ============================================================================
@@ -398,9 +405,9 @@ const webinarChatGen = createTextGenerator({
398
405
  /** @type {Dungeon} */
399
406
  const dungeon = {
400
407
  seed: SEED,
401
- token: "",
402
- numDays: days,
403
- numEvents: num_users * 120, // Increased for more variety
408
+ token,
409
+ numDays: num_days,
410
+ numEvents: num_users * avg_events_per_user,
404
411
  numUsers: num_users,
405
412
  hasAnonIds: false,
406
413
  hasSessionIds: true, // Enable for chat flow tracking
@@ -416,7 +423,6 @@ const dungeon = {
416
423
  hasAdSpend: false,
417
424
  hasAvatar: false,
418
425
 
419
- batchSize: 2_500_000,
420
426
  concurrency: 1,
421
427
  writeToDisk: false,
422
428
 
@@ -771,6 +777,8 @@ const dungeon = {
771
777
  preferred_communication: ["email", "chat", "phone", "self_service"],
772
778
  is_power_user: [false],
773
779
  risk_level: ["healthy"],
780
+ product_tier: ["free", "basic", "pro", "enterprise"],
781
+ data_center: ["us-east", "us-west", "eu-central", "asia-pacific"],
774
782
  },
775
783
 
776
784
  // ============= Slowly Changing Dimensions =============
@@ -805,6 +813,13 @@ const dungeon = {
805
813
 
806
814
  // --- everything hook: enterprise users get a satisfaction survey event ---
807
815
  if (type === "everything" && meta && meta.profile) {
816
+ // stamp superProps from profile for consistency (skip feature_flags — intentionally per-event)
817
+ const profile = meta.profile;
818
+ record.forEach(e => {
819
+ e.product_tier = profile.product_tier;
820
+ e.data_center = profile.data_center;
821
+ });
822
+
808
823
  if (meta.profile.user_tier === "enterprise" && record.length > 5) {
809
824
  const lastEvent = record[record.length - 1];
810
825
  record.push({
File without changes