@forestadmin/datasource-demo-fintech 1.0.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/LICENSE +674 -0
- package/README.md +40 -0
- package/dist/customizations/aml_alerts.d.ts +3 -0
- package/dist/customizations/aml_alerts.js +135 -0
- package/dist/customizations/cards.d.ts +3 -0
- package/dist/customizations/cards.js +95 -0
- package/dist/customizations/chargebacks.d.ts +3 -0
- package/dist/customizations/chargebacks.js +271 -0
- package/dist/customizations/customers.d.ts +3 -0
- package/dist/customizations/customers.js +15 -0
- package/dist/customizations/kyc_cases.d.ts +3 -0
- package/dist/customizations/kyc_cases.js +105 -0
- package/dist/customizations/kyc_documents.d.ts +3 -0
- package/dist/customizations/kyc_documents.js +62 -0
- package/dist/customizations/refund_requests.d.ts +3 -0
- package/dist/customizations/refund_requests.js +151 -0
- package/dist/customizations/sar_reports.d.ts +3 -0
- package/dist/customizations/sar_reports.js +27 -0
- package/dist/customizations/utils.d.ts +21 -0
- package/dist/customizations/utils.js +22 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +97 -0
- package/dist/seed/aml.d.ts +9 -0
- package/dist/seed/aml.js +131 -0
- package/dist/seed/cards.d.ts +9 -0
- package/dist/seed/cards.js +57 -0
- package/dist/seed/chargebacks.d.ts +9 -0
- package/dist/seed/chargebacks.js +118 -0
- package/dist/seed/customers.d.ts +9 -0
- package/dist/seed/customers.js +106 -0
- package/dist/seed/dates.d.ts +7 -0
- package/dist/seed/dates.js +28 -0
- package/dist/seed/index.d.ts +9 -0
- package/dist/seed/index.js +39 -0
- package/dist/seed/kyc.d.ts +9 -0
- package/dist/seed/kyc.js +102 -0
- package/dist/seed/pools.d.ts +27 -0
- package/dist/seed/pools.js +296 -0
- package/dist/seed/refunds.d.ts +9 -0
- package/dist/seed/refunds.js +72 -0
- package/dist/seed/types.d.ts +17 -0
- package/dist/seed/types.js +5 -0
- package/dist/seed/utils.d.ts +16 -0
- package/dist/seed/utils.js +40 -0
- package/package.json +33 -0
package/dist/seed/aml.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = seedAml;
|
|
4
|
+
const dates_1 = require("./dates");
|
|
5
|
+
const pools_1 = require("./pools");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
function amlSeverity(risk, sanctioned, atype) {
|
|
8
|
+
if (sanctioned || atype === 'SANCTIONS_MATCH')
|
|
9
|
+
return (0, utils_1.choices)(['HIGH', 'CRITICAL'], [40, 60]);
|
|
10
|
+
return (0, utils_1.choices)(pools_1.AML_SEVERITIES, { HIGH: [0, 1, 5, 4], MEDIUM: [1, 5, 3, 1], LOW: [6, 3, 1, 0] }[risk]);
|
|
11
|
+
}
|
|
12
|
+
function alertNotes(status) {
|
|
13
|
+
if (status === 'CLEARED') {
|
|
14
|
+
return (0, utils_1.pick)(['False positive — name overlap.', 'Cleared after review.']);
|
|
15
|
+
}
|
|
16
|
+
if (status === 'ESCALATED')
|
|
17
|
+
return (0, utils_1.pick)(['Escalated to MLRO.', 'Under enhanced due diligence.']);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Raises 70 AML alerts, weighting customers by risk/PEP/sanctions, then files SARs
|
|
22
|
+
* for the escalated ones. A filed SAR pushes its source alert to SAR_FILED so the
|
|
23
|
+
* two collections always tell the same story.
|
|
24
|
+
*/
|
|
25
|
+
async function seedAml(knex, customers) {
|
|
26
|
+
await knex.schema.createTable('aml_alerts', table => {
|
|
27
|
+
table.increments('id').primary();
|
|
28
|
+
table.integer('customer_id');
|
|
29
|
+
table.string('alert_type');
|
|
30
|
+
table.string('severity');
|
|
31
|
+
table.string('status');
|
|
32
|
+
table.datetime('triggered_at');
|
|
33
|
+
table.string('resolution_notes');
|
|
34
|
+
table.string('sar_reference');
|
|
35
|
+
table.datetime('resolved_at');
|
|
36
|
+
});
|
|
37
|
+
await knex.schema.createTable('sar_reports', table => {
|
|
38
|
+
table.increments('id').primary();
|
|
39
|
+
table.integer('alert_id');
|
|
40
|
+
table.integer('customer_id');
|
|
41
|
+
table.string('reference');
|
|
42
|
+
table.string('status');
|
|
43
|
+
table.string('activity_type');
|
|
44
|
+
table.date('activity_start_date');
|
|
45
|
+
table.date('activity_end_date');
|
|
46
|
+
table.float('total_amount');
|
|
47
|
+
table.integer('transaction_count');
|
|
48
|
+
table.string('narrative');
|
|
49
|
+
table.datetime('filed_at');
|
|
50
|
+
table.datetime('created_at');
|
|
51
|
+
});
|
|
52
|
+
const weights = customers.map(c => {
|
|
53
|
+
let w = { HIGH: 6, MEDIUM: 2, LOW: 1 }[c.risk_rating];
|
|
54
|
+
if (c.is_pep)
|
|
55
|
+
w += 4;
|
|
56
|
+
if (c.is_sanctioned)
|
|
57
|
+
w += 8;
|
|
58
|
+
return w;
|
|
59
|
+
});
|
|
60
|
+
const alerts = [];
|
|
61
|
+
let sarSeq = 0;
|
|
62
|
+
for (let aid = 1; aid <= 70; aid += 1) {
|
|
63
|
+
const c = (0, utils_1.choices)(customers, weights);
|
|
64
|
+
let atype;
|
|
65
|
+
if (c.is_sanctioned) {
|
|
66
|
+
atype = (0, utils_1.chance)(0.7) ? 'SANCTIONS_MATCH' : (0, utils_1.pick)(pools_1.ATYPES);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
atype = (0, utils_1.chance)(0.08) ? 'SANCTIONS_MATCH' : (0, utils_1.pick)(pools_1.ATYPES.filter(t => t !== 'SANCTIONS_MATCH'));
|
|
70
|
+
}
|
|
71
|
+
const st = (0, utils_1.choices)(pools_1.AML_STATUSES, [30, 28, 22, 20]);
|
|
72
|
+
const trig = (0, utils_1.randint)(1, 130);
|
|
73
|
+
let sarRef = null;
|
|
74
|
+
if (st === 'ESCALATED' && (c.risk_rating === 'HIGH' || c.is_sanctioned || (0, utils_1.chance)(0.5))) {
|
|
75
|
+
sarSeq += 1;
|
|
76
|
+
sarRef = `SAR-2026-${String(sarSeq).padStart(5, '0')}`;
|
|
77
|
+
}
|
|
78
|
+
const resolved = ['CLEARED', 'ESCALATED'].includes(st);
|
|
79
|
+
alerts.push({
|
|
80
|
+
id: aid,
|
|
81
|
+
customer_id: c.id,
|
|
82
|
+
alert_type: atype,
|
|
83
|
+
severity: amlSeverity(c.risk_rating, c.is_sanctioned, atype),
|
|
84
|
+
status: st,
|
|
85
|
+
triggered_at: (0, dates_1.daysAgo)(trig),
|
|
86
|
+
resolution_notes: alertNotes(st),
|
|
87
|
+
sar_reference: sarRef,
|
|
88
|
+
resolved_at: resolved ? (0, dates_1.daysAgo)((0, utils_1.randint)(1, Math.max(2, trig - 1))) : null,
|
|
89
|
+
linkedSarRef: sarRef,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const sars = [];
|
|
93
|
+
let sid = 0;
|
|
94
|
+
for (const a of alerts.filter(x => x.linkedSarRef)) {
|
|
95
|
+
sid += 1;
|
|
96
|
+
const start = (0, utils_1.randint)(40, 120);
|
|
97
|
+
const end = (0, utils_1.randint)(5, 35);
|
|
98
|
+
const status = (0, utils_1.choices)(pools_1.SAR_STATUSES, [25, 25, 50]);
|
|
99
|
+
const filedAt = (0, utils_1.chance)(0.6) ? (0, dates_1.daysAgo)((0, utils_1.randint)(1, end)) : null;
|
|
100
|
+
const createdAt = (0, dates_1.daysAgo)(end + (0, utils_1.randint)(1, 5));
|
|
101
|
+
sars.push({
|
|
102
|
+
id: sid,
|
|
103
|
+
alert_id: a.id,
|
|
104
|
+
customer_id: a.customer_id,
|
|
105
|
+
reference: a.linkedSarRef,
|
|
106
|
+
status,
|
|
107
|
+
activity_type: a.alert_type,
|
|
108
|
+
activity_start_date: (0, dates_1.dayOnlyAgo)(start),
|
|
109
|
+
activity_end_date: (0, dates_1.dayOnlyAgo)(end),
|
|
110
|
+
total_amount: (0, utils_1.round2)((0, utils_1.uniform)(8000, 240000)),
|
|
111
|
+
transaction_count: (0, utils_1.randint)(3, 80),
|
|
112
|
+
narrative: `Suspicious activity consistent with ${a.alert_type
|
|
113
|
+
.replace(/_/g, ' ')
|
|
114
|
+
.toLowerCase()} detected over ${start - end} days; cumulative value exceeds internal thresholds. Funds movement reviewed by compliance and escalated to the financial intelligence unit.`,
|
|
115
|
+
filed_at: filedAt,
|
|
116
|
+
created_at: createdAt,
|
|
117
|
+
});
|
|
118
|
+
// Coherence: an alert with a linked SAR reflects that SAR's state.
|
|
119
|
+
if (['FILED', 'SUBMITTED'].includes(status)) {
|
|
120
|
+
a.status = 'SAR_FILED';
|
|
121
|
+
a.resolved_at = a.resolved_at || filedAt || createdAt;
|
|
122
|
+
a.resolution_notes = `SAR ${a.linkedSarRef} filed with the FIU.`;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
a.status = 'ESCALATED';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
await (0, utils_1.insertAll)(knex, 'aml_alerts', alerts.map(({ linkedSarRef, ...row }) => row));
|
|
129
|
+
await (0, utils_1.insertAll)(knex, 'sar_reports', sars);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW1sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlZWQvYW1sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkNBLDBCQXdIQztBQWhLRCxtQ0FBOEM7QUFDOUMsbUNBQTZFO0FBQzdFLG1DQUFxRjtBQVlyRixTQUFTLFdBQVcsQ0FBQyxJQUFZLEVBQUUsVUFBbUIsRUFBRSxLQUFhO0lBQ25FLElBQUksVUFBVSxJQUFJLEtBQUssS0FBSyxpQkFBaUI7UUFBRSxPQUFPLElBQUEsZUFBTyxFQUFDLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFOUYsT0FBTyxJQUFBLGVBQU8sRUFDWixzQkFBYyxFQUNkLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FDN0QsSUFBaUMsQ0FDbEMsQ0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLE1BQWM7SUFDaEMsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDekIsT0FBTyxJQUFBLFlBQUksRUFBQyxDQUFDLGdDQUFnQyxFQUFFLHVCQUF1QixDQUFDLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRUQsSUFBSSxNQUFNLEtBQUssV0FBVztRQUFFLE9BQU8sSUFBQSxZQUFJLEVBQUMsQ0FBQyxvQkFBb0IsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDLENBQUM7SUFFakcsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNZLEtBQUssVUFBVSxPQUFPLENBQUMsSUFBVSxFQUFFLFNB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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Card, Customer } from './types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
export interface CardsResult {
|
|
4
|
+
cards: Card[];
|
|
5
|
+
cardsByCust: Record<number, Card[]>;
|
|
6
|
+
}
|
|
7
|
+
/** Issues 1–3 cards per customer; blocked cards carry a reason and a block date. */
|
|
8
|
+
export default function seedCards(knex: Knex, customers: Customer[]): Promise<CardsResult>;
|
|
9
|
+
//# sourceMappingURL=cards.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = seedCards;
|
|
4
|
+
const dates_1 = require("./dates");
|
|
5
|
+
const pools_1 = require("./pools");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
/** Issues 1–3 cards per customer; blocked cards carry a reason and a block date. */
|
|
8
|
+
async function seedCards(knex, customers) {
|
|
9
|
+
var _a;
|
|
10
|
+
await knex.schema.createTable('cards', table => {
|
|
11
|
+
table.increments('id').primary();
|
|
12
|
+
table.integer('customer_id');
|
|
13
|
+
table.string('card_type');
|
|
14
|
+
table.string('status');
|
|
15
|
+
table.string('last_four_digits');
|
|
16
|
+
table.datetime('issued_at');
|
|
17
|
+
table.date('expires_at');
|
|
18
|
+
table.string('blocked_reason');
|
|
19
|
+
table.datetime('blocked_at');
|
|
20
|
+
});
|
|
21
|
+
const cards = [];
|
|
22
|
+
const cardsByCust = {};
|
|
23
|
+
let cid = 0;
|
|
24
|
+
for (const c of customers) {
|
|
25
|
+
const n = (0, utils_1.randint)(1, 3);
|
|
26
|
+
for (let k = 0; k < n; k += 1) {
|
|
27
|
+
cid += 1;
|
|
28
|
+
const st = (0, utils_1.choices)(pools_1.CARD_STATUSES, [70, 11, 8, 7, 4]);
|
|
29
|
+
const issued = (0, utils_1.randint)(20, 380);
|
|
30
|
+
const card = {
|
|
31
|
+
id: cid,
|
|
32
|
+
customer_id: c.id,
|
|
33
|
+
card_type: (0, utils_1.choices)(pools_1.CARD_TYPES, [55, 45]),
|
|
34
|
+
status: st,
|
|
35
|
+
last_four_digits: String((0, utils_1.randint)(0, 9999)).padStart(4, '0'),
|
|
36
|
+
issued_at: (0, dates_1.daysAgo)(issued),
|
|
37
|
+
expires_at: (0, dates_1.dayOnlyAgo)(-(0, utils_1.randint)(365, 1460)),
|
|
38
|
+
blocked_reason: null,
|
|
39
|
+
blocked_at: null,
|
|
40
|
+
};
|
|
41
|
+
if (st === 'BLOCKED') {
|
|
42
|
+
card.blocked_reason = (0, utils_1.pick)([
|
|
43
|
+
'Suspected fraud',
|
|
44
|
+
'Reported lost',
|
|
45
|
+
'Compliance hold',
|
|
46
|
+
'Customer request',
|
|
47
|
+
]);
|
|
48
|
+
card.blocked_at = (0, dates_1.daysAgo)((0, utils_1.randint)(1, Math.max(2, issued - 5)));
|
|
49
|
+
}
|
|
50
|
+
cards.push(card);
|
|
51
|
+
(cardsByCust[_a = c.id] || (cardsByCust[_a] = [])).push(card);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
await (0, utils_1.insertAll)(knex, 'cards', cards);
|
|
55
|
+
return { cards, cardsByCust };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VlZC9jYXJkcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWFBLDRCQXNEQztBQWhFRCxtQ0FBOEM7QUFDOUMsbUNBQW9EO0FBQ3BELG1DQUE0RDtBQU81RCxvRkFBb0Y7QUFDckUsS0FBSyxVQUFVLFNBQVMsQ0FBQyxJQUFVLEVBQUUsU0FBcUI7O0lBQ3ZFLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFO1FBQzdDLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM3QixLQUFLLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFCLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2pDLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN6QixLQUFLLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDL0IsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUN6QixNQUFNLFdBQVcsR0FBMkIsRUFBRSxDQUFDO0lBQy9DLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztJQUVaLEtBQUssTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxDQUFDLEdBQUcsSUFBQSxlQUFPLEVBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzlCLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDVCxNQUFNLEVBQUUsR0FBRyxJQUFBLGVBQU8sRUFBQyxxQkFBYSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckQsTUFBTSxNQUFNLEdBQUcsSUFBQSxlQUFPLEVBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxHQUFTO2dCQUNqQixFQUFFLEVBQUUsR0FBRztnQkFDUCxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2pCLFNBQVMsRUFBRSxJQUFBLGVBQU8sRUFBQyxrQkFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QyxNQUFNLEVBQUUsRUFBRTtnQkFDVixnQkFBZ0IsRUFBRSxNQUFNLENBQUMsSUFBQSxlQUFPLEVBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7Z0JBQzNELFNBQVMsRUFBRSxJQUFBLGVBQU8sRUFBQyxNQUFNLENBQUM7Z0JBQzFCLFVBQVUsRUFBRSxJQUFBLGtCQUFVLEVBQUMsQ0FBQyxJQUFBLGVBQU8sRUFBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzNDLGNBQWMsRUFBRSxJQUFJO2dCQUNwQixVQUFVLEVBQUUsSUFBSTthQUNqQixDQUFDO1lBRUYsSUFBSSxFQUFFLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBQSxZQUFJLEVBQUM7b0JBQ3pCLGlCQUFpQjtvQkFDakIsZUFBZTtvQkFDZixpQkFBaUI7b0JBQ2pCLGtCQUFrQjtpQkFDbkIsQ0FBQyxDQUFDO2dCQUNILElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBQSxlQUFPLEVBQUMsSUFBQSxlQUFPLEVBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUVELEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakIsQ0FBQyxXQUFXLE1BQUMsQ0FBQyxDQUFDLEVBQUUsTUFBaEIsV0FBVyxPQUFXLEVBQUUsRUFBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sSUFBQSxpQkFBUyxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFdEMsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQztBQUNoQyxDQUFDIn0=
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Card, Customer, Refund } from './types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
/**
|
|
4
|
+
* Spreads chargebacks over 60 customers (1–5 each), each tied to one of the
|
|
5
|
+
* customer's cards and, for customer disputes, occasionally to an existing refund
|
|
6
|
+
* request — so the dispute trail links back to a real refund.
|
|
7
|
+
*/
|
|
8
|
+
export default function seedChargebacks(knex: Knex, customers: Customer[], cardsByCust: Record<number, Card[]>, refundsByCust: Record<number, Refund[]>): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=chargebacks.d.ts.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = seedChargebacks;
|
|
4
|
+
const dates_1 = require("./dates");
|
|
5
|
+
const pools_1 = require("./pools");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
/**
|
|
8
|
+
* Spreads chargebacks over 60 customers (1–5 each), each tied to one of the
|
|
9
|
+
* customer's cards and, for customer disputes, occasionally to an existing refund
|
|
10
|
+
* request — so the dispute trail links back to a real refund.
|
|
11
|
+
*/
|
|
12
|
+
async function seedChargebacks(knex, customers, cardsByCust, refundsByCust) {
|
|
13
|
+
await knex.schema.createTable('chargebacks', table => {
|
|
14
|
+
table.increments('id').primary();
|
|
15
|
+
table.string('reference');
|
|
16
|
+
table.integer('customer_id');
|
|
17
|
+
table.integer('card_id');
|
|
18
|
+
table.integer('refund_request_id');
|
|
19
|
+
table.string('transaction_id');
|
|
20
|
+
table.string('merchant_name');
|
|
21
|
+
table.string('merchant_category');
|
|
22
|
+
table.string('mcc_code');
|
|
23
|
+
table.float('transaction_amount');
|
|
24
|
+
table.string('transaction_currency');
|
|
25
|
+
table.date('transaction_date');
|
|
26
|
+
table.float('amount');
|
|
27
|
+
table.string('currency');
|
|
28
|
+
table.string('network');
|
|
29
|
+
table.string('reason_code');
|
|
30
|
+
table.string('reason_description');
|
|
31
|
+
table.string('source');
|
|
32
|
+
table.string('processor_dispute_id');
|
|
33
|
+
table.string('status');
|
|
34
|
+
table.datetime('filed_at');
|
|
35
|
+
table.datetime('representment_deadline');
|
|
36
|
+
table.datetime('decision_at');
|
|
37
|
+
table.string('evidence_url');
|
|
38
|
+
table.datetime('evidence_submitted_at');
|
|
39
|
+
table.boolean('provisional_credit_issued');
|
|
40
|
+
table.string('analyst_email');
|
|
41
|
+
table.string('resolution_notes');
|
|
42
|
+
table.datetime('created_at');
|
|
43
|
+
table.datetime('updated_at');
|
|
44
|
+
});
|
|
45
|
+
const chargebacks = [];
|
|
46
|
+
let cbid = 0;
|
|
47
|
+
const cbCusts = (0, utils_1.sample)(customers, 60);
|
|
48
|
+
const plan = [];
|
|
49
|
+
for (const c of cbCusts) {
|
|
50
|
+
for (let k = 0; k < (0, utils_1.choices)([1, 2, 3, 5], [46, 30, 17, 7]); k += 1)
|
|
51
|
+
plan.push(c);
|
|
52
|
+
}
|
|
53
|
+
for (const c of (0, utils_1.shuffle)(plan)) {
|
|
54
|
+
cbid += 1;
|
|
55
|
+
const [merch, cat, mcc] = (0, utils_1.pick)(pools_1.MERCHANTS);
|
|
56
|
+
const card = (0, utils_1.pick)(cardsByCust[c.id]);
|
|
57
|
+
const txAmount = (0, utils_1.round2)((0, utils_1.uniform)(12, 2400));
|
|
58
|
+
const amount = (0, utils_1.chance)(0.35) ? (0, utils_1.round2)(txAmount * (0, utils_1.uniform)(0.2, 0.9)) : txAmount; // partial disputes
|
|
59
|
+
const status = (0, utils_1.choices)(pools_1.CB_STATUS, [22, 16, 13, 13, 5, 5, 3, 3]);
|
|
60
|
+
const filed = (0, utils_1.randint)(1, 110);
|
|
61
|
+
const [rcode, rdesc] = (0, utils_1.pick)(pools_1.CB_REASONS);
|
|
62
|
+
const src = (0, utils_1.choices)(pools_1.SOURCES, [55, 30, 15]);
|
|
63
|
+
let rr = null;
|
|
64
|
+
if (src === 'CUSTOMER_DISPUTE' && refundsByCust[c.id] && (0, utils_1.chance)(0.4)) {
|
|
65
|
+
rr = (0, utils_1.pick)(refundsByCust[c.id]).id;
|
|
66
|
+
}
|
|
67
|
+
const decided = ['WON', 'LOST', 'ACCEPTED'].includes(status);
|
|
68
|
+
const presented = [
|
|
69
|
+
'PRESENTED',
|
|
70
|
+
'REPRESENTED',
|
|
71
|
+
'WON',
|
|
72
|
+
'LOST',
|
|
73
|
+
'ARBITRATION',
|
|
74
|
+
'PRE_ARBITRATION',
|
|
75
|
+
].includes(status);
|
|
76
|
+
chargebacks.push({
|
|
77
|
+
id: cbid,
|
|
78
|
+
reference: `CB-2026-${String(cbid).padStart(5, '0')}`,
|
|
79
|
+
customer_id: c.id,
|
|
80
|
+
card_id: card.id,
|
|
81
|
+
refund_request_id: rr,
|
|
82
|
+
transaction_id: `TXN-${(0, utils_1.randint)(10000, 99999)}`,
|
|
83
|
+
merchant_name: merch,
|
|
84
|
+
merchant_category: cat,
|
|
85
|
+
mcc_code: mcc,
|
|
86
|
+
transaction_amount: txAmount,
|
|
87
|
+
transaction_currency: 'EUR',
|
|
88
|
+
transaction_date: (0, dates_1.dayOnlyAgo)(filed + (0, utils_1.randint)(2, 20)),
|
|
89
|
+
amount,
|
|
90
|
+
currency: 'EUR',
|
|
91
|
+
network: (0, utils_1.pick)(pools_1.NETWORKS),
|
|
92
|
+
reason_code: rcode,
|
|
93
|
+
reason_description: rdesc,
|
|
94
|
+
source: src,
|
|
95
|
+
processor_dispute_id: (0, utils_1.chance)(0.7) ? `ADYEN-DSP-${(0, utils_1.randint)(100000, 999999)}` : null,
|
|
96
|
+
status,
|
|
97
|
+
filed_at: (0, dates_1.daysAgo)(filed),
|
|
98
|
+
representment_deadline: (0, dates_1.daysAgo)(filed - 30),
|
|
99
|
+
decision_at: decided ? (0, dates_1.daysAgo)((0, utils_1.randint)(1, Math.max(2, filed - 2))) : null,
|
|
100
|
+
evidence_url: presented && (0, utils_1.chance)(0.7) ? `https://disputes.neobank.eu/evidence/${cbid}.zip` : null,
|
|
101
|
+
evidence_submitted_at: presented && (0, utils_1.chance)(0.7) ? (0, dates_1.daysAgo)((0, utils_1.randint)(1, Math.max(2, filed - 1))) : null,
|
|
102
|
+
provisional_credit_issued: (0, utils_1.chance)(0.4),
|
|
103
|
+
analyst_email: (0, utils_1.chance)(0.6) ? (0, utils_1.pick)(pools_1.ANALYSTS) : null,
|
|
104
|
+
resolution_notes: decided
|
|
105
|
+
? (0, utils_1.pick)([
|
|
106
|
+
'Won at representment.',
|
|
107
|
+
'Lost — insufficient evidence.',
|
|
108
|
+
'Accepted liability.',
|
|
109
|
+
'Pending issuer response.',
|
|
110
|
+
])
|
|
111
|
+
: null,
|
|
112
|
+
created_at: (0, dates_1.daysAgo)(filed > 2 ? filed : 1),
|
|
113
|
+
updated_at: (0, dates_1.daysAgo)((0, utils_1.randint)(0, Math.max(1, filed - 1))),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
await (0, utils_1.insertAll)(knex, 'chargebacks', chargebacks);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcmdlYmFja3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VlZC9jaGFyZ2ViYWNrcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXNCQSxrQ0FxSEM7QUF4SUQsbUNBQThDO0FBQzlDLG1DQUF3RjtBQUN4RixtQ0FVaUI7QUFFakI7Ozs7R0FJRztBQUNZLEtBQUssVUFBVSxlQUFlLENBQzNDLElBQVUsRUFDVixTQUFxQixFQUNyQixXQUFtQyxFQUNuQyxhQUF1QztJQUV2QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsRUFBRTtRQUNuRCxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM3QixLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNuQyxLQUFLLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDL0IsS0FBSyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUM5QixLQUFLLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDbEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6QixLQUFLLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDbEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3JDLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUMvQixLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3RCLEtBQUssQ0FBQyxNQUFN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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Customer } from './types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the customer base, then derives every other table from it. Risk rating,
|
|
5
|
+
* PEP/sanctions flags and onboarding status are correlated on purpose: sanctioned
|
|
6
|
+
* customers never clear onboarding, high-risk ones skew towards risky countries.
|
|
7
|
+
*/
|
|
8
|
+
export default function seedCustomers(knex: Knex): Promise<Customer[]>;
|
|
9
|
+
//# sourceMappingURL=customers.d.ts.map
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = seedCustomers;
|
|
4
|
+
const dates_1 = require("./dates");
|
|
5
|
+
const pools_1 = require("./pools");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
const N = 150;
|
|
8
|
+
/**
|
|
9
|
+
* Builds the customer base, then derives every other table from it. Risk rating,
|
|
10
|
+
* PEP/sanctions flags and onboarding status are correlated on purpose: sanctioned
|
|
11
|
+
* customers never clear onboarding, high-risk ones skew towards risky countries.
|
|
12
|
+
*/
|
|
13
|
+
async function seedCustomers(knex) {
|
|
14
|
+
await knex.schema.createTable('customers', table => {
|
|
15
|
+
table.increments('id').primary();
|
|
16
|
+
table.string('first_name');
|
|
17
|
+
table.string('last_name');
|
|
18
|
+
table.string('email');
|
|
19
|
+
table.string('phone');
|
|
20
|
+
table.date('date_of_birth');
|
|
21
|
+
table.string('nationality');
|
|
22
|
+
table.string('country_of_residence');
|
|
23
|
+
table.string('address_line1');
|
|
24
|
+
table.string('address_line2');
|
|
25
|
+
table.string('city');
|
|
26
|
+
table.string('postal_code');
|
|
27
|
+
table.string('country');
|
|
28
|
+
table.string('onboarding_status');
|
|
29
|
+
table.string('risk_rating');
|
|
30
|
+
table.boolean('is_pep');
|
|
31
|
+
table.boolean('is_sanctioned');
|
|
32
|
+
table.string('referral_code');
|
|
33
|
+
table.datetime('created_at');
|
|
34
|
+
table.datetime('updated_at');
|
|
35
|
+
});
|
|
36
|
+
const nHigh = Math.round(N * 0.2);
|
|
37
|
+
const nMed = Math.round(N * 0.33);
|
|
38
|
+
const riskPlan = (0, utils_1.shuffle)([
|
|
39
|
+
...Array(nHigh).fill('HIGH'),
|
|
40
|
+
...Array(nMed).fill('MEDIUM'),
|
|
41
|
+
...Array(N - nHigh - nMed).fill('LOW'),
|
|
42
|
+
]);
|
|
43
|
+
const ids = Array.from({ length: N }, (_, i) => i + 1);
|
|
44
|
+
const highIds = ids.filter(i => riskPlan[i - 1] === 'HIGH');
|
|
45
|
+
const elevatedIds = ids.filter(i => ['HIGH', 'MEDIUM'].includes(riskPlan[i - 1]));
|
|
46
|
+
const sanctionedIds = new Set((0, utils_1.sample)(highIds, Math.max(2, Math.round(N * 0.035))));
|
|
47
|
+
const pepIds = new Set((0, utils_1.sample)(elevatedIds, Math.max(4, Math.round(N * 0.08))));
|
|
48
|
+
const customers = [];
|
|
49
|
+
const seenEmails = new Set();
|
|
50
|
+
for (let i = 1; i <= N; i += 1) {
|
|
51
|
+
const fn = pools_1.FIRST[(i - 1) % pools_1.FIRST.length];
|
|
52
|
+
const ln = pools_1.LAST[(i * 7) % pools_1.LAST.length];
|
|
53
|
+
const risk = riskPlan[i - 1];
|
|
54
|
+
const sanctioned = sanctionedIds.has(i);
|
|
55
|
+
const pep = pepIds.has(i);
|
|
56
|
+
let cor;
|
|
57
|
+
let onb;
|
|
58
|
+
if (risk === 'HIGH') {
|
|
59
|
+
cor = (0, utils_1.chance)(0.5) ? (0, utils_1.pick)(pools_1.HIGH_RISK_COUNTRIES) : (0, utils_1.pick)(pools_1.COUNTRIES);
|
|
60
|
+
onb = (0, utils_1.pick)(['APPROVED', 'PENDING_REVIEW', 'REJECTED']);
|
|
61
|
+
}
|
|
62
|
+
else if (risk === 'MEDIUM') {
|
|
63
|
+
cor = (0, utils_1.pick)(pools_1.COUNTRIES);
|
|
64
|
+
onb = (0, utils_1.pick)(['APPROVED', 'APPROVED', 'PENDING_REVIEW']);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
cor = (0, utils_1.pick)(pools_1.COUNTRIES);
|
|
68
|
+
onb = (0, utils_1.pick)(['APPROVED', 'APPROVED', 'APPROVED', 'STARTED']);
|
|
69
|
+
}
|
|
70
|
+
if (sanctioned)
|
|
71
|
+
onb = (0, utils_1.pick)(['REJECTED', 'PENDING_REVIEW']); // never clears onboarding
|
|
72
|
+
const country = pools_1.CITIES[cor] ? cor : (0, utils_1.pick)(pools_1.COUNTRIES);
|
|
73
|
+
const [city, postal] = (0, utils_1.pick)(pools_1.CITIES[country]);
|
|
74
|
+
const created = (0, utils_1.randint)(60, 220);
|
|
75
|
+
const slug = (0, pools_1.deaccent)(`${fn.toLowerCase()}.${ln.toLowerCase()}`);
|
|
76
|
+
let email = `${slug}@example.com`;
|
|
77
|
+
if (seenEmails.has(email))
|
|
78
|
+
email = `${slug}${i}@example.com`; // names repeat at scale
|
|
79
|
+
seenEmails.add(email);
|
|
80
|
+
customers.push({
|
|
81
|
+
id: i,
|
|
82
|
+
first_name: fn,
|
|
83
|
+
last_name: ln,
|
|
84
|
+
email,
|
|
85
|
+
phone: `+${pools_1.DIAL[cor] ?? '33'} ${(0, utils_1.randint)(600, 799)} ${(0, utils_1.randint)(100000, 999999)}`,
|
|
86
|
+
date_of_birth: `${(0, utils_1.randint)(1962, 2003)}-${String((0, utils_1.randint)(1, 12)).padStart(2, '0')}-${String((0, utils_1.randint)(1, 28)).padStart(2, '0')}`,
|
|
87
|
+
nationality: (0, utils_1.pick)(pools_1.COUNTRIES),
|
|
88
|
+
country_of_residence: cor,
|
|
89
|
+
address_line1: `${(0, utils_1.pick)(pools_1.STREETS)} ${(0, utils_1.randint)(1, 180)}`,
|
|
90
|
+
address_line2: (0, utils_1.chance)(0.8) ? null : `Apt ${(0, utils_1.randint)(1, 40)}`,
|
|
91
|
+
city,
|
|
92
|
+
postal_code: postal,
|
|
93
|
+
country,
|
|
94
|
+
onboarding_status: onb,
|
|
95
|
+
risk_rating: risk,
|
|
96
|
+
is_pep: pep,
|
|
97
|
+
is_sanctioned: sanctioned,
|
|
98
|
+
referral_code: (0, utils_1.chance)(0.7) ? null : `REF${(0, utils_1.randint)(1000, 9999)}`,
|
|
99
|
+
created_at: (0, dates_1.daysAgo)(created),
|
|
100
|
+
updated_at: (0, dates_1.daysAgo)((0, utils_1.randint)(1, Math.max(2, created - 10))),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
await (0, utils_1.insertAll)(knex, 'customers', customers);
|
|
104
|
+
return customers;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlZWQvY3VzdG9tZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBdUJBLGdDQXFHQztBQXpIRCxtQ0FBa0M7QUFDbEMsbUNBU2lCO0FBQ2pCLG1DQUE0RTtBQUU1RSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUM7QUFFZDs7OztHQUlHO0FBQ1ksS0FBSyxVQUFVLGFBQWEsQ0FBQyxJQUFVO0lBQ3BELE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxFQUFFO1FBQ2pELEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUMzQixLQUFLLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzFCLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0QixLQUFLLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzVCLEtBQUssQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3JDLEtBQUssQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDOUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUM5QixLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JCLEtBQUssQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN4QixLQUFLLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENB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
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** ISO timestamp `days` in the past (negative = future). */
|
|
2
|
+
export declare function daysAgo(days: number): string;
|
|
3
|
+
/** ISO timestamp `hours` in the past (negative = future). */
|
|
4
|
+
export declare function hoursAgo(hours: number): string;
|
|
5
|
+
/** `YYYY-MM-DD` date-only string `days` in the past (negative = future). */
|
|
6
|
+
export declare function dayOnlyAgo(days: number): string;
|
|
7
|
+
//# sourceMappingURL=dates.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Demo dates are computed relative to the moment the data source is loaded, so a
|
|
3
|
+
// project bootstrapped with `forest create demo` always shows fresh, recent data
|
|
4
|
+
// — regardless of when it is run.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.daysAgo = daysAgo;
|
|
7
|
+
exports.hoursAgo = hoursAgo;
|
|
8
|
+
exports.dayOnlyAgo = dayOnlyAgo;
|
|
9
|
+
function shifted(days) {
|
|
10
|
+
const date = new Date();
|
|
11
|
+
date.setUTCDate(date.getUTCDate() - days);
|
|
12
|
+
return date;
|
|
13
|
+
}
|
|
14
|
+
/** ISO timestamp `days` in the past (negative = future). */
|
|
15
|
+
function daysAgo(days) {
|
|
16
|
+
return shifted(days).toISOString();
|
|
17
|
+
}
|
|
18
|
+
/** ISO timestamp `hours` in the past (negative = future). */
|
|
19
|
+
function hoursAgo(hours) {
|
|
20
|
+
const date = new Date();
|
|
21
|
+
date.setUTCHours(date.getUTCHours() - hours);
|
|
22
|
+
return date.toISOString();
|
|
23
|
+
}
|
|
24
|
+
/** `YYYY-MM-DD` date-only string `days` in the past (negative = future). */
|
|
25
|
+
function dayOnlyAgo(days) {
|
|
26
|
+
return shifted(days).toISOString().slice(0, 10);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VlZC9kYXRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsaUZBQWlGO0FBQ2pGLGlGQUFpRjtBQUNqRixrQ0FBa0M7O0FBVWxDLDBCQUVDO0FBR0QsNEJBS0M7QUFHRCxnQ0FFQztBQXZCRCxTQUFTLE9BQU8sQ0FBQyxJQUFZO0lBQzNCLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFFMUMsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsNERBQTREO0FBQzVELFNBQWdCLE9BQU8sQ0FBQyxJQUFZO0lBQ2xDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQ3JDLENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsU0FBZ0IsUUFBUSxDQUFDLEtBQWE7SUFDcEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUN4QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUU3QyxPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUM1QixDQUFDO0FBRUQsNEVBQTRFO0FBQzVFLFNBQWdCLFVBQVUsQ0FBQyxJQUFZO0lBQ3JDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbEQsQ0FBQyJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Populates a fresh SQLite database at `filename` with the demo fintech dataset.
|
|
3
|
+
*
|
|
4
|
+
* Tables are built in dependency order — customers first, then everything that
|
|
5
|
+
* references them — so foreign keys resolve and the data stays coherent. The
|
|
6
|
+
* caller owns the file's lifecycle; we own the connection.
|
|
7
|
+
*/
|
|
8
|
+
export default function seed(filename: string): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = seed;
|
|
7
|
+
const knex_1 = __importDefault(require("knex"));
|
|
8
|
+
const aml_1 = __importDefault(require("./aml"));
|
|
9
|
+
const cards_1 = __importDefault(require("./cards"));
|
|
10
|
+
const chargebacks_1 = __importDefault(require("./chargebacks"));
|
|
11
|
+
const customers_1 = __importDefault(require("./customers"));
|
|
12
|
+
const kyc_1 = __importDefault(require("./kyc"));
|
|
13
|
+
const refunds_1 = __importDefault(require("./refunds"));
|
|
14
|
+
/**
|
|
15
|
+
* Populates a fresh SQLite database at `filename` with the demo fintech dataset.
|
|
16
|
+
*
|
|
17
|
+
* Tables are built in dependency order — customers first, then everything that
|
|
18
|
+
* references them — so foreign keys resolve and the data stays coherent. The
|
|
19
|
+
* caller owns the file's lifecycle; we own the connection.
|
|
20
|
+
*/
|
|
21
|
+
async function seed(filename) {
|
|
22
|
+
const knex = (0, knex_1.default)({
|
|
23
|
+
client: 'sqlite3',
|
|
24
|
+
connection: { filename },
|
|
25
|
+
useNullAsDefault: true,
|
|
26
|
+
});
|
|
27
|
+
try {
|
|
28
|
+
const customers = await (0, customers_1.default)(knex);
|
|
29
|
+
const { cardsByCust } = await (0, cards_1.default)(knex, customers);
|
|
30
|
+
const { refundsByCust } = await (0, refunds_1.default)(knex, customers);
|
|
31
|
+
await (0, kyc_1.default)(knex, customers);
|
|
32
|
+
await (0, aml_1.default)(knex, customers);
|
|
33
|
+
await (0, chargebacks_1.default)(knex, customers, cardsByCust, refundsByCust);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
await knex.destroy();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VlZC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQWdCQSx1QkFrQkM7QUFsQ0QsZ0RBQXdCO0FBRXhCLGdEQUE0QjtBQUM1QixvREFBZ0M7QUFDaEMsZ0VBQTRDO0FBQzVDLDREQUF3QztBQUN4QyxnREFBNEI7QUFDNUIsd0RBQW9DO0FBRXBDOzs7Ozs7R0FNRztBQUNZLEtBQUssVUFBVSxJQUFJLENBQUMsUUFBZ0I7SUFDakQsTUFBTSxJQUFJLEdBQUcsSUFBQSxjQUFJLEVBQUM7UUFDaEIsTUFBTSxFQUFFLFNBQVM7UUFDakIsVUFBVSxFQUFFLEVBQUUsUUFBUSxFQUFFO1FBQ3hCLGdCQUFnQixFQUFFLElBQUk7S0FDdkIsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDO1FBQ0gsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFBLG1CQUFhLEVBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLE1BQU0sSUFBQSxlQUFTLEVBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sRUFBRSxhQUFhLEVBQUUsR0FBRyxNQUFNLElBQUEsaUJBQVcsRUFBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFN0QsTUFBTSxJQUFBLGFBQU8sRUFBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0IsTUFBTSxJQUFBLGFBQU8sRUFBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0IsTUFBTSxJQUFBLHFCQUFlLEVBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDckUsQ0FBQztZQUFTLENBQUM7UUFDVCxNQUFNLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN2QixDQUFDO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Customer } from './types';
|
|
2
|
+
import type { Knex } from 'knex';
|
|
3
|
+
/**
|
|
4
|
+
* Opens KYC cases (1–2 per customer) plus their documents. Case status mirrors the
|
|
5
|
+
* customer's compliance profile: sanctioned/PEP customers escalate, approved ones
|
|
6
|
+
* tend to resolve cleanly.
|
|
7
|
+
*/
|
|
8
|
+
export default function seedKyc(knex: Knex, customers: Customer[]): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=kyc.d.ts.map
|