@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.
- package/README.md +7 -7
- package/dungeons/technical/ad-spend-schema.json +128 -0
- package/dungeons/technical/ad-spend.js +116 -0
- package/dungeons/technical/anonymous-users-schema.json +91 -0
- package/dungeons/technical/anonymous-users.js +102 -0
- package/dungeons/technical/array-of-object-lookup-schema.json +191 -0
- package/dungeons/{array-of-object-lookup.js → technical/array-of-object-lookup.js} +11 -4
- package/dungeons/technical/experiments-schema.json +197 -0
- package/dungeons/technical/experiments.js +168 -0
- package/dungeons/technical/foobar-schema.json +362 -0
- package/dungeons/{foobar.js → technical/foobar.js} +2 -2
- package/dungeons/technical/group-analytics-schema.json +149 -0
- package/dungeons/technical/group-analytics.js +151 -0
- package/dungeons/technical/mirror-strategies-schema.json +84 -0
- package/dungeons/technical/mirror-strategies.js +126 -0
- package/dungeons/technical/nested-objects-schema.json +145 -0
- package/dungeons/technical/nested-objects.js +207 -0
- package/dungeons/technical/retention-cadence-schema.json +37 -0
- package/dungeons/{retention-cadence.js → technical/retention-cadence.js} +1 -1
- package/dungeons/technical/sanity-schema.json +185 -0
- package/dungeons/{sanity.js → technical/sanity.js} +3 -2
- package/dungeons/technical/scale-test-schema.json +70 -0
- package/dungeons/technical/scale-test.js +90 -0
- package/dungeons/technical/scd-schema.json +270 -0
- package/dungeons/{scd.js → technical/scd.js} +19 -10
- package/dungeons/technical/simple-schema.json +278 -0
- package/dungeons/{simple.js → technical/simple.js} +6 -6
- package/dungeons/technical/simplest-schema.json +635 -0
- package/dungeons/{simplest.js → technical/simplest.js} +6 -6
- package/dungeons/technical/text-generation-schema.json +1059 -0
- package/dungeons/{text-generation.js → technical/text-generation.js} +23 -9
- package/dungeons/vertical/community-schema.json +557 -0
- package/dungeons/vertical/community.js +788 -0
- package/dungeons/vertical/devtools-schema.json +580 -0
- package/dungeons/vertical/devtools.js +837 -0
- package/dungeons/vertical/ecommerce-schema.json +586 -0
- package/dungeons/{ecommerce.js → vertical/ecommerce.js} +34 -3
- package/dungeons/vertical/education-schema.json +697 -0
- package/dungeons/{education.js → vertical/education.js} +54 -36
- package/dungeons/vertical/fintech-schema.json +563 -0
- package/dungeons/{fintech.js → vertical/fintech.js} +91 -53
- package/dungeons/vertical/fitness-schema.json +508 -0
- package/dungeons/vertical/fitness.js +802 -0
- package/dungeons/vertical/food-delivery-schema.json +678 -0
- package/dungeons/{food.js → vertical/food-delivery.js} +51 -23
- package/dungeons/vertical/gaming-schema.json +394 -0
- package/dungeons/{gaming.js → vertical/gaming.js} +9 -7
- package/dungeons/vertical/healthcare-schema.json +527 -0
- package/dungeons/vertical/healthcare.js +769 -0
- package/dungeons/vertical/insurance-application-schema.json +466 -0
- package/dungeons/{insurance-application.js → vertical/insurance-application.js} +33 -29
- package/dungeons/vertical/logistics-schema.json +552 -0
- package/dungeons/vertical/logistics.js +793 -0
- package/dungeons/vertical/marketplace-schema.json +511 -0
- package/dungeons/vertical/marketplace.js +844 -0
- package/dungeons/vertical/media-schema.json +787 -0
- package/dungeons/{media.js → vertical/media.js} +94 -16
- package/dungeons/vertical/rpg-schema.json +654 -0
- package/dungeons/{rpg.js → vertical/rpg.js} +78 -57
- package/dungeons/vertical/sass-schema.json +653 -0
- package/dungeons/{sass.js → vertical/sass.js} +49 -23
- package/dungeons/vertical/social-schema.json +552 -0
- package/dungeons/{social.js → vertical/social.js} +60 -14
- package/dungeons/vertical/travel-schema.json +558 -0
- package/dungeons/vertical/travel.js +736 -0
- package/index.js +19 -15
- package/lib/core/config-validator.js +286 -1
- package/lib/core/context.js +7 -5
- package/lib/generators/adspend.js +3 -3
- package/lib/generators/events.js +141 -14
- package/lib/generators/funnels.js +67 -7
- package/lib/generators/text.js +2 -2
- package/lib/orchestrators/user-loop.js +441 -22
- package/lib/templates/soup-presets.js +2 -2
- package/lib/utils/utils.js +4 -5
- package/package.json +4 -3
- package/scripts/dungeon-to-json.mjs +163 -0
- package/scripts/extract-dungeon-schema.mjs +297 -0
- package/scripts/json-to-dungeon.mjs +200 -0
- package/scripts/run-dungeon.mjs +76 -0
- package/scripts/run-many.mjs +118 -0
- package/scripts/verify-runner.mjs +42 -0
- package/types.d.ts +313 -1
- package/dungeons/array-of-object-lookup-schema.json +0 -327
- package/dungeons/ecommerce-schema.json +0 -462
- package/dungeons/education-schema.json +0 -2409
- package/dungeons/fintech-schema.json +0 -14034
- package/dungeons/foobar-schema.json +0 -403
- package/dungeons/food-delivery-schema.json +0 -192
- package/dungeons/food-delivery.js +0 -602
- package/dungeons/food-schema.json +0 -1152
- package/dungeons/gaming-schema.json +0 -1270
- package/dungeons/insurance-application-schema.json +0 -204
- package/dungeons/media-schema.json +0 -906
- package/dungeons/retention-cadence-schema.json +0 -78
- package/dungeons/rpg-schema.json +0 -4526
- package/dungeons/sanity-schema.json +0 -255
- package/dungeons/sass-schema.json +0 -1291
- package/dungeons/scd-schema.json +0 -919
- package/dungeons/simple-schema.json +0 -608
- package/dungeons/simplest-schema.json +0 -1418
- package/dungeons/social-schema.json +0 -1118
- package/dungeons/text-generation-schema.json +0 -3096
|
@@ -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 "
|
|
4
|
+
import * as u from "../../lib/utils/utils.js";
|
|
5
5
|
|
|
6
6
|
const SEED = "harness-fintech";
|
|
7
7
|
dayjs.extend(utc);
|
|
@@ -221,7 +221,7 @@ const config = {
|
|
|
221
221
|
weight: 1,
|
|
222
222
|
isFirstEvent: true,
|
|
223
223
|
properties: {
|
|
224
|
-
"account_type":
|
|
224
|
+
"account_type": ["personal", "business", "personal"],
|
|
225
225
|
"signup_channel": ["app", "web", "referral", "branch"],
|
|
226
226
|
}
|
|
227
227
|
},
|
|
@@ -231,6 +231,7 @@ const config = {
|
|
|
231
231
|
properties: {
|
|
232
232
|
"session_duration_sec": u.weighNumRange(10, 600, 0.3, 60),
|
|
233
233
|
"pages_viewed": u.weighNumRange(1, 15, 0.5, 3),
|
|
234
|
+
"month_end_anxiety": [false],
|
|
234
235
|
}
|
|
235
236
|
},
|
|
236
237
|
{
|
|
@@ -239,6 +240,7 @@ const config = {
|
|
|
239
240
|
properties: {
|
|
240
241
|
"account_balance": u.weighNumRange(0, 50000, 0.8, 2500),
|
|
241
242
|
"account_type": ["checking", "savings", "investment"],
|
|
243
|
+
"month_end_check": [false],
|
|
242
244
|
}
|
|
243
245
|
},
|
|
244
246
|
{
|
|
@@ -249,6 +251,8 @@ const config = {
|
|
|
249
251
|
"amount": u.weighNumRange(1, 5000, 0.3, 50),
|
|
250
252
|
"merchant_category": ["grocery", "restaurant", "gas", "retail", "online", "subscription", "utilities"],
|
|
251
253
|
"payment_method": ["debit", "credit", "contactless", "online"],
|
|
254
|
+
"payday": [false],
|
|
255
|
+
"fraud_sequence": [false],
|
|
252
256
|
}
|
|
253
257
|
},
|
|
254
258
|
{
|
|
@@ -258,6 +262,7 @@ const config = {
|
|
|
258
262
|
"transfer_type": ["internal", "external", "p2p", "wire"],
|
|
259
263
|
"amount": u.weighNumRange(10, 10000, 0.3, 200),
|
|
260
264
|
"recipient_type": ["friend", "family", "business", "self"],
|
|
265
|
+
"post_payday_spending": [false],
|
|
261
266
|
}
|
|
262
267
|
},
|
|
263
268
|
{
|
|
@@ -266,7 +271,9 @@ const config = {
|
|
|
266
271
|
properties: {
|
|
267
272
|
"bill_type": ["rent", "utilities", "phone", "insurance", "subscription", "loan_payment"],
|
|
268
273
|
"amount": u.weighNumRange(20, 3000, 0.5, 150),
|
|
269
|
-
"auto_pay":
|
|
274
|
+
"auto_pay": [false, false, false, true, true],
|
|
275
|
+
"missed_payment": [false],
|
|
276
|
+
"manual_payment": [false],
|
|
270
277
|
}
|
|
271
278
|
},
|
|
272
279
|
{
|
|
@@ -292,6 +299,7 @@ const config = {
|
|
|
292
299
|
"goal_type": ["emergency", "vacation", "car", "home", "education", "retirement"],
|
|
293
300
|
"target_amount": u.weighNumRange(500, 50000, 0.3, 5000),
|
|
294
301
|
"monthly_contribution": u.weighNumRange(25, 2000, 0.5, 200),
|
|
302
|
+
"budget_discipline": [false],
|
|
295
303
|
}
|
|
296
304
|
},
|
|
297
305
|
{
|
|
@@ -300,7 +308,9 @@ const config = {
|
|
|
300
308
|
properties: {
|
|
301
309
|
"investment_type": ["stocks", "etf", "crypto", "bonds", "mutual_fund"],
|
|
302
310
|
"amount": u.weighNumRange(10, 10000, 0.3, 250),
|
|
303
|
-
"action":
|
|
311
|
+
"action": ["buy", "sell", "buy"],
|
|
312
|
+
"premium_returns": [false],
|
|
313
|
+
"budget_discipline": [false],
|
|
304
314
|
}
|
|
305
315
|
},
|
|
306
316
|
{
|
|
@@ -308,6 +318,7 @@ const config = {
|
|
|
308
318
|
weight: 1,
|
|
309
319
|
properties: {
|
|
310
320
|
"reason": ["lost", "stolen", "suspicious_activity", "travel"],
|
|
321
|
+
"fraud_sequence": [false],
|
|
311
322
|
}
|
|
312
323
|
},
|
|
313
324
|
{
|
|
@@ -316,6 +327,7 @@ const config = {
|
|
|
316
327
|
properties: {
|
|
317
328
|
"dispute_amount": u.weighNumRange(10, 2000, 0.5, 100),
|
|
318
329
|
"reason": ["unauthorized", "duplicate", "not_received", "damaged", "wrong_amount"],
|
|
330
|
+
"fraud_sequence": [false],
|
|
319
331
|
}
|
|
320
332
|
},
|
|
321
333
|
{
|
|
@@ -340,8 +352,8 @@ const config = {
|
|
|
340
352
|
weight: 2,
|
|
341
353
|
properties: {
|
|
342
354
|
"old_tier": ["basic", "plus", "premium"],
|
|
343
|
-
"new_tier":
|
|
344
|
-
"monthly_fee":
|
|
355
|
+
"new_tier": ["plus", "premium", "premium"],
|
|
356
|
+
"monthly_fee": [4.99, 9.99, 14.99],
|
|
345
357
|
}
|
|
346
358
|
},
|
|
347
359
|
{
|
|
@@ -350,7 +362,8 @@ const config = {
|
|
|
350
362
|
properties: {
|
|
351
363
|
"channel": ["chat", "phone", "email", "in_app"],
|
|
352
364
|
"issue_type": ["transaction", "account", "card", "transfer", "technical"],
|
|
353
|
-
"resolved":
|
|
365
|
+
"resolved": [false, true, true, true, true],
|
|
366
|
+
"fraud_sequence": [false],
|
|
354
367
|
}
|
|
355
368
|
},
|
|
356
369
|
{
|
|
@@ -358,7 +371,7 @@ const config = {
|
|
|
358
371
|
weight: 10,
|
|
359
372
|
properties: {
|
|
360
373
|
"notification_type": ["transaction", "low_balance", "bill_due", "reward", "security", "promo"],
|
|
361
|
-
"action_taken":
|
|
374
|
+
"action_taken": [false, false, true, true, true],
|
|
362
375
|
}
|
|
363
376
|
},
|
|
364
377
|
{
|
|
@@ -367,13 +380,15 @@ const config = {
|
|
|
367
380
|
properties: {
|
|
368
381
|
"reward_type": ["cashback", "points", "discount", "partner_offer"],
|
|
369
382
|
"value": u.weighNumRange(1, 100, 0.5, 10),
|
|
383
|
+
"premium_reward": [false],
|
|
370
384
|
}
|
|
371
385
|
}
|
|
372
386
|
],
|
|
373
387
|
|
|
374
388
|
superProps: {
|
|
375
|
-
account_tier:
|
|
389
|
+
account_tier: ["basic", "basic", "basic", "plus", "plus", "premium"],
|
|
376
390
|
platform: ["ios", "android", "web"],
|
|
391
|
+
low_balance_churn: [false],
|
|
377
392
|
},
|
|
378
393
|
|
|
379
394
|
userProps: {
|
|
@@ -381,7 +396,13 @@ const config = {
|
|
|
381
396
|
"income_bracket": ["under_30k", "30k_50k", "50k_75k", "75k_100k", "100k_150k", "over_150k"],
|
|
382
397
|
"account_age_months": u.weighNumRange(1, 60, 0.5, 12),
|
|
383
398
|
"total_balance": u.weighNumRange(0, 100000, 0.3, 5000),
|
|
384
|
-
"has_direct_deposit":
|
|
399
|
+
"has_direct_deposit": [false, false, true, true, true],
|
|
400
|
+
"account_segment": ["personal"],
|
|
401
|
+
"employee_count": [0],
|
|
402
|
+
"annual_revenue": [0],
|
|
403
|
+
"industry": [""],
|
|
404
|
+
"age_range": [""],
|
|
405
|
+
"life_stage": [""],
|
|
385
406
|
},
|
|
386
407
|
|
|
387
408
|
groupKeys: [
|
|
@@ -393,7 +414,7 @@ const config = {
|
|
|
393
414
|
"household_size": u.weighNumRange(1, 6),
|
|
394
415
|
"combined_income": u.weighNumRange(20000, 300000, 0.3, 75000),
|
|
395
416
|
"financial_health_score": u.weighNumRange(1, 100, 1, 65),
|
|
396
|
-
"primary_bank":
|
|
417
|
+
"primary_bank": ["NexBank_only", "multi_bank", "NexBank_only"],
|
|
397
418
|
}
|
|
398
419
|
},
|
|
399
420
|
|
|
@@ -568,48 +589,62 @@ const config = {
|
|
|
568
589
|
const burstCount = chance.integer({ min: 3, max: 5 });
|
|
569
590
|
const fraudEvents = [];
|
|
570
591
|
|
|
592
|
+
// Find template events for cloning
|
|
593
|
+
const txnTemplate = userEvents.find(e => e.event === "transaction completed");
|
|
594
|
+
const cardTemplate = userEvents.find(e => e.event === "card locked");
|
|
595
|
+
const disputeTemplate = userEvents.find(e => e.event === "dispute filed");
|
|
596
|
+
const supportTemplate = userEvents.find(e => e.event === "support contacted");
|
|
597
|
+
|
|
571
598
|
for (let i = 0; i < burstCount; i++) {
|
|
599
|
+
if (txnTemplate) {
|
|
600
|
+
fraudEvents.push({
|
|
601
|
+
...txnTemplate,
|
|
602
|
+
time: midTime.add(i * 10, "minutes").toISOString(),
|
|
603
|
+
user_id: distinctId,
|
|
604
|
+
transaction_type: "purchase",
|
|
605
|
+
amount: chance.integer({ min: 500, max: 3000 }),
|
|
606
|
+
merchant_category: chance.pickone(["online", "retail"]),
|
|
607
|
+
payment_method: "credit",
|
|
608
|
+
fraud_sequence: true,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// Card locked after the burst
|
|
614
|
+
if (cardTemplate) {
|
|
572
615
|
fraudEvents.push({
|
|
573
|
-
|
|
574
|
-
time: midTime.add(
|
|
616
|
+
...cardTemplate,
|
|
617
|
+
time: midTime.add(burstCount * 10 + 5, "minutes").toISOString(),
|
|
575
618
|
user_id: distinctId,
|
|
576
|
-
|
|
577
|
-
amount: chance.integer({ min: 500, max: 3000 }),
|
|
578
|
-
merchant_category: chance.pickone(["online", "retail"]),
|
|
579
|
-
payment_method: "credit",
|
|
619
|
+
reason: "suspicious_activity",
|
|
580
620
|
fraud_sequence: true,
|
|
581
621
|
});
|
|
582
622
|
}
|
|
583
623
|
|
|
584
|
-
// Card locked after the burst
|
|
585
|
-
fraudEvents.push({
|
|
586
|
-
event: "card locked",
|
|
587
|
-
time: midTime.add(burstCount * 10 + 5, "minutes").toISOString(),
|
|
588
|
-
user_id: distinctId,
|
|
589
|
-
reason: "suspicious_activity",
|
|
590
|
-
fraud_sequence: true,
|
|
591
|
-
});
|
|
592
|
-
|
|
593
624
|
// Dispute filed shortly after
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
625
|
+
if (disputeTemplate) {
|
|
626
|
+
fraudEvents.push({
|
|
627
|
+
...disputeTemplate,
|
|
628
|
+
time: midTime.add(burstCount * 10 + 30, "minutes").toISOString(),
|
|
629
|
+
user_id: distinctId,
|
|
630
|
+
dispute_amount: chance.integer({ min: 500, max: 3000 }),
|
|
631
|
+
reason: "unauthorized",
|
|
632
|
+
fraud_sequence: true,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
602
635
|
|
|
603
636
|
// Support contacted
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
637
|
+
if (supportTemplate) {
|
|
638
|
+
fraudEvents.push({
|
|
639
|
+
...supportTemplate,
|
|
640
|
+
time: midTime.add(burstCount * 10 + 45, "minutes").toISOString(),
|
|
641
|
+
user_id: distinctId,
|
|
642
|
+
channel: "phone",
|
|
643
|
+
issue_type: "card",
|
|
644
|
+
resolved: true,
|
|
645
|
+
fraud_sequence: true,
|
|
646
|
+
});
|
|
647
|
+
}
|
|
613
648
|
|
|
614
649
|
// Splice all fraud events into the user's timeline
|
|
615
650
|
userEvents.splice(midIdx + 1, 0, ...fraudEvents);
|
|
@@ -674,16 +709,19 @@ const config = {
|
|
|
674
709
|
|
|
675
710
|
// Splice extra savings goal events (budget-conscious users set more goals)
|
|
676
711
|
if (event.event === "budget created" && chance.bool({ likelihood: 50 })) {
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
712
|
+
const savingsTemplate = userEvents.find(e => e.event === "savings goal set");
|
|
713
|
+
if (savingsTemplate) {
|
|
714
|
+
const extraGoal = {
|
|
715
|
+
...savingsTemplate,
|
|
716
|
+
time: eventTime.add(chance.integer({ min: 1, max: 7 }), "days").toISOString(),
|
|
717
|
+
user_id: event.user_id,
|
|
718
|
+
goal_type: chance.pickone(["emergency", "vacation", "car", "home"]),
|
|
719
|
+
target_amount: chance.integer({ min: 1000, max: 20000 }),
|
|
720
|
+
monthly_contribution: chance.integer({ min: 100, max: 800 }),
|
|
721
|
+
budget_discipline: true,
|
|
722
|
+
};
|
|
723
|
+
userEvents.splice(idx + 1, 0, extraGoal);
|
|
724
|
+
}
|
|
687
725
|
}
|
|
688
726
|
});
|
|
689
727
|
}
|