@ak--47/dungeon-master 1.0.0 → 1.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 (103) hide show
  1. package/README.md +7 -7
  2. package/dungeons/technical/ad-spend-schema.json +128 -0
  3. package/dungeons/technical/ad-spend.js +116 -0
  4. package/dungeons/technical/anonymous-users-schema.json +91 -0
  5. package/dungeons/technical/anonymous-users.js +102 -0
  6. package/dungeons/technical/array-of-object-lookup-schema.json +191 -0
  7. package/dungeons/{array-of-object-lookup.js → technical/array-of-object-lookup.js} +11 -4
  8. package/dungeons/technical/experiments-schema.json +197 -0
  9. package/dungeons/technical/experiments.js +168 -0
  10. package/dungeons/technical/foobar-schema.json +362 -0
  11. package/dungeons/{foobar.js → technical/foobar.js} +2 -2
  12. package/dungeons/technical/group-analytics-schema.json +149 -0
  13. package/dungeons/technical/group-analytics.js +151 -0
  14. package/dungeons/technical/mirror-strategies-schema.json +84 -0
  15. package/dungeons/technical/mirror-strategies.js +126 -0
  16. package/dungeons/technical/nested-objects-schema.json +145 -0
  17. package/dungeons/technical/nested-objects.js +207 -0
  18. package/dungeons/technical/retention-cadence-schema.json +37 -0
  19. package/dungeons/{retention-cadence.js → technical/retention-cadence.js} +1 -1
  20. package/dungeons/technical/sanity-schema.json +185 -0
  21. package/dungeons/{sanity.js → technical/sanity.js} +3 -2
  22. package/dungeons/technical/scale-test-schema.json +70 -0
  23. package/dungeons/technical/scale-test.js +90 -0
  24. package/dungeons/technical/scd-schema.json +270 -0
  25. package/dungeons/{scd.js → technical/scd.js} +19 -10
  26. package/dungeons/technical/simple-schema.json +278 -0
  27. package/dungeons/{simple.js → technical/simple.js} +6 -6
  28. package/dungeons/technical/simplest-schema.json +635 -0
  29. package/dungeons/{simplest.js → technical/simplest.js} +6 -6
  30. package/dungeons/technical/text-generation-schema.json +1059 -0
  31. package/dungeons/{text-generation.js → technical/text-generation.js} +23 -9
  32. package/dungeons/vertical/community-schema.json +557 -0
  33. package/dungeons/vertical/community.js +788 -0
  34. package/dungeons/vertical/devtools-schema.json +580 -0
  35. package/dungeons/vertical/devtools.js +837 -0
  36. package/dungeons/vertical/ecommerce-schema.json +586 -0
  37. package/dungeons/{ecommerce.js → vertical/ecommerce.js} +34 -3
  38. package/dungeons/vertical/education-schema.json +697 -0
  39. package/dungeons/{education.js → vertical/education.js} +54 -36
  40. package/dungeons/vertical/fintech-schema.json +563 -0
  41. package/dungeons/{fintech.js → vertical/fintech.js} +91 -53
  42. package/dungeons/vertical/fitness-schema.json +508 -0
  43. package/dungeons/vertical/fitness.js +802 -0
  44. package/dungeons/vertical/food-delivery-schema.json +678 -0
  45. package/dungeons/{food.js → vertical/food-delivery.js} +51 -23
  46. package/dungeons/vertical/gaming-schema.json +394 -0
  47. package/dungeons/{gaming.js → vertical/gaming.js} +9 -7
  48. package/dungeons/vertical/healthcare-schema.json +527 -0
  49. package/dungeons/vertical/healthcare.js +769 -0
  50. package/dungeons/vertical/insurance-application-schema.json +466 -0
  51. package/dungeons/{insurance-application.js → vertical/insurance-application.js} +33 -29
  52. package/dungeons/vertical/logistics-schema.json +552 -0
  53. package/dungeons/vertical/logistics.js +793 -0
  54. package/dungeons/vertical/marketplace-schema.json +511 -0
  55. package/dungeons/vertical/marketplace.js +844 -0
  56. package/dungeons/vertical/media-schema.json +787 -0
  57. package/dungeons/{media.js → vertical/media.js} +94 -16
  58. package/dungeons/vertical/rpg-schema.json +654 -0
  59. package/dungeons/{rpg.js → vertical/rpg.js} +78 -57
  60. package/dungeons/vertical/sass-schema.json +653 -0
  61. package/dungeons/{sass.js → vertical/sass.js} +49 -23
  62. package/dungeons/vertical/social-schema.json +552 -0
  63. package/dungeons/{social.js → vertical/social.js} +60 -14
  64. package/dungeons/vertical/travel-schema.json +558 -0
  65. package/dungeons/vertical/travel.js +736 -0
  66. package/index.js +19 -15
  67. package/lib/core/config-validator.js +286 -1
  68. package/lib/core/context.js +7 -5
  69. package/lib/generators/adspend.js +3 -3
  70. package/lib/generators/events.js +141 -14
  71. package/lib/generators/funnels.js +67 -7
  72. package/lib/generators/text.js +2 -2
  73. package/lib/orchestrators/user-loop.js +441 -22
  74. package/lib/templates/soup-presets.js +2 -2
  75. package/lib/utils/utils.js +4 -5
  76. package/package.json +4 -3
  77. package/scripts/dungeon-to-json.mjs +163 -0
  78. package/scripts/extract-dungeon-schema.mjs +297 -0
  79. package/scripts/json-to-dungeon.mjs +200 -0
  80. package/scripts/run-dungeon.mjs +76 -0
  81. package/scripts/run-many.mjs +118 -0
  82. package/scripts/verify-runner.mjs +42 -0
  83. package/types.d.ts +313 -1
  84. package/dungeons/array-of-object-lookup-schema.json +0 -327
  85. package/dungeons/ecommerce-schema.json +0 -462
  86. package/dungeons/education-schema.json +0 -2409
  87. package/dungeons/fintech-schema.json +0 -14034
  88. package/dungeons/foobar-schema.json +0 -403
  89. package/dungeons/food-delivery-schema.json +0 -192
  90. package/dungeons/food-delivery.js +0 -602
  91. package/dungeons/food-schema.json +0 -1152
  92. package/dungeons/gaming-schema.json +0 -1270
  93. package/dungeons/insurance-application-schema.json +0 -204
  94. package/dungeons/media-schema.json +0 -906
  95. package/dungeons/retention-cadence-schema.json +0 -78
  96. package/dungeons/rpg-schema.json +0 -4526
  97. package/dungeons/sanity-schema.json +0 -255
  98. package/dungeons/sass-schema.json +0 -1291
  99. package/dungeons/scd-schema.json +0 -919
  100. package/dungeons/simple-schema.json +0 -608
  101. package/dungeons/simplest-schema.json +0 -1418
  102. package/dungeons/social-schema.json +0 -1118
  103. package/dungeons/text-generation-schema.json +0 -3096
