@inspirer-dev/crm-dashboard 1.0.3
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/admin/src/components/RulesBuilder/constants.ts +316 -0
- package/admin/src/components/RulesBuilder/index.tsx +506 -0
- package/admin/src/components/RulesBuilder/types.ts +69 -0
- package/admin/src/components/RulesBuilder/utils.ts +203 -0
- package/admin/src/index.ts +71 -0
- package/admin/src/pages/HomePage/index.tsx +500 -0
- package/admin/src/translations/en.json +5 -0
- package/admin/src/translations/ru.json +5 -0
- package/admin/tsconfig.json +8 -0
- package/dist/_chunks/en-CC6nrL6u.mjs +8 -0
- package/dist/_chunks/en-Cx5J83tP.js +8 -0
- package/dist/_chunks/index-9qOMKawN.mjs +17266 -0
- package/dist/_chunks/index-BYtwkTin.js +17285 -0
- package/dist/_chunks/index-DS_1_TmO.js +853 -0
- package/dist/_chunks/index-DpQ-BmOq.mjs +851 -0
- package/dist/_chunks/ru-Bbls49WS.mjs +8 -0
- package/dist/_chunks/ru-BjlFbstB.js +8 -0
- package/dist/admin/index.js +85 -0
- package/dist/admin/index.mjs +86 -0
- package/dist/server/index.js +2469 -0
- package/dist/server/index.mjs +2470 -0
- package/package.json +76 -0
- package/server/src/bootstrap.ts +3 -0
- package/server/src/config/index.ts +4 -0
- package/server/src/content-types/index.ts +1 -0
- package/server/src/controllers/controller.ts +22 -0
- package/server/src/controllers/index.ts +5 -0
- package/server/src/destroy.ts +3 -0
- package/server/src/index.ts +23 -0
- package/server/src/middlewares/index.ts +1 -0
- package/server/src/policies/index.ts +1 -0
- package/server/src/register.ts +11 -0
- package/server/src/routes/index.ts +26 -0
- package/server/src/services/index.ts +5 -0
- package/server/src/services/service.ts +27 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import type { MetricDefinition, RuleOperator } from './types';
|
|
2
|
+
|
|
3
|
+
export const OPERATORS: { value: RuleOperator; label: string; description: string }[] = [
|
|
4
|
+
{ value: '$eq', label: '=', description: 'Equals' },
|
|
5
|
+
{ value: '$ne', label: '≠', description: 'Not equals' },
|
|
6
|
+
{ value: '$gt', label: '>', description: 'Greater than' },
|
|
7
|
+
{ value: '$lt', label: '<', description: 'Less than' },
|
|
8
|
+
{ value: '$gte', label: '≥', description: 'Greater or equal' },
|
|
9
|
+
{ value: '$lte', label: '≤', description: 'Less or equal' },
|
|
10
|
+
{ value: '$in', label: 'in', description: 'In list' },
|
|
11
|
+
{ value: '$nin', label: 'not in', description: 'Not in list' },
|
|
12
|
+
{ value: '$exists', label: 'exists', description: 'Field exists' },
|
|
13
|
+
{ value: '$regex', label: 'matches', description: 'Regex match' },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const numberOperators: RuleOperator[] = ['$eq', '$ne', '$gt', '$lt', '$gte', '$lte'];
|
|
17
|
+
const timeAgoOperators: RuleOperator[] = ['$gt', '$lt', '$gte', '$lte'];
|
|
18
|
+
const booleanOperators: RuleOperator[] = ['$eq', '$ne'];
|
|
19
|
+
const stringOperators: RuleOperator[] = ['$eq', '$ne', '$regex', '$in', '$nin'];
|
|
20
|
+
const existsOperators: RuleOperator[] = ['$exists'];
|
|
21
|
+
|
|
22
|
+
export const METRICS: MetricDefinition[] = [
|
|
23
|
+
{
|
|
24
|
+
key: 'deposit_count',
|
|
25
|
+
label: 'Deposit Count',
|
|
26
|
+
category: 'counters',
|
|
27
|
+
valueType: 'number',
|
|
28
|
+
description: 'Total number of successful deposits',
|
|
29
|
+
operators: numberOperators,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: 'case_open_count',
|
|
33
|
+
label: 'Case Open Count',
|
|
34
|
+
category: 'counters',
|
|
35
|
+
valueType: 'number',
|
|
36
|
+
description: 'Total cases opened',
|
|
37
|
+
operators: numberOperators,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'upgrade_count',
|
|
41
|
+
label: 'Upgrade Count',
|
|
42
|
+
category: 'counters',
|
|
43
|
+
valueType: 'number',
|
|
44
|
+
description: 'Total upgrades performed',
|
|
45
|
+
operators: numberOperators,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
key: 'battle_count',
|
|
49
|
+
label: 'Battle Count',
|
|
50
|
+
category: 'counters',
|
|
51
|
+
valueType: 'number',
|
|
52
|
+
description: 'Total battles created/participated',
|
|
53
|
+
operators: numberOperators,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
key: 'contract_count',
|
|
57
|
+
label: 'Contract Count',
|
|
58
|
+
category: 'counters',
|
|
59
|
+
valueType: 'number',
|
|
60
|
+
description: 'Total contracts executed',
|
|
61
|
+
operators: numberOperators,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: 'withdraw_count',
|
|
65
|
+
label: 'Withdraw Count',
|
|
66
|
+
category: 'counters',
|
|
67
|
+
valueType: 'number',
|
|
68
|
+
description: 'Total withdrawals',
|
|
69
|
+
operators: numberOperators,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: 'session_count',
|
|
73
|
+
label: 'Session Count',
|
|
74
|
+
category: 'counters',
|
|
75
|
+
valueType: 'number',
|
|
76
|
+
description: 'Total sessions',
|
|
77
|
+
operators: numberOperators,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: 'consecutive_active_days',
|
|
81
|
+
label: 'Consecutive Active Days',
|
|
82
|
+
category: 'counters',
|
|
83
|
+
valueType: 'number',
|
|
84
|
+
description: 'Days active in a row',
|
|
85
|
+
operators: numberOperators,
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
key: 'deposit_sum_total',
|
|
90
|
+
label: 'Total Deposits Sum',
|
|
91
|
+
category: 'money',
|
|
92
|
+
valueType: 'number',
|
|
93
|
+
description: 'Sum of all deposits in RUB',
|
|
94
|
+
operators: numberOperators,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: 'withdraw_sum_total',
|
|
98
|
+
label: 'Total Withdrawals Sum',
|
|
99
|
+
category: 'money',
|
|
100
|
+
valueType: 'number',
|
|
101
|
+
description: 'Sum of all withdrawals',
|
|
102
|
+
operators: numberOperators,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
key: 'win_sum_total',
|
|
106
|
+
label: 'Total Wins Sum',
|
|
107
|
+
category: 'money',
|
|
108
|
+
valueType: 'number',
|
|
109
|
+
description: 'Sum of all winnings',
|
|
110
|
+
operators: numberOperators,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: 'avg_deposit',
|
|
114
|
+
label: 'Average Deposit',
|
|
115
|
+
category: 'money',
|
|
116
|
+
valueType: 'number',
|
|
117
|
+
description: 'Average deposit amount',
|
|
118
|
+
operators: numberOperators,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
key: 'balance',
|
|
122
|
+
label: 'Current Balance',
|
|
123
|
+
category: 'money',
|
|
124
|
+
valueType: 'number',
|
|
125
|
+
description: 'Current account balance',
|
|
126
|
+
operators: numberOperators,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
key: 'net_deposit',
|
|
130
|
+
label: 'Net Deposit',
|
|
131
|
+
category: 'money',
|
|
132
|
+
valueType: 'number',
|
|
133
|
+
description: 'Deposits minus withdrawals',
|
|
134
|
+
operators: numberOperators,
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
{
|
|
138
|
+
key: 'last_deposit_at',
|
|
139
|
+
label: 'Last Deposit',
|
|
140
|
+
category: 'time',
|
|
141
|
+
valueType: 'time_ago',
|
|
142
|
+
description: 'Time since last deposit',
|
|
143
|
+
operators: timeAgoOperators,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
key: 'last_case_open_at',
|
|
147
|
+
label: 'Last Case Open',
|
|
148
|
+
category: 'time',
|
|
149
|
+
valueType: 'time_ago',
|
|
150
|
+
description: 'Time since last case opened',
|
|
151
|
+
operators: timeAgoOperators,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
key: 'last_upgrade_at',
|
|
155
|
+
label: 'Last Upgrade',
|
|
156
|
+
category: 'time',
|
|
157
|
+
valueType: 'time_ago',
|
|
158
|
+
description: 'Time since last upgrade',
|
|
159
|
+
operators: timeAgoOperators,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
key: 'last_battle_at',
|
|
163
|
+
label: 'Last Battle',
|
|
164
|
+
category: 'time',
|
|
165
|
+
valueType: 'time_ago',
|
|
166
|
+
description: 'Time since last battle',
|
|
167
|
+
operators: timeAgoOperators,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
key: 'last_contract_at',
|
|
171
|
+
label: 'Last Contract',
|
|
172
|
+
category: 'time',
|
|
173
|
+
valueType: 'time_ago',
|
|
174
|
+
description: 'Time since last contract',
|
|
175
|
+
operators: timeAgoOperators,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
key: 'last_withdraw_at',
|
|
179
|
+
label: 'Last Withdrawal',
|
|
180
|
+
category: 'time',
|
|
181
|
+
valueType: 'time_ago',
|
|
182
|
+
description: 'Time since last withdrawal',
|
|
183
|
+
operators: timeAgoOperators,
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
key: 'last_session_at',
|
|
187
|
+
label: 'Last Activity',
|
|
188
|
+
category: 'time',
|
|
189
|
+
valueType: 'time_ago',
|
|
190
|
+
description: 'Time since last session/activity',
|
|
191
|
+
operators: timeAgoOperators,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
key: 'registered_at',
|
|
195
|
+
label: 'Registration Date',
|
|
196
|
+
category: 'time',
|
|
197
|
+
valueType: 'time_ago',
|
|
198
|
+
description: 'Time since registration',
|
|
199
|
+
operators: timeAgoOperators,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
key: 'first_deposit_at',
|
|
203
|
+
label: 'First Deposit Date',
|
|
204
|
+
category: 'time',
|
|
205
|
+
valueType: 'time_ago',
|
|
206
|
+
description: 'Time since first deposit',
|
|
207
|
+
operators: [...timeAgoOperators, ...existsOperators],
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
{
|
|
211
|
+
key: 'is_vip',
|
|
212
|
+
label: 'Is VIP',
|
|
213
|
+
category: 'status',
|
|
214
|
+
valueType: 'boolean',
|
|
215
|
+
description: 'VIP status',
|
|
216
|
+
operators: booleanOperators,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
key: 'is_ftd',
|
|
220
|
+
label: 'Is FTD (First-Time Depositor)',
|
|
221
|
+
category: 'status',
|
|
222
|
+
valueType: 'boolean',
|
|
223
|
+
description: 'Has exactly 1 deposit',
|
|
224
|
+
operators: booleanOperators,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
key: 'has_telegram',
|
|
228
|
+
label: 'Has Telegram',
|
|
229
|
+
category: 'status',
|
|
230
|
+
valueType: 'boolean',
|
|
231
|
+
description: 'Telegram connected',
|
|
232
|
+
operators: booleanOperators,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
key: 'telegram_opt_out',
|
|
236
|
+
label: 'Telegram Opt-Out',
|
|
237
|
+
category: 'status',
|
|
238
|
+
valueType: 'boolean',
|
|
239
|
+
description: 'User opted out of TG messages',
|
|
240
|
+
operators: booleanOperators,
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
key: 'has_free_case',
|
|
244
|
+
label: 'Has Free Case',
|
|
245
|
+
category: 'status',
|
|
246
|
+
valueType: 'boolean',
|
|
247
|
+
description: 'Has available free case',
|
|
248
|
+
operators: booleanOperators,
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
{
|
|
252
|
+
key: 'lifecycle_stage',
|
|
253
|
+
label: 'Lifecycle Stage',
|
|
254
|
+
category: 'activity',
|
|
255
|
+
valueType: 'string',
|
|
256
|
+
description: 'New, Active, Sleep, Churn, Dead',
|
|
257
|
+
operators: stringOperators,
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
key: 'referral_source',
|
|
261
|
+
label: 'Referral Source',
|
|
262
|
+
category: 'activity',
|
|
263
|
+
valueType: 'string',
|
|
264
|
+
description: 'How user was acquired',
|
|
265
|
+
operators: stringOperators,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
key: 'country',
|
|
269
|
+
label: 'Country',
|
|
270
|
+
category: 'activity',
|
|
271
|
+
valueType: 'string',
|
|
272
|
+
description: 'User country code',
|
|
273
|
+
operators: stringOperators,
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
key: 'timezone',
|
|
277
|
+
label: 'Timezone',
|
|
278
|
+
category: 'activity',
|
|
279
|
+
valueType: 'string',
|
|
280
|
+
description: 'User timezone',
|
|
281
|
+
operators: stringOperators,
|
|
282
|
+
},
|
|
283
|
+
];
|
|
284
|
+
|
|
285
|
+
export const METRICS_BY_CATEGORY = METRICS.reduce(
|
|
286
|
+
(acc, metric) => {
|
|
287
|
+
if (!acc[metric.category]) {
|
|
288
|
+
acc[metric.category] = [];
|
|
289
|
+
}
|
|
290
|
+
acc[metric.category].push(metric);
|
|
291
|
+
return acc;
|
|
292
|
+
},
|
|
293
|
+
{} as Record<string, MetricDefinition[]>
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
export const CATEGORY_LABELS: Record<string, string> = {
|
|
297
|
+
counters: '📊 Counters',
|
|
298
|
+
money: '💰 Money',
|
|
299
|
+
time: '⏰ Time-based',
|
|
300
|
+
status: '🏷️ Status',
|
|
301
|
+
activity: '📱 Activity & Profile',
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export const LIFECYCLE_STAGES = ['new', 'active', 'sleep', 'churn', 'dead'];
|
|
305
|
+
|
|
306
|
+
export const TIME_UNITS = [
|
|
307
|
+
{ value: 'minutes_ago', label: 'minutes ago' },
|
|
308
|
+
{ value: 'hours_ago', label: 'hours ago' },
|
|
309
|
+
{ value: 'days_ago', label: 'days ago' },
|
|
310
|
+
];
|
|
311
|
+
|
|
312
|
+
export const DEFAULT_RULE: Omit<import('./types').SingleRule, 'id'> = {
|
|
313
|
+
field: 'deposit_count',
|
|
314
|
+
operator: '$eq',
|
|
315
|
+
value: 0,
|
|
316
|
+
};
|