@openora/core 0.4.1-canary.39 → 0.4.1-canary.40
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/dist/.tsbuildinfo +1 -1
- package/dist/audit/plugin.d.ts.map +1 -1
- package/dist/audit/plugin.js +27 -0
- package/dist/audit/plugin.js.map +1 -1
- package/dist/common/errors/errors.classes.js +3 -3
- package/dist/common/errors/errors.classes.js.map +1 -1
- package/dist/common/errors/errors.mapper.js +1 -1
- package/dist/common/errors/errors.mapper.js.map +1 -1
- package/dist/compliance/__tests__/kyc.service.test.js +5 -0
- package/dist/compliance/__tests__/kyc.service.test.js.map +1 -1
- package/dist/compliance/service/kyc.service.js +1 -1
- package/dist/compliance/service/kyc.service.js.map +1 -1
- package/dist/contracts/adapters/identity-reader.d.ts +9 -3
- package/dist/contracts/adapters/identity-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/identity-reader.js.map +1 -1
- package/dist/contracts/adapters/index.d.ts +2 -0
- package/dist/contracts/adapters/index.d.ts.map +1 -1
- package/dist/contracts/adapters/index.js +1 -0
- package/dist/contracts/adapters/index.js.map +1 -1
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts +10 -0
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js +11 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js.map +1 -0
- package/dist/contracts/adapters/wallet-reader.d.ts +8 -0
- package/dist/contracts/adapters/wallet-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-reader.js.map +1 -1
- package/dist/contracts/schemas/events.d.ts +57 -0
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +12 -0
- package/dist/contracts/schemas/events.js.map +1 -1
- package/dist/contracts/schemas/platform-config.d.ts +9 -1
- package/dist/contracts/schemas/platform-config.d.ts.map +1 -1
- package/dist/contracts/schemas/player.d.ts +10 -2
- package/dist/contracts/schemas/player.d.ts.map +1 -1
- package/dist/contracts/schemas/tag.d.ts +65 -1
- package/dist/contracts/schemas/tag.d.ts.map +1 -1
- package/dist/contracts/schemas/tag.js +10 -0
- package/dist/contracts/schemas/tag.js.map +1 -1
- package/dist/iam/service/iam.service.d.ts +1 -1
- package/dist/pam/identity/adapters/identity-reader.service.d.ts +6 -4
- package/dist/pam/identity/adapters/identity-reader.service.d.ts.map +1 -1
- package/dist/pam/identity/adapters/identity-reader.service.js +19 -1
- package/dist/pam/identity/adapters/identity-reader.service.js.map +1 -1
- package/dist/pam/identity/service/identity.service.d.ts.map +1 -1
- package/dist/pam/identity/service/identity.service.js +4 -0
- package/dist/pam/identity/service/identity.service.js.map +1 -1
- package/dist/pam/player-management/__tests__/player.router.test.js +2 -2
- package/dist/pam/player-management/__tests__/player.router.test.js.map +1 -1
- package/dist/pam/player-management/__tests__/player.service.test.js +28 -2
- package/dist/pam/player-management/__tests__/player.service.test.js.map +1 -1
- package/dist/pam/player-management/contract/index.d.ts +21 -1
- package/dist/pam/player-management/contract/index.d.ts.map +1 -1
- package/dist/pam/player-management/plugin.js +1 -1
- package/dist/pam/player-management/plugin.js.map +1 -1
- package/dist/pam/player-management/router/index.d.ts +17 -1
- package/dist/pam/player-management/router/index.d.ts.map +1 -1
- package/dist/pam/player-management/service/player.service.d.ts +3 -1
- package/dist/pam/player-management/service/player.service.d.ts.map +1 -1
- package/dist/pam/player-management/service/player.service.js +14 -1
- package/dist/pam/player-management/service/player.service.js.map +1 -1
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js +600 -17
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js.map +1 -1
- package/dist/pam/tag/__tests__/tag-mappers.test.js +25 -0
- package/dist/pam/tag/__tests__/tag-mappers.test.js.map +1 -1
- package/dist/pam/tag/__tests__/tag.router.test.js +71 -1
- package/dist/pam/tag/__tests__/tag.router.test.js.map +1 -1
- package/dist/pam/tag/__tests__/tag.service.test.js +342 -15
- package/dist/pam/tag/__tests__/tag.service.test.js.map +1 -1
- package/dist/pam/tag/contract/index.d.ts +97 -0
- package/dist/pam/tag/contract/index.d.ts.map +1 -1
- package/dist/pam/tag/contract/index.js +3 -0
- package/dist/pam/tag/contract/index.js.map +1 -1
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts +37 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts.map +1 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js +20 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js.map +1 -0
- package/dist/pam/tag/drizzle/migrations/0002_silent_skaar.sql +4 -0
- package/dist/pam/tag/drizzle/migrations/0003_overconfident_guardian.sql +3 -0
- package/dist/pam/tag/drizzle/migrations/meta/0002_snapshot.json +335 -0
- package/dist/pam/tag/drizzle/migrations/meta/0003_snapshot.json +343 -0
- package/dist/pam/tag/drizzle/migrations/meta/_journal.json +14 -0
- package/dist/pam/tag/migrate.d.ts.map +1 -1
- package/dist/pam/tag/migrate.js +34 -0
- package/dist/pam/tag/migrate.js.map +1 -1
- package/dist/pam/tag/plugin.d.ts.map +1 -1
- package/dist/pam/tag/plugin.js +35 -16
- package/dist/pam/tag/plugin.js.map +1 -1
- package/dist/pam/tag/router/index.d.ts +81 -0
- package/dist/pam/tag/router/index.d.ts.map +1 -1
- package/dist/pam/tag/router/index.js +34 -18
- package/dist/pam/tag/router/index.js.map +1 -1
- package/dist/pam/tag/schema/index.d.ts +42 -3
- package/dist/pam/tag/schema/index.d.ts.map +1 -1
- package/dist/pam/tag/schema/index.js +13 -2
- package/dist/pam/tag/schema/index.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.js +28 -0
- package/dist/pam/tag/seed/data/default-tag-rules.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.js +4 -0
- package/dist/pam/tag/seed/data/default-tags.js.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.d.ts +113 -12
- package/dist/pam/tag/service/tag-evaluation.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.js +354 -35
- package/dist/pam/tag/service/tag-evaluation.service.js.map +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-mappers.js +1 -0
- package/dist/pam/tag/service/tag-mappers.js.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.d.ts +3 -3
- package/dist/pam/tag/service/tag.service.d.ts +141 -11
- package/dist/pam/tag/service/tag.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag.service.js +242 -23
- package/dist/pam/tag/service/tag.service.js.map +1 -1
- package/dist/server/auth/permissions.d.ts +12 -0
- package/dist/server/auth/permissions.d.ts.map +1 -1
- package/dist/server/auth/permissions.js +2 -0
- package/dist/server/auth/permissions.js.map +1 -1
- package/dist/server/db/__tests__/migrate.test.js +79 -2
- package/dist/server/db/__tests__/migrate.test.js.map +1 -1
- package/dist/server/db/migrate.d.ts +11 -0
- package/dist/server/db/migrate.d.ts.map +1 -1
- package/dist/server/db/migrate.js +3 -0
- package/dist/server/db/migrate.js.map +1 -1
- package/dist/server/plugin-host/__tests__/core-plugins.test.js +1 -1
- package/dist/server/plugin-host/__tests__/core-plugins.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js +60 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js.map +1 -1
- package/dist/wallet/__tests__/wallet.service.test.js +41 -0
- package/dist/wallet/__tests__/wallet.service.test.js.map +1 -1
- package/dist/wallet/adapters/wallet-reader.service.d.ts +1 -0
- package/dist/wallet/adapters/wallet-reader.service.d.ts.map +1 -1
- package/dist/wallet/adapters/wallet-reader.service.js +18 -1
- package/dist/wallet/adapters/wallet-reader.service.js.map +1 -1
- package/dist/wallet/plugin.d.ts.map +1 -1
- package/dist/wallet/plugin.js +7 -4
- package/dist/wallet/plugin.js.map +1 -1
- package/dist/wallet/service/wallet.service.d.ts +4 -2
- package/dist/wallet/service/wallet.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet.service.js +11 -1
- package/dist/wallet/service/wallet.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -14,6 +14,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
14
14
|
kyc_pending: "kyc_pending";
|
|
15
15
|
kyc_rejected: "kyc_rejected";
|
|
16
16
|
test_account: "test_account";
|
|
17
|
+
dormant_high_roller: "dormant_high_roller";
|
|
18
|
+
withdrawal_review: "withdrawal_review";
|
|
19
|
+
multi_account: "multi_account";
|
|
20
|
+
level: "level";
|
|
17
21
|
}>;
|
|
18
22
|
isSticky: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
19
23
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
@@ -29,6 +33,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
29
33
|
kyc_pending: "kyc_pending";
|
|
30
34
|
kyc_rejected: "kyc_rejected";
|
|
31
35
|
test_account: "test_account";
|
|
36
|
+
dormant_high_roller: "dormant_high_roller";
|
|
37
|
+
withdrawal_review: "withdrawal_review";
|
|
38
|
+
multi_account: "multi_account";
|
|
39
|
+
level: "level";
|
|
32
40
|
}>;
|
|
33
41
|
isSticky: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
34
42
|
createdAt: import("zod").ZodISODateTime;
|
|
@@ -46,6 +54,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
46
54
|
kyc_pending: "kyc_pending";
|
|
47
55
|
kyc_rejected: "kyc_rejected";
|
|
48
56
|
test_account: "test_account";
|
|
57
|
+
dormant_high_roller: "dormant_high_roller";
|
|
58
|
+
withdrawal_review: "withdrawal_review";
|
|
59
|
+
multi_account: "multi_account";
|
|
60
|
+
level: "level";
|
|
49
61
|
}>;
|
|
50
62
|
}, import("zod/v4/core").$strip>, import("zod").ZodBoolean, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
51
63
|
listPlayerTags: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<OssContext & Record<never, never>, OssContext & Record<never, never>, OssContext>, OssContext, import("zod").ZodObject<{
|
|
@@ -92,8 +104,23 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
92
104
|
kyc_pending: "kyc_pending";
|
|
93
105
|
kyc_rejected: "kyc_rejected";
|
|
94
106
|
test_account: "test_account";
|
|
107
|
+
dormant_high_roller: "dormant_high_roller";
|
|
108
|
+
withdrawal_review: "withdrawal_review";
|
|
109
|
+
multi_account: "multi_account";
|
|
110
|
+
level: "level";
|
|
95
111
|
}>;
|
|
96
112
|
}, import("zod/v4/core").$strip>;
|
|
113
|
+
assignMetadata: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
114
|
+
amountBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
115
|
+
amount: import("zod").ZodString;
|
|
116
|
+
threshold: import("zod").ZodString;
|
|
117
|
+
}, import("zod/v4/core").$strip>>;
|
|
118
|
+
countBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
119
|
+
count: import("zod").ZodNumber;
|
|
120
|
+
thresholdCount: import("zod").ZodNumber;
|
|
121
|
+
thresholdDays: import("zod").ZodNumber;
|
|
122
|
+
}, import("zod/v4/core").$strip>>;
|
|
123
|
+
}, import("zod/v4/core").$strip>>;
|
|
97
124
|
}, import("zod/v4/core").$strip>>;
|
|
98
125
|
total: import("zod").ZodNumber;
|
|
99
126
|
page: import("zod").ZodNumber;
|
|
@@ -117,6 +144,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
117
144
|
kyc_pending: "kyc_pending";
|
|
118
145
|
kyc_rejected: "kyc_rejected";
|
|
119
146
|
test_account: "test_account";
|
|
147
|
+
dormant_high_roller: "dormant_high_roller";
|
|
148
|
+
withdrawal_review: "withdrawal_review";
|
|
149
|
+
multi_account: "multi_account";
|
|
150
|
+
level: "level";
|
|
120
151
|
}>;
|
|
121
152
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
122
153
|
id: import("zod").ZodUUID;
|
|
@@ -149,8 +180,23 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
149
180
|
kyc_pending: "kyc_pending";
|
|
150
181
|
kyc_rejected: "kyc_rejected";
|
|
151
182
|
test_account: "test_account";
|
|
183
|
+
dormant_high_roller: "dormant_high_roller";
|
|
184
|
+
withdrawal_review: "withdrawal_review";
|
|
185
|
+
multi_account: "multi_account";
|
|
186
|
+
level: "level";
|
|
152
187
|
}>;
|
|
153
188
|
}, import("zod/v4/core").$strip>;
|
|
189
|
+
assignMetadata: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
190
|
+
amountBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
191
|
+
amount: import("zod").ZodString;
|
|
192
|
+
threshold: import("zod").ZodString;
|
|
193
|
+
}, import("zod/v4/core").$strip>>;
|
|
194
|
+
countBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
195
|
+
count: import("zod").ZodNumber;
|
|
196
|
+
thresholdCount: import("zod").ZodNumber;
|
|
197
|
+
thresholdDays: import("zod").ZodNumber;
|
|
198
|
+
}, import("zod/v4/core").$strip>>;
|
|
199
|
+
}, import("zod/v4/core").$strip>>;
|
|
154
200
|
}, import("zod/v4/core").$strip>, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
155
201
|
removePlayerTag: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<OssContext & Record<never, never>, OssContext & Record<never, never>, OssContext>, OssContext, import("zod").ZodObject<{
|
|
156
202
|
playerId: import("zod").ZodUUID;
|
|
@@ -170,6 +216,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
170
216
|
kyc_pending: "kyc_pending";
|
|
171
217
|
kyc_rejected: "kyc_rejected";
|
|
172
218
|
test_account: "test_account";
|
|
219
|
+
dormant_high_roller: "dormant_high_roller";
|
|
220
|
+
withdrawal_review: "withdrawal_review";
|
|
221
|
+
multi_account: "multi_account";
|
|
222
|
+
level: "level";
|
|
173
223
|
}>;
|
|
174
224
|
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
175
225
|
id: import("zod").ZodUUID;
|
|
@@ -202,8 +252,23 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
202
252
|
kyc_pending: "kyc_pending";
|
|
203
253
|
kyc_rejected: "kyc_rejected";
|
|
204
254
|
test_account: "test_account";
|
|
255
|
+
dormant_high_roller: "dormant_high_roller";
|
|
256
|
+
withdrawal_review: "withdrawal_review";
|
|
257
|
+
multi_account: "multi_account";
|
|
258
|
+
level: "level";
|
|
205
259
|
}>;
|
|
206
260
|
}, import("zod/v4/core").$strip>;
|
|
261
|
+
assignMetadata: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
262
|
+
amountBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
263
|
+
amount: import("zod").ZodString;
|
|
264
|
+
threshold: import("zod").ZodString;
|
|
265
|
+
}, import("zod/v4/core").$strip>>;
|
|
266
|
+
countBreach: import("zod").ZodNullable<import("zod").ZodObject<{
|
|
267
|
+
count: import("zod").ZodNumber;
|
|
268
|
+
thresholdCount: import("zod").ZodNumber;
|
|
269
|
+
thresholdDays: import("zod").ZodNumber;
|
|
270
|
+
}, import("zod/v4/core").$strip>>;
|
|
271
|
+
}, import("zod/v4/core").$strip>>;
|
|
207
272
|
}, import("zod/v4/core").$strip>, import("@orpc/server").MergedErrorMap<Record<never, never>, Record<never, never>>, Record<never, never>>;
|
|
208
273
|
listAssignableTags: import("@orpc/server").Procedure<import("@orpc/server").MergedInitialContext<OssContext & Record<never, never>, OssContext & Record<never, never>, OssContext>, OssContext, import("zod").ZodObject<{
|
|
209
274
|
playerId: import("zod").ZodUUID;
|
|
@@ -220,6 +285,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
220
285
|
kyc_pending: "kyc_pending";
|
|
221
286
|
kyc_rejected: "kyc_rejected";
|
|
222
287
|
test_account: "test_account";
|
|
288
|
+
dormant_high_roller: "dormant_high_roller";
|
|
289
|
+
withdrawal_review: "withdrawal_review";
|
|
290
|
+
multi_account: "multi_account";
|
|
291
|
+
level: "level";
|
|
223
292
|
}>;
|
|
224
293
|
isSticky: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
225
294
|
createdAt: import("zod").ZodISODateTime;
|
|
@@ -239,6 +308,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
239
308
|
kyc_pending: "kyc_pending";
|
|
240
309
|
kyc_rejected: "kyc_rejected";
|
|
241
310
|
test_account: "test_account";
|
|
311
|
+
dormant_high_roller: "dormant_high_roller";
|
|
312
|
+
withdrawal_review: "withdrawal_review";
|
|
313
|
+
multi_account: "multi_account";
|
|
314
|
+
level: "level";
|
|
242
315
|
}>;
|
|
243
316
|
isEnabled: import("zod").ZodBoolean;
|
|
244
317
|
threshold: import("zod").ZodNullable<import("zod").ZodString>;
|
|
@@ -259,6 +332,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
259
332
|
kyc_pending: "kyc_pending";
|
|
260
333
|
kyc_rejected: "kyc_rejected";
|
|
261
334
|
test_account: "test_account";
|
|
335
|
+
dormant_high_roller: "dormant_high_roller";
|
|
336
|
+
withdrawal_review: "withdrawal_review";
|
|
337
|
+
multi_account: "multi_account";
|
|
338
|
+
level: "level";
|
|
262
339
|
}>;
|
|
263
340
|
isEnabled: import("zod").ZodBoolean;
|
|
264
341
|
threshold: import("zod").ZodNullable<import("zod").ZodString>;
|
|
@@ -278,6 +355,10 @@ export declare function createTagRouter(tag: TagService, rule: TagRuleService, a
|
|
|
278
355
|
kyc_pending: "kyc_pending";
|
|
279
356
|
kyc_rejected: "kyc_rejected";
|
|
280
357
|
test_account: "test_account";
|
|
358
|
+
dormant_high_roller: "dormant_high_roller";
|
|
359
|
+
withdrawal_review: "withdrawal_review";
|
|
360
|
+
multi_account: "multi_account";
|
|
361
|
+
level: "level";
|
|
281
362
|
}>;
|
|
282
363
|
isEnabled: import("zod").ZodBoolean;
|
|
283
364
|
threshold: import("zod").ZodNullable<import("zod").ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pam/tag/router/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pam/tag/router/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,EACL,UAAU,EAMX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAwB,MAAM,gCAAgC,CAAC;AAEtF,wBAAgB,eAAe,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkE5F"}
|
|
@@ -1,32 +1,48 @@
|
|
|
1
1
|
import { implement } from '@orpc/server';
|
|
2
|
-
import { getUserId } from '@openora/core/server';
|
|
2
|
+
import { getUserId, mapErrors } from '@openora/core/server';
|
|
3
3
|
import { tagContract } from '../contract/index.js';
|
|
4
|
+
import { TagNotFoundError, TagAlreadyInUseError, TagAssignmentNotFoundError, TagKeyConflictError, TagInUseError, } from '../service/tag.service.js';
|
|
5
|
+
import { TagRuleNotFoundError } from '../service/tag-rule.service.js';
|
|
4
6
|
export function createTagRouter(tag, rule, adminGuard) {
|
|
5
7
|
const os = implement(tagContract).$context();
|
|
6
8
|
return os.router({
|
|
7
|
-
createTag: os.createTag.handler(({ input }) =>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
return tag.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
createTag: os.createTag.handler(async ({ context, input }) => {
|
|
10
|
+
await adminGuard.assert(context, 'tag', 'create');
|
|
11
|
+
return mapErrors({ CONFLICT: TagKeyConflictError }, () => tag.createTag(input, getUserId(context)));
|
|
12
|
+
}),
|
|
13
|
+
deleteTag: os.deleteTag.handler(async ({ context, input }) => {
|
|
14
|
+
await adminGuard.assert(context, 'tag', 'delete');
|
|
15
|
+
return mapErrors({ NOT_FOUND: TagNotFoundError, CONFLICT: TagInUseError }, () => tag.deleteTag(input, getUserId(context)));
|
|
16
|
+
}),
|
|
17
|
+
listPlayerTags: os.listPlayerTags.handler(async ({ context, input }) => {
|
|
18
|
+
await adminGuard.assert(context, 'tag', 'view');
|
|
19
|
+
return tag.listPlayerTags({
|
|
20
|
+
playerId: input.playerId,
|
|
21
|
+
page: input.page,
|
|
22
|
+
limit: input.limit,
|
|
23
|
+
sortBy: input.sortBy,
|
|
24
|
+
sortOrder: input.sortOrder,
|
|
25
|
+
});
|
|
26
|
+
}),
|
|
27
|
+
assignPlayerTag: os.assignPlayerTag.handler(async ({ context, input }) => {
|
|
28
|
+
await adminGuard.assert(context, 'tag', 'create');
|
|
29
|
+
return mapErrors({ NOT_FOUND: TagNotFoundError, CONFLICT: TagAlreadyInUseError }, () => tag.assignPlayerTag({ ...input, assignActorUserId: getUserId(context) }, context.clientMeta));
|
|
30
|
+
}),
|
|
31
|
+
removePlayerTag: os.removePlayerTag.handler(async ({ context, input }) => {
|
|
32
|
+
await adminGuard.assert(context, 'tag', 'delete');
|
|
33
|
+
return mapErrors({ NOT_FOUND: [TagNotFoundError, TagAssignmentNotFoundError] }, () => tag.removePlayerTag({ ...input, removalActorUserId: getUserId(context) }, context.clientMeta));
|
|
34
|
+
}),
|
|
35
|
+
listAssignableTags: os.listAssignableTags.handler(async ({ context, input }) => {
|
|
36
|
+
await adminGuard.assert(context, 'tag', 'view');
|
|
37
|
+
return tag.listAssignableTags(input.playerId);
|
|
38
|
+
}),
|
|
23
39
|
listTagRules: os.listTagRules.handler(async ({ context }) => {
|
|
24
40
|
await adminGuard.assert(context, 'tag-rule', 'view');
|
|
25
41
|
return rule.listTagRules();
|
|
26
42
|
}),
|
|
27
43
|
upsertTagRule: os.upsertTagRule.handler(async ({ context, input }) => {
|
|
28
44
|
const { userId, ip, userAgent } = await adminGuard.assert(context, 'tag-rule', 'update');
|
|
29
|
-
return rule.upsertTagRule(input, userId, { ip, userAgent });
|
|
45
|
+
return mapErrors({ NOT_FOUND: TagRuleNotFoundError }, () => rule.upsertTagRule(input, userId, { ip, userAgent }));
|
|
30
46
|
}),
|
|
31
47
|
});
|
|
32
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pam/tag/router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAoC,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pam/tag/router/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const tagAssignRemoveSourceEnum: import("drizzle-orm/pg-core").PgEnum<["scheduled", "manual"]>;
|
|
2
|
-
export declare const tagKeyEnum: import("drizzle-orm/pg-core").PgEnum<["high_roller", "vip", "bonus_abuser", "high_risk", "inactive", "large_depositor", "self_excluded", "kyc_pending", "kyc_rejected", "test_account"]>;
|
|
2
|
+
export declare const tagKeyEnum: import("drizzle-orm/pg-core").PgEnum<["high_roller", "vip", "bonus_abuser", "high_risk", "inactive", "large_depositor", "self_excluded", "kyc_pending", "kyc_rejected", "test_account", "dormant_high_roller", "withdrawal_review", "multi_account", "level"]>;
|
|
3
3
|
export declare const tag: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
4
|
name: "tag";
|
|
5
5
|
schema: undefined;
|
|
@@ -26,14 +26,14 @@ export declare const tag: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
26
26
|
tableName: "tag";
|
|
27
27
|
dataType: "string";
|
|
28
28
|
columnType: "PgEnumColumn";
|
|
29
|
-
data: "high_roller" | "vip" | "bonus_abuser" | "high_risk" | "inactive" | "large_depositor" | "self_excluded" | "kyc_pending" | "kyc_rejected" | "test_account";
|
|
29
|
+
data: "high_roller" | "vip" | "bonus_abuser" | "high_risk" | "inactive" | "large_depositor" | "self_excluded" | "kyc_pending" | "kyc_rejected" | "test_account" | "dormant_high_roller" | "withdrawal_review" | "multi_account" | "level";
|
|
30
30
|
driverParam: string;
|
|
31
31
|
notNull: true;
|
|
32
32
|
hasDefault: false;
|
|
33
33
|
isPrimaryKey: false;
|
|
34
34
|
isAutoincrement: false;
|
|
35
35
|
hasRuntimeDefault: false;
|
|
36
|
-
enumValues: ["high_roller", "vip", "bonus_abuser", "high_risk", "inactive", "large_depositor", "self_excluded", "kyc_pending", "kyc_rejected", "test_account"];
|
|
36
|
+
enumValues: ["high_roller", "vip", "bonus_abuser", "high_risk", "inactive", "large_depositor", "self_excluded", "kyc_pending", "kyc_rejected", "test_account", "dormant_high_roller", "withdrawal_review", "multi_account", "level"];
|
|
37
37
|
baseColumn: never;
|
|
38
38
|
identity: undefined;
|
|
39
39
|
generated: undefined;
|
|
@@ -198,6 +198,45 @@ export declare const playerTag: import("drizzle-orm/pg-core").PgTableWithColumns
|
|
|
198
198
|
identity: undefined;
|
|
199
199
|
generated: undefined;
|
|
200
200
|
}, {}, {}>;
|
|
201
|
+
assignMetadata: import("drizzle-orm/pg-core").PgColumn<{
|
|
202
|
+
name: "assignMetadata";
|
|
203
|
+
tableName: "player_tag";
|
|
204
|
+
dataType: "json";
|
|
205
|
+
columnType: "PgJsonb";
|
|
206
|
+
data: {
|
|
207
|
+
amountBreach: {
|
|
208
|
+
amount: string;
|
|
209
|
+
threshold: string;
|
|
210
|
+
} | null;
|
|
211
|
+
countBreach: {
|
|
212
|
+
count: number;
|
|
213
|
+
thresholdCount: number;
|
|
214
|
+
thresholdDays: number;
|
|
215
|
+
} | null;
|
|
216
|
+
};
|
|
217
|
+
driverParam: unknown;
|
|
218
|
+
notNull: false;
|
|
219
|
+
hasDefault: false;
|
|
220
|
+
isPrimaryKey: false;
|
|
221
|
+
isAutoincrement: false;
|
|
222
|
+
hasRuntimeDefault: false;
|
|
223
|
+
enumValues: undefined;
|
|
224
|
+
baseColumn: never;
|
|
225
|
+
identity: undefined;
|
|
226
|
+
generated: undefined;
|
|
227
|
+
}, {}, {
|
|
228
|
+
$type: {
|
|
229
|
+
amountBreach: {
|
|
230
|
+
amount: string;
|
|
231
|
+
threshold: string;
|
|
232
|
+
} | null;
|
|
233
|
+
countBreach: {
|
|
234
|
+
count: number;
|
|
235
|
+
thresholdCount: number;
|
|
236
|
+
thresholdDays: number;
|
|
237
|
+
} | null;
|
|
238
|
+
};
|
|
239
|
+
}>;
|
|
201
240
|
removedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
202
241
|
name: "removedAt";
|
|
203
242
|
tableName: "player_tag";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pam/tag/schema/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/pam/tag/schema/index.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,yBAAyB,+DAA4D,CAAC;AACnG,eAAO,MAAM,UAAU,gQAA6B,CAAC;AAErD,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQd,CAAC;AAEH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCrB,CAAC;AAEF,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,CAAC,YAAY,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,YAAY,CAAC;AAEtD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBlB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { tagAssignRemoveSource, tagKeys } from '@openora/core/contracts';
|
|
2
|
-
import {
|
|
2
|
+
import { isNull } from 'drizzle-orm';
|
|
3
|
+
import { pgTable, uuid, text, timestamp, index, uniqueIndex, boolean, pgEnum, integer, decimal, jsonb, } from 'drizzle-orm/pg-core';
|
|
3
4
|
export const tagAssignRemoveSourceEnum = pgEnum('tag_assign_remove_source', tagAssignRemoveSource);
|
|
4
5
|
export const tagKeyEnum = pgEnum('tag_key', tagKeys);
|
|
5
6
|
export const tag = pgTable('tag', {
|
|
@@ -23,6 +24,7 @@ export const playerTag = pgTable('player_tag', {
|
|
|
23
24
|
assignReason: text().notNull(),
|
|
24
25
|
assignActor: tagAssignRemoveSourceEnum().notNull(),
|
|
25
26
|
assignActorUserId: uuid() /* Potential FKey - user; null = system actor */,
|
|
27
|
+
assignMetadata: jsonb().$type(),
|
|
26
28
|
/* Removal data */
|
|
27
29
|
removedAt: timestamp({ withTimezone: true }),
|
|
28
30
|
removalReason: text(),
|
|
@@ -33,7 +35,16 @@ export const playerTag = pgTable('player_tag', {
|
|
|
33
35
|
.notNull()
|
|
34
36
|
.$onUpdateFn(() => new Date()),
|
|
35
37
|
createdAt: timestamp({ withTimezone: true }).notNull().defaultNow(),
|
|
36
|
-
}, (table) => [
|
|
38
|
+
}, (table) => [
|
|
39
|
+
index('player_tag_player_tag_idx').on(table.playerId, table.tagId),
|
|
40
|
+
index('player_tag_tag_id_idx').on(table.tagId).where(isNull(table.removedAt)),
|
|
41
|
+
// DB-level source of truth for "at most one active assignment per (tag, player)" -
|
|
42
|
+
// the service pre-check is a friendly fast path only; this index is what actually
|
|
43
|
+
// closes the concurrent-insert / at-least-once-redelivery race.
|
|
44
|
+
uniqueIndex('player_tag_active_key')
|
|
45
|
+
.on(table.tagId, table.playerId)
|
|
46
|
+
.where(isNull(table.removedAt)),
|
|
47
|
+
]);
|
|
37
48
|
export const tagRule = pgTable('tag_rule', {
|
|
38
49
|
id: uuid().primaryKey().defaultRandom(),
|
|
39
50
|
tagId: uuid()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pam/tag/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EACL,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,KAAK,EACL,OAAO,EACP,MAAM,EACN,OAAO,EACP,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/pam/tag/schema/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-tag-rules.d.ts","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tag-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"default-tag-rules.d.ts","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tag-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,EAuEjD,CAAC"}
|
|
@@ -13,6 +13,13 @@ export const DEFAULT_TAG_RULES = [
|
|
|
13
13
|
thresholdDays: null,
|
|
14
14
|
thresholdCount: null,
|
|
15
15
|
},
|
|
16
|
+
{
|
|
17
|
+
tagKey: 'bonus_abuser',
|
|
18
|
+
isEnabled: true,
|
|
19
|
+
threshold: null,
|
|
20
|
+
thresholdDays: null,
|
|
21
|
+
thresholdCount: null,
|
|
22
|
+
},
|
|
16
23
|
{
|
|
17
24
|
tagKey: 'high_risk',
|
|
18
25
|
isEnabled: false,
|
|
@@ -41,5 +48,26 @@ export const DEFAULT_TAG_RULES = [
|
|
|
41
48
|
thresholdDays: null,
|
|
42
49
|
thresholdCount: null,
|
|
43
50
|
},
|
|
51
|
+
{
|
|
52
|
+
tagKey: 'multi_account',
|
|
53
|
+
isEnabled: true,
|
|
54
|
+
threshold: null,
|
|
55
|
+
thresholdDays: null,
|
|
56
|
+
thresholdCount: null,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
tagKey: 'dormant_high_roller',
|
|
60
|
+
isEnabled: false,
|
|
61
|
+
threshold: null,
|
|
62
|
+
thresholdDays: null,
|
|
63
|
+
thresholdCount: null,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
tagKey: 'withdrawal_review',
|
|
67
|
+
isEnabled: false,
|
|
68
|
+
threshold: null,
|
|
69
|
+
thresholdDays: null,
|
|
70
|
+
thresholdCount: null,
|
|
71
|
+
},
|
|
44
72
|
];
|
|
45
73
|
//# sourceMappingURL=default-tag-rules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-tag-rules.js","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tag-rules.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAyB;IACrD;QACE,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,UAAU;QAClB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"default-tag-rules.js","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tag-rules.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAyB;IACrD;QACE,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,UAAU;QAClB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,cAAc;QACtB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,eAAe;QACvB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,qBAAqB;QAC7B,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;IACD;QACE,MAAM,EAAE,mBAAmB;QAC3B,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,IAAI;KACrB;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-tags.d.ts","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,eAAO,MAAM,YAAY,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"default-tags.d.ts","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,eAAO,MAAM,YAAY,EAAE,cAAc,EAexC,CAAC"}
|
|
@@ -9,5 +9,9 @@ export const DEFAULT_TAGS = [
|
|
|
9
9
|
{ key: 'kyc_pending', isSticky: false },
|
|
10
10
|
{ key: 'kyc_rejected', isSticky: true },
|
|
11
11
|
{ key: 'test_account', isSticky: true },
|
|
12
|
+
{ key: 'dormant_high_roller', isSticky: false },
|
|
13
|
+
{ key: 'withdrawal_review', isSticky: true },
|
|
14
|
+
{ key: 'multi_account', isSticky: true },
|
|
15
|
+
{ key: 'level', isSticky: false },
|
|
12
16
|
];
|
|
13
17
|
//# sourceMappingURL=default-tags.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-tags.js","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tags.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9B,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvC,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpC,EAAE,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;IACxC,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvC,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvC,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"default-tags.js","sourceRoot":"","sources":["../../../../../src/pam/tag/seed/data/default-tags.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC9B,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvC,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpC,EAAE,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;IACxC,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;IACvC,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvC,EAAE,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE;IACvC,EAAE,GAAG,EAAE,qBAAqB,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC/C,EAAE,GAAG,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC5C,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;IACxC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;CAClC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WalletReader, type IdentityReader } from '@openora/core/contracts';
|
|
1
|
+
import { type WalletReader, type IdentityReader, type User } from '@openora/core/contracts';
|
|
2
2
|
import { TagService } from './tag.service.js';
|
|
3
3
|
import { TagRuleService } from './tag-rule.service.js';
|
|
4
4
|
export declare class TagEvaluationService {
|
|
@@ -18,37 +18,138 @@ export declare class TagEvaluationService {
|
|
|
18
18
|
* Called on wallet.deposit.completed.
|
|
19
19
|
*/
|
|
20
20
|
onDepositCompleted(payload: unknown): Promise<void>;
|
|
21
|
+
/** True when the withdrawal_review rule is enabled and amount crosses its threshold. Shared by the event path and the synchronous command-port path below so both stay in lockstep. */
|
|
22
|
+
private _withdrawalReviewThresholdCrossed;
|
|
23
|
+
/**
|
|
24
|
+
* Assigns withdrawal_review when a single withdrawal attempt exceeds its threshold.
|
|
25
|
+
* Called on wallet.withdrawal.requested (the attempt, before funds move) so the
|
|
26
|
+
* review tag lands before payout. Sticky - never auto-removed here or anywhere else.
|
|
27
|
+
* This is the async, best-effort fan-out path (other consumers may want the event) -
|
|
28
|
+
* wallet's own auto-approval decision does NOT wait on this; it calls
|
|
29
|
+
* evaluateWithdrawalRequested below instead. Idempotent with that path via
|
|
30
|
+
* TagAlreadyInUseError (see tryAssignTag).
|
|
31
|
+
*/
|
|
32
|
+
onWithdrawalRequested(payload: unknown): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Synchronous, transactional counterpart to onWithdrawalRequested, bound behind
|
|
35
|
+
* TAG_EVALUATION_COMMANDS. wallet.withdraw() awaits this on its own transaction handle
|
|
36
|
+
* BEFORE its maybeAutoApprove reads risk tags, so a withdrawal_review assignment is
|
|
37
|
+
* guaranteed committed before the auto-approval decision runs - closing the race the
|
|
38
|
+
* fire-and-forget EventBus emit above cannot (an EventBus emit is never awaited by the
|
|
39
|
+
* emitter). Money-adjacent: never events-only for this decision (see
|
|
40
|
+
* messaging-and-microservices "money never flows over events"). Any error here
|
|
41
|
+
* propagates and aborts the caller's withdrawal transaction - a review-gate evaluation
|
|
42
|
+
* failure must block the withdrawal rather than silently skip review.
|
|
43
|
+
*/
|
|
44
|
+
evaluateWithdrawalRequested(tx: unknown, args: {
|
|
45
|
+
userId: User['id'];
|
|
46
|
+
amount: string;
|
|
47
|
+
}): Promise<void>;
|
|
21
48
|
/**
|
|
22
49
|
* Evaluates the high_risk rule based on withdrawal amount and frequency.
|
|
23
|
-
* Called on wallet.withdrawal.completed.
|
|
24
|
-
*
|
|
25
|
-
* (
|
|
50
|
+
* Called on wallet.withdrawal.completed. Only assigns the tag when a threshold is
|
|
51
|
+
* crossed; removal is handled separately by the daily resweep in runDailyEvaluation
|
|
52
|
+
* (a rolling-window count/amount can drop back under threshold with no new
|
|
53
|
+
* withdrawal, so it can't be detected event-driven-only). Records which breach
|
|
54
|
+
* condition(s) fired in assignMetadata - the resweep uses this to know whether the
|
|
55
|
+
* amount dimension (never resweepable, see _runHighRiskResweep) was involved.
|
|
26
56
|
*/
|
|
27
57
|
onWithdrawalCompleted(payload: unknown): Promise<void>;
|
|
28
58
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
59
|
+
* Handles password login side effects:
|
|
60
|
+
* - removes inactive/dormant_high_roller on activity
|
|
61
|
+
* - assigns multi_account + bonus_abuser when another player has used this login IP
|
|
31
62
|
*/
|
|
32
63
|
onUserLogin(payload: unknown): Promise<void>;
|
|
33
64
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
65
|
+
* Phone-login path mirrors password-login risk evaluation. The signal is the same
|
|
66
|
+
* authenticated session IP; the login method is intentionally not encoded in the tag.
|
|
67
|
+
*/
|
|
68
|
+
onUserPhoneLogin(payload: unknown): Promise<void>;
|
|
69
|
+
private onAuthenticatedLogin;
|
|
70
|
+
private evaluateSharedLoginIp;
|
|
71
|
+
/**
|
|
72
|
+
* Applies kyc_pending on KYC submission only while the profile still has a pending-like
|
|
73
|
+
* status. Does not clear kyc_rejected: that sticky tag remains until a later approved
|
|
74
|
+
* state explicitly clears it.
|
|
36
75
|
*/
|
|
37
76
|
onKycSubmitted(payload: unknown): Promise<void>;
|
|
38
77
|
/**
|
|
39
78
|
* Manages kyc_pending / kyc_rejected lifecycle on KYC status changes.
|
|
40
|
-
* Called on compliance.kyc.updated.
|
|
79
|
+
* Called on compliance.kyc.updated. Assignment respects each tag rule's isEnabled flag;
|
|
80
|
+
* terminal cleanup still runs so disabled rules cannot strand old active rows.
|
|
41
81
|
*
|
|
42
82
|
* Transitions:
|
|
43
83
|
* verified / manually_overridden -> remove kyc_pending + kyc_rejected
|
|
44
84
|
* rejected -> remove kyc_pending, assign kyc_rejected
|
|
45
|
-
* resubmission_requested -> assign kyc_pending
|
|
85
|
+
* resubmission_requested -> assign kyc_pending, keep kyc_rejected sticky
|
|
46
86
|
*/
|
|
47
87
|
onKycStatusUpdated(payload: unknown): Promise<void>;
|
|
48
88
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
89
|
+
* Assigns self_excluded when a player activates self-exclusion.
|
|
90
|
+
* Called on rg.self_exclusion.activated.
|
|
91
|
+
*/
|
|
92
|
+
onSelfExclusionActivated(payload: unknown): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Removes self_excluded when a player's self-exclusion is lifted.
|
|
95
|
+
* Called on rg.self_exclusion.lifted.
|
|
96
|
+
*/
|
|
97
|
+
onSelfExclusionLifted(payload: unknown): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Replaces the single mutable `level` tag with the player's new level.
|
|
100
|
+
* Called on player.level.changed (emitted by PlayerService.update() after commit).
|
|
101
|
+
* Not sticky - the level value lives only in assignReason text, never as a separate
|
|
102
|
+
* tag key per level. The swap goes through TagService.replacePlayerTag: removal of
|
|
103
|
+
* the prior active row (silent no-op when absent) + insert of the new one on ONE
|
|
104
|
+
* transaction, so a mid-swap failure can never strand the player with the old row
|
|
105
|
+
* removed and no new one committed. The loser of a concurrent replace throws
|
|
106
|
+
* TagAlreadyInUseError with nothing committed - swallowed here as the usual
|
|
107
|
+
* idempotent no-op (player.level itself stays the source of truth).
|
|
108
|
+
*/
|
|
109
|
+
onPlayerLevelChanged(payload: unknown): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Daily scheduled evaluation, three independent sweeps:
|
|
112
|
+
* - inactive: assigns to players who have not logged in for rule.thresholdDays
|
|
113
|
+
* days. Removal is handled by onUserLogin on next login.
|
|
114
|
+
* - dormant_high_roller: a co-occurrence check, not a history lookup - high_roller
|
|
115
|
+
* is only re-evaluated on deposit, so a player who goes quiet never loses it via
|
|
116
|
+
* that path. Assigns to players who are both currently inactive (per this tag's
|
|
117
|
+
* OWN thresholdDays, decoupled from the inactive rule's) and currently hold an
|
|
118
|
+
* active high_roller tag. Removal is handled by onUserLogin on next login.
|
|
119
|
+
* - high_risk resweep: removal-only, frequency dimension only. A rolling
|
|
120
|
+
* withdrawal-count window can drop back under threshold with no new withdrawal
|
|
121
|
+
* to trigger onWithdrawalCompleted, so current holders are rechecked here and
|
|
122
|
+
* removed once the count falls below threshold. Deliberately does NOT recheck
|
|
123
|
+
* the amount dimension - assignment's amount check has no time bound, so a
|
|
124
|
+
* windowed recheck would silently de-designate a still-risky player once their
|
|
125
|
+
* triggering withdrawal ages out of the window (an AML false negative). Now gated
|
|
126
|
+
* on each holder's assignMetadata (recorded at assignment): a holder whose
|
|
127
|
+
* metadata shows an amount breach is skipped regardless of their current count,
|
|
128
|
+
* and a holder with null metadata (pre-migration/legacy row, or manually
|
|
129
|
+
* assigned) is also skipped - "unknown why this was assigned" is treated as
|
|
130
|
+
* "do not auto-remove". Skipped entirely when thresholdDays or thresholdCount is
|
|
131
|
+
* null - an amount-only high_risk rule isn't resweepable by the cron; it stays
|
|
132
|
+
* until an admin clears it or a future withdrawal re-triggers assignment.
|
|
51
133
|
*/
|
|
52
134
|
runDailyEvaluation(): Promise<void>;
|
|
135
|
+
private _runInactiveSweep;
|
|
136
|
+
private _runDormantHighRollerSweep;
|
|
137
|
+
/**
|
|
138
|
+
* Frequency-only removal. Assignment (onWithdrawalCompleted) checks a single
|
|
139
|
+
* withdrawal's amount with no time bound, so an amount-only breach from outside
|
|
140
|
+
* this rolling window is invisible to a windowed recheck - resweeping it would
|
|
141
|
+
* silently de-designate a still-risky player (an AML false negative). Only the
|
|
142
|
+
* count dimension, which IS windowed at assignment time, is safe to resweep. Each
|
|
143
|
+
* holder's assignMetadata (recorded at assignment) records which breach dimension(s)
|
|
144
|
+
* fired; a holder whose metadata shows an amount breach, or whose metadata is null
|
|
145
|
+
* (pre-migration/legacy row or manual assignment - unknown why it was assigned), is
|
|
146
|
+
* skipped regardless of their current windowed count - pinned until an admin
|
|
147
|
+
* manually clears the tag or a future onWithdrawalCompleted re-evaluation populates
|
|
148
|
+
* metadata. Skipped entirely when thresholdDays or thresholdCount is null - an
|
|
149
|
+
* amount-only rule has no frequency dimension to resweep against and is never
|
|
150
|
+
* auto-cleared by the cron, only by an admin or a future onWithdrawalCompleted
|
|
151
|
+
* re-evaluation.
|
|
152
|
+
*/
|
|
153
|
+
private _runHighRiskResweep;
|
|
53
154
|
}
|
|
54
155
|
//# sourceMappingURL=tag-evaluation.service.d.ts.map
|