@@ -0,0 +1,466 @@
1
+ {
2
+ "events": [
3
+ {
4
+ "event": "account created",
5
+ "isFirstEvent": true,
6
+ "properties": {
7
+ "signup_source": [
8
+ "web",
9
+ "mobile",
10
+ "agent_referral",
11
+ "partner"
12
+ ],
13
+ "account_type": [
14
+ "individual",
15
+ "family",
16
+ "business"
17
+ ]
18
+ }
19
+ },
20
+ {
21
+ "event": "page viewed",
22
+ "weight": 10,
23
+ "properties": {
24
+ "page_name": [
25
+ "home",
26
+ "quotes",
27
+ "coverage_options",
28
+ "claims",
29
+ "faq",
30
+ "profile",
31
+ "payment",
32
+ "documents"
33
+ ],
34
+ "referrer": [
35
+ "direct",
36
+ "google",
37
+ "email",
38
+ "social_media"
39
+ ]
40
+ }
41
+ },
42
+ {
43
+ "event": "quote requested",
44
+ "weight": 5,
45
+ "properties": {
46
+ "coverage_level": [
47
+ "basic",
48
+ "standard",
49
+ "premium"
50
+ ],
51
+ "deductible": {
52
+ "$range": [
53
+ 443,
54
+ 4473
55
+ ]
56
+ }
57
+ }
58
+ },
59
+ {
60
+ "event": "quote received",
61
+ "weight": 4,
62
+ "properties": {
63
+ "monthly_premium": {
64
+ "$range": [
65
+ 164,
66
+ 651
67
+ ]
68
+ },
69
+ "coverage_amount": {
70
+ "$range": [
71
+ 79151,
72
+ 430388
73
+ ]
74
+ },
75
+ "quote_comparison_count": [
76
+ 2,
77
+ 4
78
+ ]
79
+ }
80
+ },
81
+ {
82
+ "event": "application started",
83
+ "weight": 4,
84
+ "properties": {
85
+ "coverage_level": [
86
+ "basic",
87
+ "standard",
88
+ "premium"
89
+ ],
90
+ "estimated_premium": {
91
+ "$range": [
92
+ 175,
93
+ 646
94
+ ]
95
+ }
96
+ }
97
+ },
98
+ {
99
+ "event": "application step completed",
100
+ "weight": 6,
101
+ "properties": {
102
+ "step_name": [
103
+ "personal_info",
104
+ "coverage_selection",
105
+ "medical_history",
106
+ "vehicle_info",
107
+ "beneficiary",
108
+ "review"
109
+ ],
110
+ "step_number": {
111
+ "$range": [
112
+ 1,
113
+ 5
114
+ ]
115
+ },
116
+ "time_on_step_sec": {
117
+ "$range": [
118
+ 121,
119
+ 491
120
+ ]
121
+ }
122
+ }
123
+ },
124
+ {
125
+ "event": "document uploaded",
126
+ "weight": 3,
127
+ "properties": {
128
+ "document_type": [
129
+ "drivers_license",
130
+ "proof_of_address",
131
+ "vehicle_registration",
132
+ "medical_records",
133
+ "property_photos"
134
+ ],
135
+ "file_size_kb": {
136
+ "$range": [
137
+ 552,
138
+ 4345
139
+ ]
140
+ }
141
+ }
142
+ },
143
+ {
144
+ "event": "application submitted",
145
+ "weight": 3,
146
+ "properties": {
147
+ "documents_attached": [
148
+ 4
149
+ ],
150
+ "application_time_min": {
151
+ "$range": [
152
+ 17,
153
+ 47
154
+ ]
155
+ }
156
+ }
157
+ },
158
+ {
159
+ "event": "application approved",
160
+ "weight": 2,
161
+ "properties": {
162
+ "approved_premium": {
163
+ "$range": [
164
+ 130,
165
+ 648
166
+ ]
167
+ },
168
+ "approval_time_hours": {
169
+ "$range": [
170
+ 8,
171
+ 61
172
+ ]
173
+ }
174
+ }
175
+ },
176
+ {
177
+ "event": "policy activated",
178
+ "weight": 2,
179
+ "properties": {
180
+ "policy_term_months": [
181
+ 6,
182
+ 12,
183
+ 24
184
+ ],
185
+ "effective_date_offset_days": [
186
+ 10,
187
+ 23,
188
+ 21,
189
+ 22,
190
+ 19,
191
+ 14,
192
+ 18
193
+ ]
194
+ }
195
+ },
196
+ {
197
+ "event": "claim filed",
198
+ "weight": 2,
199
+ "properties": {
200
+ "claim_type": [
201
+ "collision",
202
+ "theft",
203
+ "water_damage",
204
+ "fire",
205
+ "medical",
206
+ "liability"
207
+ ],
208
+ "estimated_amount": {
209
+ "$range": [
210
+ 5885,
211
+ 43341
212
+ ]
213
+ }
214
+ }
215
+ },
216
+ {
217
+ "event": "claim status checked",
218
+ "weight": 4,
219
+ "properties": {
220
+ "claim_status": [
221
+ "submitted",
222
+ "under_review",
223
+ "approved",
224
+ "denied",
225
+ "payment_pending"
226
+ ],
227
+ "days_since_filed": [
228
+ 48,
229
+ 20,
230
+ 42,
231
+ 12,
232
+ 35,
233
+ 27,
234
+ 47,
235
+ 21
236
+ ]
237
+ }
238
+ },
239
+ {
240
+ "event": "payment made",
241
+ "weight": 5,
242
+ "properties": {
243
+ "payment_method": [
244
+ "credit_card",
245
+ "bank_transfer",
246
+ "auto_pay",
247
+ "check"
248
+ ],
249
+ "amount": {
250
+ "$range": [
251
+ 181,
252
+ 677
253
+ ]
254
+ },
255
+ "payment_status": [
256
+ "success",
257
+ "failed"
258
+ ]
259
+ }
260
+ },
261
+ {
262
+ "event": "support ticket created",
263
+ "weight": 4,
264
+ "properties": {
265
+ "issue_category": [
266
+ "billing",
267
+ "claims",
268
+ "coverage",
269
+ "technical",
270
+ "policy_change"
271
+ ],
272
+ "priority": [
273
+ "low",
274
+ "medium",
275
+ "high"
276
+ ],
277
+ "channel": [
278
+ "chat",
279
+ "phone",
280
+ "email",
281
+ "web_form"
282
+ ],
283
+ "pre_release_bug": [
284
+ false
285
+ ]
286
+ }
287
+ },
288
+ {
289
+ "event": "support ticket resolved",
290
+ "weight": 3,
291
+ "properties": {
292
+ "resolution_type": [
293
+ "self_service",
294
+ "agent_assisted",
295
+ "escalated",
296
+ "auto_resolved"
297
+ ],
298
+ "satisfaction_score": [
299
+ 3,
300
+ 2,
301
+ 4
302
+ ],
303
+ "resolution_time_hours": [
304
+ 53,
305
+ 50,
306
+ 57,
307
+ 52,
308
+ 20,
309
+ 54,
310
+ 36,
311
+ 17
312
+ ]
313
+ }
314
+ },
315
+ {
316
+ "event": "coverage reviewed",
317
+ "weight": 4,
318
+ "properties": {
319
+ "current_premium": {
320
+ "$range": [
321
+ 183,
322
+ 666
323
+ ]
324
+ },
325
+ "coverage_adequate": [
326
+ true,
327
+ false
328
+ ]
329
+ }
330
+ },
331
+ {
332
+ "event": "profile updated",
333
+ "weight": 2,
334
+ "properties": {
335
+ "field_updated": [
336
+ "address",
337
+ "phone",
338
+ "email",
339
+ "beneficiary",
340
+ "payment_method",
341
+ "vehicle_info"
342
+ ]
343
+ }
344
+ },
345
+ {
346
+ "event": "renewal completed",
347
+ "weight": 2,
348
+ "properties": {
349
+ "renewal_premium": {
350
+ "$range": [
351
+ 162,
352
+ 651
353
+ ]
354
+ },
355
+ "premium_change_pct": [
356
+ 14,
357
+ -4,
358
+ 6
359
+ ],
360
+ "auto_renewed": [
361
+ true,
362
+ false
363
+ ]
364
+ }
365
+ }
366
+ ],
367
+ "superProps": {
368
+ "platform": [
369
+ "web",
370
+ "ios",
371
+ "android"
372
+ ],
373
+ "insurance_type": [
374
+ "auto",
375
+ "home",
376
+ "life",
377
+ "health",
378
+ "renters"
379
+ ],
380
+ "app_version": [
381
+ "2.10"
382
+ ]
383
+ },
384
+ "userProps": {
385
+ "age_range": [
386
+ "18-25",
387
+ "26-35",
388
+ "36-45",
389
+ "46-55",
390
+ "56-65",
391
+ "65+"
392
+ ],
393
+ "risk_profile": [
394
+ "low",
395
+ "medium",
396
+ "high"
397
+ ],
398
+ "policy_count": [
399
+ 3
400
+ ],
401
+ "lifetime_premium": {
402
+ "$range": [
403
+ 8131,
404
+ 43291
405
+ ]
406
+ },
407
+ "preferred_contact": [
408
+ "email",
409
+ "phone",
410
+ "app_notification"
411
+ ]
412
+ },
413
+ "funnels": [
414
+ {
415
+ "sequence": [
416
+ "account created",
417
+ "page viewed",
418
+ "quote requested"
419
+ ],
420
+ "isFirstFunnel": true,
421
+ "conversionRate": 85,
422
+ "timeToConvert": 0.5
423
+ },
424
+ {
425
+ "sequence": [
426
+ "application started",
427
+ "application step completed",
428
+ "document uploaded",
429
+ "application submitted"
430
+ ],
431
+ "conversionRate": 60,
432
+ "timeToConvert": 48,
433
+ "weight": 4
434
+ },
435
+ {
436
+ "sequence": [
437
+ "application submitted",
438
+ "application approved",
439
+ "policy activated"
440
+ ],
441
+ "conversionRate": 70,
442
+ "timeToConvert": 72,
443
+ "weight": 3
444
+ },
445
+ {
446
+ "sequence": [
447
+ "claim filed",
448
+ "claim status checked",
449
+ "support ticket created"
450
+ ],
451
+ "conversionRate": 50,
452
+ "timeToConvert": 24,
453
+ "weight": 2
454
+ },
455
+ {
456
+ "sequence": [
457
+ "coverage reviewed",
458
+ "payment made",
459
+ "renewal completed"
460
+ ],
461
+ "conversionRate": 65,
462
+ "timeToConvert": 72,
463
+ "weight": 3
464
+ }
465
+ ]
466
+ }
@@ -1,7 +1,7 @@
1
1
  import dayjs from "dayjs";
