make-mp-data 2.0.23 → 2.1.0

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 (38) hide show
  1. package/dungeons/ai-chat-analytics-ed.js +274 -0
  2. package/dungeons/business.js +0 -1
  3. package/dungeons/complex.js +0 -1
  4. package/dungeons/experiments.js +0 -1
  5. package/dungeons/gaming.js +47 -14
  6. package/dungeons/media.js +5 -6
  7. package/dungeons/mil.js +296 -0
  8. package/dungeons/money2020-ed-also.js +277 -0
  9. package/dungeons/money2020-ed.js +579 -0
  10. package/dungeons/sanity.js +0 -1
  11. package/dungeons/scd.js +0 -1
  12. package/dungeons/simple.js +57 -18
  13. package/dungeons/student-teacher.js +0 -1
  14. package/dungeons/text-generation.js +706 -0
  15. package/dungeons/userAgent.js +1 -2
  16. package/entry.js +3 -0
  17. package/index.js +8 -36
  18. package/lib/cli/cli.js +0 -7
  19. package/lib/core/config-validator.js +6 -8
  20. package/lib/generators/adspend.js +1 -1
  21. package/lib/generators/events.js +1 -1
  22. package/lib/generators/funnels.js +293 -242
  23. package/lib/generators/text-bak-old.js +1121 -0
  24. package/lib/generators/text.js +1173 -0
  25. package/lib/orchestrators/mixpanel-sender.js +1 -1
  26. package/lib/templates/abbreviated.d.ts +13 -3
  27. package/lib/templates/defaults.js +311 -169
  28. package/lib/templates/hooks-instructions.txt +434 -0
  29. package/lib/templates/phrases-bak.js +925 -0
  30. package/lib/templates/phrases.js +2066 -0
  31. package/lib/templates/{instructions.txt → schema-instructions.txt} +78 -1
  32. package/lib/templates/scratch-dungeon-template.js +1 -1
  33. package/lib/templates/textQuickTest.js +172 -0
  34. package/lib/utils/ai.js +51 -2
  35. package/lib/utils/utils.js +29 -18
  36. package/package.json +7 -5
  37. package/types.d.ts +319 -4
  38. package/lib/utils/chart.js +0 -206