2
2
  import utc from "dayjs/plugin/utc.js";
3
3
  import "dotenv/config";
4
- import * as u from "../lib/utils/utils.js";
4
+ import * as u from "../../lib/utils/utils.js";
5
5
 
6
6
  const SEED = "dm4-insurance";
7
7
  dayjs.extend(utc);
@@ -9,7 +9,7 @@ const chance = u.initChance(SEED);
9
9
  const num_users = 5_000;
10
10
  const days = 100;
11
11
 
12
- /** @typedef {import("../types").Dungeon} Config */
12
+ /** @typedef {import("../../types").Dungeon} Config */
13
13
 
14
14
  /*
15
15
  * ===================================================================
@@ -49,9 +49,11 @@ const days = 100;
49
49
  * ===================================================================
50
50
  *
51
51
  * -------------------------------------------------------------------
52
- * 1. VERSION STAMPING (event hook)
52
+ * 1. VERSION STAMPING (everything hook)
53
53
  * -------------------------------------------------------------------
54
- * Every event gets a deterministic app_version based on its timestamp.
54
+ * Every event gets a deterministic app_version based on its final
55
+ * timestamp. Uses the everything hook (not event hook) because funnel
56
+ * events adjust their time AFTER the event hook runs.
55
57
  * All users shift simultaneously on release dates:
56
58
  * - Days 0-30: v2.10
57
59
  * - Days 30-60: v2.11
@@ -317,6 +319,7 @@ const config = {
317
319
  ],
318
320
  priority: ["low", "medium", "medium", "high"],
319
321
  channel: ["chat", "phone", "email", "web_form"],
322
+ pre_release_bug: [false],
320
323
  },
321
324
  },
322
325
  {
@@ -424,6 +427,7 @@ const config = {
424
427
  superProps: {
425
428
  platform: ["web", "ios", "android"],
426
429
  insurance_type: ["auto", "home", "life", "health", "renters"],
430
+ app_version: ["2.10"],
427
431
  },
428
432
 
429
433
  // ── User Props (set once per user) ──
@@ -441,9 +445,11 @@ const config = {
441
445
  *
442
446
  * This hook function creates 3 deliberate patterns in the data:
443
447
  *
444
- * 1. VERSION STAMPING (event): Every event gets a deterministic app_version
445
- * based on its timestamp. v2.10 → v2.11 → v2.12 → v2.13.
446
- * All users shift simultaneously on release dates.
448
+ * 1. VERSION STAMPING (everything): Every event gets a deterministic app_version
449
+ * based on its final timestamp. v2.10 → v2.11 → v2.12 → v2.13.
450
+ * All users shift simultaneously on release dates. Uses the everything
451
+ * hook (not event hook) because funnel events adjust time after the
452
+ * event hook runs.
447
453
  *
448
454
  * 2. SUPPORT TICKET VOLUME (everything): Pre-v2.13 period has inflated
449
455
  * support ticket volume (2-3 extra tickets per user with bug-related
@@ -457,32 +463,30 @@ const config = {
457
463
  */