@@ -0,0 +1,706 @@
1
+ import dayjs from "dayjs";
2
+ import utc from "dayjs/plugin/utc.js";
3
+ import "dotenv/config";
4
+ import { weighNumRange, range, date, initChance, exhaust, choose, integer } from "../lib/utils/utils.js";
5
+ import { createGenerator, generateBatch } from "../lib/generators/text.js";
6
+
7
+ const SEED = "make sdfsme textsdfsdf sdsdfljkhasdflsadf yo";
8
+ dayjs.extend(utc);
9
+ const chance = initChance(SEED);
10
+ const num_users = 1_000;
11
+ const days = 90;
12
+
13
+ /** @typedef {import("../types.js").Dungeon} Dungeon */
14
+
15
+
16
+ // Enterprise support ticket generator with keywords and high authenticity
17
+ const enterpriseSupportGen = createGenerator({
18
+ style: "support",
19
+ tone: "neg",
20
+ intensity: "high",
21
+ formality: "technical",
22
+ keywords: {
23
+ features: ['Dashboard Analytics', 'Export API', 'SSO Login', 'Admin Console', 'User Management'],
24
+ products: ['DataViz Pro', 'Enterprise Suite', 'v3.2.1', 'v2.8.4'],
25
+ technical: ['CORS error', 'timeout', 'memory leak', 'authentication', 'database'],
26
+ errors: ['ERR_CONNECTION_REFUSED', '500 Internal Server', 'TIMEOUT_ERROR', 'AUTH_FAILED'],
27
+ competitors: ['Tableau', 'PowerBI', 'Looker', 'Qlik']
28
+ },
29
+ mixedSentiment: true,
30
+ authenticityLevel: 0.7,
31
+ typos: true,
32
+ typoRate: 0.02,
33
+ specificityLevel: 0.8,
34
+ min: 80,
35
+ max: 300,
36
+ includeMetadata: false,
37
+ // System is now always optimized for speed + uniqueness
38
+ });
39
+
40
+ // Casual review generator with typos and mixed sentiment
41
+ const casualReviewGen = createGenerator({
42
+ style: "review",
43
+ tone: "pos",
44
+ intensity: "medium",
45
+ formality: "casual",
46
+ keywords: {
47
+ features: ['user interface', 'mobile app', 'notifications', 'search function'],
48
+ products: ['the app', 'this tool', 'the platform'],
49
+ metrics: ['response time', 'uptime', 'user experience']
50
+ },
51
+ mixedSentiment: true,
52
+ authenticityLevel: 0.4,
53
+ typos: true,
54
+ typoRate: 0.03,
55
+ sentimentDrift: 0.3,
56
+ min: 30,
57
+ max: 200,
58
+ includeMetadata: false
59
+ });
60
+
61
+ // Technical forum posts with advanced features
62
+ const technicalForumGen = createGenerator({
63
+ style: "forum",
64
+ tone: "neu",
65
+ formality: "technical",
66
+ keywords: {
67
+ technical: ['REST API', 'GraphQL', 'webhooks', 'microservices', 'cloud infrastructure'],
68
+ versions: ['v1.2.3', 'latest', 'beta', 'stable release'],
69
+ errors: ['404 Not Found', 'Rate Limiting', 'SSL Certificate']
70
+ },
71
+ userPersona: true,
72
+ timestamps: true,
73
+ authenticityLevel: 0.6,
74
+ specificityLevel: 0.9,
75
+ min: 50,
76
+ max: 250,
77
+ includeMetadata: false
78
+ });
79
+
80
+ // Search queries with realistic typos
81
+ const searchQueryGen = createGenerator({
82
+ style: "search",
83
+ tone: "neu",
84
+ formality: "casual",
85
+ keywords: {
86
+ features: ['export data', 'user settings', 'help docs', 'pricing'],
87
+ technical: ['API documentation', 'integration guide', 'troubleshooting']
88
+ },
89
+ typos: true,
90
+ typoRate: 0.05,
91
+ min: 2,
92
+ max: 50,
93
+ includeMetadata: false
94
+ });
95
+
96
+ // Business feedback with professional tone
97
+ const businessFeedbackGen = createGenerator({
98
+ style: "feedback",
99
+ tone: "neu",
100
+ formality: "business",
101
+ keywords: {
102
+ metrics: ['ROI', 'efficiency', 'cost savings', 'productivity'],
103
+ features: ['reporting', 'analytics', 'integration capabilities']
104
+ },
105
+ authenticityLevel: 0.3,
106
+ specificityLevel: 0.7,
107
+ min: 40,
108
+ max: 180,
109
+ includeMetadata: false
110
+ });
111
+
112
+ // Chat messages with high authenticity and typos
113
+ const chatMessageGen = createGenerator({
114
+ style: "chat",
115
+ tone: "neu",
116
+ formality: "casual",
117
+ keywords: {
118
+ products: ['the app', 'dashboard', 'mobile version'],
119
+ features: ['notifications', 'sync', 'offline mode']
120
+ },
121
+ mixedSentiment: true,
122
+ authenticityLevel: 0.8,
123
+ typos: true,
124
+ typoRate: 0.04,
125
+ sentimentDrift: 0.4,
126
+ min: 5,
127
+ max: 150,
128
+ includeMetadata: false
129
+ });
130
+
131
+ // Comment generator for charity/fundraiser/wedding sites
132
+ const charityCommentGen = createGenerator({
133
+ style: "comments",
134
+ tone: "pos",
135
+ formality: "casual",
136
+ keywords: {
137
+ causes: ['medical expenses', 'education fund', 'disaster relief', 'animal rescue'],
138
+ events: ['wedding', 'graduation', 'celebration', 'memorial'],
139
+ emotions: ['inspiring', 'heartwarming', 'touching', 'amazing']
140
+ },
141
+ mixedSentiment: false,
142
+ authenticityLevel: 0.9,
143
+ typos: true,
144
+ typoRate: 0.02,
145
+ min: 10,
146
+ max: 100,
147
+ includeMetadata: false
148
+ });
149
+
150
+ // Tweet generator for social media announcements
151
+ const socialTweetGen = createGenerator({
152
+ style: "tweet",
153
+ tone: "neu",
154
+ formality: "casual",
155
+ keywords: {
156
+ announcements: ['new feature', 'product launch', 'company news', 'milestone'],
157
+ hashtags: ['#startup', '#tech', '#innovation', '#community'],
158
+ mentions: ['@followers', '@team', '@customers']
159
+ },
160
+ mixedSentiment: true,
161
+ authenticityLevel: 0.7,
162
+ typos: true,
163
+ typoRate: 0.03,
164
+ sentimentDrift: 0.3,
165
+ min: 10,
166
+ max: 280, // Twitter character limit
167
+ includeMetadata: false
168
+ });
169
+
170
+ // Email communication generator
171
+ const emailGen = createGenerator({
172
+ style: "email",
173
+ tone: "neu",
174
+ formality: "business",
175
+ keywords: {
176
+ features: ['account management', 'billing', 'subscription'],
177
+ products: ['Enterprise Plan', 'Pro Account']
178
+ },
179
+ authenticityLevel: 0.5,
180
+ userPersona: true,
181
+ min: 60,
182
+ max: 300,
183
+ includeMetadata: false
184
+ });
185
+
186
+ // Social Media Generators
187
+ const twitterGen = createGenerator({
188
+ style: "chat",
189
+ tone: "neu",
190
+ formality: "casual",
191
+ keywords: {
192
+ products: ['@company', 'the app', 'your platform'],
193
+ features: ['new update', 'dark mode', 'mobile app', 'API'],
194
+ hashtags: ['#ProductHunt', '#SaaS', '#TechReview', '#UserExperience']
195
+ },
196
+ mixedSentiment: true,
197
+ authenticityLevel: 0.9,
198
+ typos: true,
199
+ typoRate: 0.06,
200
+ sentimentDrift: 0.5,
201
+ min: 10,
202
+ max: 280, // Twitter character limit
203
+ includeMetadata: false
204
+ });
205
+
206
+ const linkedinGen = createGenerator({
207
+ style: "feedback",
208
+ tone: "neu",
209
+ formality: "business",
210
+ keywords: {
211
+ business: ['ROI', 'team productivity', 'workflow efficiency', 'digital transformation'],
212
+ products: ['this solution', 'the platform', 'our implementation'],
213
+ metrics: ['25% time savings', '40% faster', 'reduced costs', 'improved outcomes']
214
+ },
215
+ authenticityLevel: 0.4,
216
+ specificityLevel: 0.8,
217
+ userPersona: true,
218
+ min: 50,
219
+ max: 400,
220
+ includeMetadata: false
221
+ });
222
+
223
+ const redditGen = createGenerator({
224
+ style: "forum",
225
+ tone: "neu",
226
+ formality: "casual",
227
+ keywords: {
228
+ reddit: ['UPDATE:', 'TL;DR', 'Edit:', 'Anyone else?', 'PSA'],
229
+ products: ['this tool', 'the service', 'their platform'],
230
+ community: ['r/SaaS', 'fellow devs', 'community']
231
+ },
232
+ mixedSentiment: true,
233
+ authenticityLevel: 0.8,
234
+ typos: true,
235
+ typoRate: 0.03,
236
+ sentimentDrift: 0.4,
237
+ min: 30,
238
+ max: 500,
239
+ includeMetadata: false
240
+ });
241
+
242
+ // Product Usage Generators
243
+ const bugReportGen = createGenerator({
244
+ style: "support",
245
+ tone: "neg",
246
+ formality: "technical",
247
+ keywords: {
248
+ technical: ['console errors', 'reproduction steps', 'browser version', 'stack trace'],
249
+ errors: ['TypeError', 'ReferenceError', '404', '500', 'timeout'],
250
+ environment: ['Chrome 118', 'macOS Ventura', 'Windows 11', 'mobile Safari']
251
+ },
252
+ authenticityLevel: 0.6,
253
+ specificityLevel: 0.9,
254
+ typos: true,
255
+ typoRate: 0.02,
256
+ min: 80,
257
+ max: 400,
258
+ includeMetadata: false
259
+ });
260
+
261
+ const featureRequestGen = createGenerator({
262
+ style: "feedback",
263
+ tone: "pos",
264
+ formality: "business",
265
+ keywords: {
266
+ requests: ['would love to see', 'feature request', 'enhancement idea', 'suggestion'],
267
+ features: ['bulk export', 'dark mode', 'keyboard shortcuts', 'advanced filters'],
268
+ justification: ['save time', 'improve workflow', 'user experience', 'competitive feature']
269
+ },
270
+ authenticityLevel: 0.5,
271
+ specificityLevel: 0.7,
272
+ min: 40,
273
+ max: 300,
274
+ includeMetadata: false
275
+ });
276
+
277
+ const onboardingGen = createGenerator({
278
+ style: "feedback",
279
+ tone: "neu",
280
+ formality: "casual",
281
+ keywords: {
282
+ onboarding: ['getting started', 'first impression', 'setup process', 'initial experience'],
283
+ products: ['the dashboard', 'onboarding flow', 'tutorial', 'setup wizard'],
284
+ feelings: ['confused', 'excited', 'overwhelmed', 'impressed', 'frustrated']
285
+ },
286
+ mixedSentiment: true,
287
+ authenticityLevel: 0.6,
288
+ typos: true,
289
+ typoRate: 0.04,
290
+ min: 30,
291
+ max: 250,
292
+ includeMetadata: false
293
+ });
294
+
295
+ // Community Interaction Generators
296
+ const tutorialCommentGen = createGenerator({
297
+ style: "forum",
298
+ tone: "pos",
299
+ formality: "casual",
300
+ keywords: {
301
+ tutorial: ['thanks for this', 'helpful tutorial', 'step by step', 'great explanation'],
302
+ products: ['the docs', 'this guide', 'the video', 'walkthrough'],
303
+ learning: ['learned something new', 'finally understand', 'makes sense now']
304
+ },
305
+ authenticityLevel: 0.5,
306
+ min: 20,
307
+ max: 150,
308
+ includeMetadata: false
309
+ });
310
+
311
+ const webinarChatGen = createGenerator({
312
+ style: "chat",
313
+ tone: "neu",
314
+ formality: "casual",
315
+ keywords: {
316
+ webinar: ['great presentation', 'can you share slides', 'question about', 'thanks for hosting'],
317
+ products: ['the demo', 'live demo', 'presentation', 'your product'],
318
+ chat: ['Q:', 'thanks!', 'link?', '+1', 'same question']
319
+ },
320
+ authenticityLevel: 0.7,
321
+ typos: true,
322
+ typoRate: 0.05,
323
+ min: 5,
324
+ max: 100,
325
+ includeMetadata: false
326
+ });
327
+
328
+ /** @type {Dungeon} */
329
+ const dungeon = {
330
+ seed: SEED,
331
+ token: "",
332
+ numDays: days,
333
+ numEvents: num_users * 120, // Increased for more variety
334
+ numUsers: num_users,
335
+ hasAnonIds: false,
336
+ hasSessionIds: true, // Enable for chat flow tracking
337
+ format: "json",
338
+ alsoInferFunnels: true,
339
+ hasLocation: true,
340
+ hasAndroidDevices: false,
341
+ hasIOSDevices: false,
342
+ hasDesktopDevices: false,
343
+ hasBrowser: false,
344
+ hasCampaigns: false,
345
+ isAnonymous: false,
346
+ hasAdSpend: false,
347
+
348
+ hasAvatar: false,
349
+
350
+ batchSize: 1_500_000,
351
+ concurrency: 50,
352
+ writeToDisk: false,
353
+
354
+ // ============= Enhanced Events with New API =============
355
+ events: [
356
+ {
357
+ event: "enterprise_support_ticket",
358
+ weight: 1,
359
+ properties: {
360
+ ticket_text: () => enterpriseSupportGen.generateOne(),
361
+ priority: ["critical", "high", "medium", "low"],
362
+ category: ["authentication", "performance", "integration", "billing", "bug_report"],
363
+ account_tier: ["enterprise", "business", "pro"],
364
+ escalation_level: [1, 1, 1, 2, 3], // Most tickets level 1
365
+ estimated_resolution_hours: weighNumRange(1, 72, 0.3),
366
+ has_screenshot: [true, true, false, false], // 50% have screenshots
367
+ channel: ["email", "phone", "chat", "portal"],
368
+ is_resolved: [true, true, true, false], // 75% resolved
369
+ resolution_time_minutes: weighNumRange(15, 2880, 0.6) // 15min to 2 days
370
+ }
371
+ },
372
+ {
373
+ event: "casual_product_review",
374
+ weight: 1,
375
+ properties: {
376
+ review_text: () => casualReviewGen.generateOne(),
377
+ rating: weighNumRange(1, 5, 0.4), // Skewed toward higher ratings
378
+ product_category: ["mobile_app", "web_platform", "desktop_app", "api"],
379
+ is_verified_purchase: [true, true, true, false], // 75% verified
380
+ helpful_votes: weighNumRange(0, 50, 0.8),
381
+ would_recommend: [true, true, true, false], // 75% would recommend
382
+ usage_duration_days: weighNumRange(1, 365, 0.5)
383
+ }
384
+ },
385
+ {
386
+ event: "technical_forum_post",
387
+ weight: 1,
388
+ properties: {
389
+ post_text: () => technicalForumGen.generateOne(),
390
+ topic_category: ["api_help", "integration", "troubleshooting", "feature_request"],
391
+ upvotes: weighNumRange(0, 25, 0.7),
392
+ has_code_snippet: [true, false, false], // 33% have code
393
+ is_solved: [true, true, false], // 67% solved
394
+ response_count: weighNumRange(0, 15, 0.6),
395
+ user_experience_level: ["beginner", "intermediate", "advanced", "expert"]
396
+ }
397
+ },
398
+ {
399
+ event: "search_query",
400
+ weight: 1, // Most frequent event
401
+ properties: {
402
+ query_text: () => searchQueryGen.generateOne(),
403
+ search_category: ["help", "documentation", "features", "pricing", "support"],
404
+ results_found: weighNumRange(0, 100, 0.3),
405
+ clicked_result: [true, true, false], // 67% click through
406
+ result_position_clicked: weighNumRange(1, 10, 0.8), // Most click top results
407
+ search_duration_seconds: weighNumRange(1, 300, 0.7),
408
+ refined_search: [true, false, false, false] // 25% refine search
409
+ }
410
+ },
411
+ {
412
+ event: "business_feedback",
413
+ weight: 1,
414
+ properties: {
415
+ feedback_text: () => businessFeedbackGen.generateOne(),
416
+ satisfaction_score: weighNumRange(1, 10, 0.3),
417
+ feedback_category: ["feature_request", "improvement", "compliment", "concern"],
418
+ department: ["engineering", "sales", "marketing", "support", "executive"],
419
+ follow_up_requested: [true, false, false], // 33% want follow-up
420
+ urgency: ["low", "medium", "high"],
421
+ implementation_priority: weighNumRange(1, 5, 0.4)
422
+ }
423
+ },
424
+ {
425
+ event: "chat_message",
426
+ weight: 10,
427
+ properties: {
428
+ message_text: () => chatMessageGen.generateOne(),
429
+ chat_type: ["support", "sales", "general", "technical"],
430
+ message_length: weighNumRange(5, 200, 0.6),
431
+ contains_emoji: [true, false, false], // 33% have emojis
432
+ response_time_seconds: weighNumRange(1, 3600, 0.8), // Most respond quickly
433
+ is_agent_response: [true, false], // 50/50 agent vs customer
434
+ satisfaction_rating: [1, 2, 3, 4, 5, null, null], // Not always rated
435
+ requires_escalation: [true, false, false, false] // 25% escalated
436
+ }
437
+ },
438
+ {
439
+ event: "email_correspondence",
440
+ weight: 1,
441
+ properties: {
442
+ email_text: () => emailGen.generateOne(),
443
+ email_type: ["support", "billing", "account", "marketing_opt_out"],
444
+ thread_length: weighNumRange(1, 8, 0.7),
445
+ priority: ["normal", "high", "urgent"],
446
+ has_attachment: [true, false, false, false], // 25% have attachments
447
+ auto_response: [true, false, false, false], // 25% auto-responses
448
+ response_time_hours: weighNumRange(0.25, 48, 0.5),
449
+ customer_type: ["new", "existing", "enterprise", "trial"]
450
+ }
451
+ },
452
+
453
+ // Social Media Events
454
+ {
455
+ event: "twitter_post",
456
+ weight: 1,
457
+ properties: {
458
+ post_text: () => twitterGen.generateOne(),
459
+ character_count: weighNumRange(10, 280, 0.4),
460
+ has_hashtags: [true, true, false], // 67% have hashtags
461
+ has_mentions: [true, false, false], // 33% have mentions
462
+ engagement_type: ["like", "retweet", "reply", "quote_tweet"],
463
+ follower_count: weighNumRange(50, 50000, 0.7),
464
+ is_thread: [true, false, false, false], // 25% are threads
465
+ posted_via: ["web", "mobile", "api", "third_party"]
466
+ }
467
+ },
468
+ {
469
+ event: "linkedin_post",
470
+ weight: 1,
471
+ properties: {
472
+ post_text: () => linkedinGen.generateOne(),
473
+ post_type: ["update", "article", "job_posting", "company_news"],
474
+ industry_tag: ["technology", "business", "marketing", "sales", "hr"],
475
+ connection_level: ["1st", "2nd", "3rd", "not_connected"],
476
+ engagement_score: weighNumRange(0, 1000, 0.6),
477
+ is_sponsored: [true, false, false, false], // 25% sponsored
478
+ company_size: ["startup", "small", "medium", "large", "enterprise"]
479
+ }
480
+ },
481
+ {
482
+ event: "reddit_comment",
483
+ weight: 1,
484
+ properties: {
485
+ comment_text: () => redditGen.generateOne(),
486
+ subreddit: ["r/SaaS", "r/webdev", "r/startups", "r/technology", "r/programming"],
487
+ comment_depth: weighNumRange(0, 10, 0.8), // Most are top-level
488
+ upvotes: weighNumRange(-5, 500, 0.5),
489
+ is_edited: [true, false, false], // 33% edited
490
+ account_age_days: weighNumRange(1, 3650, 0.3),
491
+ is_op: [true, false, false, false], // 25% from original poster
492
+ parent_comment_id: () => chance.hash({ length: 8 })
493
+ }
494
+ },
495
+
496
+ // Product Usage Events
497
+ {
498
+ event: "bug_report_submitted",
499
+ weight: 1,
500
+ properties: {
501
+ report_text: () => bugReportGen.generateOne(),
502
+ severity: ["critical", "high", "medium", "low"],
503
+ bug_category: ["ui", "api", "performance", "data", "security"],
504
+ steps_to_reproduce: weighNumRange(2, 10, 0.4),
505
+ browser_info: ["Chrome 118", "Firefox 119", "Safari 17", "Edge 118"],
506
+ os_info: ["Windows 11", "macOS Ventura", "Ubuntu 22.04", "iOS 17"],
507
+ is_reproducible: [true, true, true, false], // 75% reproducible
508
+ affects_workflow: [true, true, false], // 67% affect workflow
509
+ has_screenshot: [true, true, false], // 67% include screenshots
510
+ reporter_role: ["admin", "user", "developer", "qa_tester"]
511
+ }
512
+ },
513
+ {
514
+ event: "feature_request_submitted",
515
+ weight: 1,
516
+ properties: {
517
+ request_text: () => featureRequestGen.generateOne(),
518
+ request_category: ["ui_improvement", "new_feature", "integration", "performance"],
519
+ priority_level: ["nice_to_have", "important", "critical", "blocker"],
520
+ estimated_users_affected: weighNumRange(1, 10000, 0.6),
521
+ business_impact: ["low", "medium", "high", "critical"],
522
+ similar_requests: weighNumRange(0, 50, 0.7),
523
+ requester_plan: ["free", "basic", "pro", "enterprise"],
524
+ implementation_complexity: ["simple", "moderate", "complex", "very_complex"],
525
+ votes: weighNumRange(0, 200, 0.5)
526
+ }
527
+ },
528
+ {
529
+ event: "onboarding_feedback",
530
+ weight: 1,
531
+ properties: {
532
+ feedback_text: () => onboardingGen.generateOne(),
533
+ onboarding_step: ["signup", "email_verification", "profile_setup", "first_use", "tutorial"],
534
+ completion_rate: weighNumRange(0, 100, 0.3), // Most struggle
535
+ time_spent_minutes: weighNumRange(1, 120, 0.6),
536
+ dropped_at_step: ["signup", "tutorial", "first_action", "payment", "completed"],
537
+ help_docs_accessed: [true, false, false], // 33% read docs
538
+ support_contacted: [true, false, false, false], // 25% contact support
539
+ device_type: ["desktop", "mobile", "tablet"],
540
+ signup_source: ["organic", "paid_ad", "referral", "social_media"]
541
+ }
542
+ },
543
+
544
+ // Community Interaction Events
545
+ {
546
+ event: "tutorial_comment_posted",
547
+ weight: 1,
548
+ properties: {
549
+ comment_text: () => tutorialCommentGen.generateOne(),
550
+ tutorial_section: ["getting_started", "advanced_features", "api_guide", "troubleshooting"],
551
+ helpfulness_rating: weighNumRange(1, 5, 0.4), // Skewed positive
552
+ comment_type: ["question", "clarification", "praise", "suggestion", "correction"],
553
+ user_experience_level: ["beginner", "intermediate", "advanced", "expert"],
554
+ tutorial_completion: weighNumRange(0, 100, 0.5),
555
+ follow_up_questions: weighNumRange(0, 5, 0.8),
556
+ marked_as_helpful: [true, true, false], // 67% helpful
557
+ time_on_tutorial_minutes: weighNumRange(2, 60, 0.6)
558
+ }
559
+ },
560
+ {
561
+ event: "webinar_chat_message",
562
+ weight: 1,
563
+ properties: {
564
+ message_text: () => webinarChatGen.generateOne(),
565
+ webinar_topic: ["product_demo", "feature_update", "best_practices", "q_and_a"],
566
+ message_timestamp_minutes: weighNumRange(0, 90, 0.5), // Throughout webinar
567
+ attendee_count: weighNumRange(50, 1000, 0.4),
568
+ is_question: [true, true, false], // 67% are questions
569
+ is_answered: [true, false, false], // 33% get answered
570
+ reaction_emoji: ["👍", "❤️", "😍", "🤔", "👏", null, null], // Some have reactions
571
+ is_moderator: [true, false, false, false, false], // 20% from moderators
572
+ attendee_type: ["customer", "prospect", "partner", "employee"]
573
+ }
574
+ },
575
+
576
+ // New text types - Comments for charity/fundraiser/wedding sites
577
+ {
578
+ event: "charity_comment_posted",
579
+ weight: 8,
580
+ properties: {
581
+ comment_text: () => charityCommentGen.generateOne(),
582
+ comment_type: ["donation_thanks", "support_message", "congratulations", "encouragement"],
583
+ cause_category: ["medical", "education", "disaster_relief", "animal_welfare", "community"],
584
+ donation_amount: weighNumRange(5, 500, 0.7), // Most small donations
585
+ is_anonymous: [true, false, false], // 33% anonymous
586
+ includes_prayer: [true, false, false, false], // 25% include prayers
587
+ emotional_tone: ["supportive", "inspiring", "grateful", "hopeful"],
588
+ relationship_to_cause: ["friend", "family", "stranger", "community_member"]
589
+ }
590
+ },
591
+ {
592
+ event: "wedding_comment_posted",
593
+ weight: 6,
594
+ properties: {
595
+ comment_text: () => charityCommentGen.generateOne(), // Reuse same generator
596
+ comment_type: ["congratulations", "well_wishes", "memory_share", "blessing"],
597
+ wedding_phase: ["engagement", "ceremony", "reception", "honeymoon"],
598
+ includes_emoji: [true, true, false], // 67% have emojis
599
+ relationship_to_couple: ["family", "friend", "coworker", "acquaintance"],
600
+ comment_length: weighNumRange(10, 150, 0.6),
601
+ is_public: [true, true, true, false] // 75% public
602
+ }
603
+ },
604
+ {
605
+ event: "social_media_tweet",
606
+ weight: 15,
607
+ properties: {
608
+ tweet_text: () => socialTweetGen.generateOne(),
609
+ tweet_type: ["announcement", "update", "opinion", "question", "share"],
610
+ character_count: weighNumRange(10, 280, 0.4),
611
+ has_hashtags: [true, true, false], // 67% have hashtags
612
+ has_mentions: [true, false, false], // 33% have mentions
613
+ has_media: [true, false, false, false], // 25% have images/videos
614
+ engagement_score: weighNumRange(0, 1000, 0.8), // Most get low engagement
615
+ is_retweet: [true, false, false, false], // 25% are retweets
616
+ time_of_day: ["morning", "afternoon", "evening", "night"],
617
+ device_type: ["mobile", "desktop", "tablet"]
618
+ }
619
+ },
620
+ {
621
+ event: "company_announcement_tweet",
622
+ weight: 3,
623
+ properties: {
624
+ tweet_text: () => socialTweetGen.generateOne(),
625
+ announcement_type: ["product_launch", "milestone", "hiring", "partnership", "event"],
626
+ urgency: ["low", "medium", "high"],
627
+ target_audience: ["customers", "investors", "employees", "general_public"],
628
+ includes_link: [true, true, false], // 67% include links
629
+ is_scheduled: [true, false], // 50% are scheduled posts
630
+ campaign_tag: ["product", "brand", "recruitment", "pr", "organic"],
631
+ expected_reach: weighNumRange(100, 50000, 0.6)
632
+ }
633
+ },
634
+
635
+ // Batch generation examples for related content
636
+ {
637
+ event: "api_discussion_thread",
638
+ weight: 1,
639
+ properties: {
640
+ // Using generateBatch for related forum posts in a thread
641
+ thread_messages: () => generateBatch({
642
+ n: integer(2, 6), // 2-6 messages per thread
643
+ style: 'forum',
644
+ tone: 'neu',
645
+ related: true,
646
+ sharedContext: 'API integration issues',
647
+ keywords: {
648
+ technical: ['REST API', 'authentication', 'rate limiting', 'webhooks'],
649
+ errors: ['401 Unauthorized', '429 Too Many Requests', 'timeout']
650
+ },
651
+ min: 40,
652
+ max: 200,
653
+ includeMetadata: false
654
+ }),
655
+ api_version: ["v1", "v2", "v3", "beta"],
656
+ severity: ["low", "medium", "high", "critical"],
657
+ affects_production: [true, false, false], // 33% affect production
658
+ resolution_status: ["open", "investigating", "resolved", "closed"]
659
+ }
660
+ }
661
+ ],
662
+
663
+ funnels: [
664
+
665
+ ],
666
+
667
+ superProps: {
668
+ product_tier: ["free", "basic", "pro", "enterprise"],
669
+ data_center: ["us-east", "us-west", "eu-central", "asia-pacific"],
670
+ feature_flags: () => {
671
+ // Dynamic feature flags
672
+ const flags = ["new_dashboard", "beta_api", "advanced_analytics", "mobile_v2"];
673
+ // @ts-ignore
674
+ return flags.filter(() => chance.bool({likelihood: 5})); // 5% chance each flag is enabled
675
+ }
676
+ },
677
+
678
+ userProps: {
679
+ account_age_days: weighNumRange(0, 1095, 0.4),
680
+ user_tier: ["free", "free", "basic", "pro", "enterprise"],
681
+ signup_method: ["email", "google", "microsoft", "sso", "invite"],
682
+ notification_enabled: [true, true, false],
683
+ has_purchased: [true, false, false],
684
+ primary_use_case: ["analytics", "reporting", "integration", "automation"],
685
+ company_size: ["1-10", "11-50", "51-200", "201-1000", "1000+"],
686
+ industry: ["technology", "finance", "healthcare", "retail", "education", "other"],
687
+ technical_expertise: ["beginner", "intermediate", "advanced", "expert"],
688
+ engagement_score: weighNumRange(0, 100, 0.3), // Most users low engagement
689
+ last_active_days_ago: weighNumRange(0, 30, 0.6),
690
+ preferred_communication: ["email", "chat", "phone", "self_service"]
691
+ },
692
+
693
+ // ============= Slowly Changing Dimensions =============
694
+ scdProps: {},
695
+
696
+ // ============= Lookup Tables =============
697
+ lookupTables: [
698
+
699
+ ],
700
+
701
+ hook: function (record, type, meta) {
702
+ return record;
703
+ }
704
+ };
705
+
706
+ export default dungeon;