458
464
  hook: function (record, type, meta) {
459
465
  // =============================================================
460
- // Hook #1: VERSION STAMPING (event)
461
- // Deterministic app_version on every event based on timestamp.
462
- // v2.10 (days 0-30) v2.11 (30-60) → v2.12 (60-90) → v2.13 (last 10 days)
463
- // =============================================================
464
- if (type === "event") {
465
- const eventTime = dayjs(record.time);
466
-
467
- if (eventTime.isBefore(V211_DATE)) {
468
- record.app_version = "2.10";
469
- } else if (eventTime.isBefore(V212_DATE)) {
470
- record.app_version = "2.11";
471
- } else if (eventTime.isBefore(V213_DATE)) {
472
- record.app_version = "2.12";
473
- } else {
474
- record.app_version = "2.13";
475
- }
476
- }
477
-
478
- // =============================================================
479
- // Hook #2 & #3: SUPPORT TICKET VOLUME + APPLICATION CONVERSION
480
- // (everything)
466
+ // Hooks #1-#3 all run in the "everything" hook so that version
467
+ // stamping sees final timestamps (funnel events adjust time
468
+ // AFTER the event hook runs).
481
469
  // =============================================================
482
470
  if (type === "everything") {
483
471
  const userEvents = record;
484
472
  if (userEvents.length === 0) return record;
485
473
 
474
+ // ─── Hook #1: VERSION STAMPING ───
475
+ // Deterministic app_version on every event based on its final timestamp.
476
+ // v2.10 (days 0-30) → v2.11 (30-60) → v2.12 (60-90) → v2.13 (last 10 days)
477
+ for (const evt of userEvents) {
478
+ const eventTime = dayjs(evt.time);
479
+ if (eventTime.isBefore(V211_DATE)) {
480
+ evt.app_version = "2.10";
481
+ } else if (eventTime.isBefore(V212_DATE)) {
482
+ evt.app_version = "2.11";
483
+ } else if (eventTime.isBefore(V213_DATE)) {
484
+ evt.app_version = "2.12";
485
+ } else {
486
+ evt.app_version = "2.13";
487
+ }
488
+ }
489
+
486
490
  // Find a user_id from any existing event
487
491
  const userId =
488
492
  userEvents.find((e) => e.user_id)?.user_id ||
@@ -531,7 +535,7 @@ const config = {
531
535
  }
532
536
 
533
537
  userEvents.push({
534
- event: "support ticket created",
538
+ ...sourceTicket,
535
539
  time: newTime.toISOString(),
536
540
  user_id: userId,
537
541
  app_version: injectedVersion,