@mamindom/contracts 1.0.130 → 1.0.133
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/events/auth/index.d.ts +1 -0
- package/dist/events/auth/index.js +1 -0
- package/dist/events/auth/user-authenticated.interface.d.ts +5 -0
- package/dist/events/auth/user-authenticated.interface.js +2 -0
- package/dist/gen/notification.d.ts +239 -0
- package/dist/gen/notification.js +50 -1
- package/dist/gen/order.d.ts +18 -0
- package/dist/gen/order.js +1 -0
- package/dist/gen/users.d.ts +15 -0
- package/dist/gen/users.js +1 -0
- package/dist/proto/notification.proto +232 -0
- package/dist/proto/order.proto +20 -0
- package/dist/proto/users.proto +16 -0
- package/events/auth/index.ts +1 -0
- package/events/auth/user-authenticated.interface.ts +5 -0
- package/gen/notification.ts +348 -0
- package/gen/order.ts +28 -0
- package/gen/users.ts +26 -0
- package/package.json +1 -1
- package/proto/notification.proto +232 -0
- package/proto/order.proto +20 -0
- package/proto/users.proto +16 -0
|
@@ -16,6 +16,42 @@ service NotificationTemplateService {
|
|
|
16
16
|
rpc RestoreVersion (RestoreVersionRequest) returns (TemplateResponse);
|
|
17
17
|
rpc RenderPreview (RenderPreviewRequest) returns (RenderPreviewResponse);
|
|
18
18
|
rpc SendTest (SendTestRequest) returns (SendTestResponse);
|
|
19
|
+
// Реальна відправка клієнту з адмінки — або по шаблону, або ad-hoc body.
|
|
20
|
+
rpc SendToCustomer (SendToCustomerRequest) returns (SendToCustomerResponse);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// SendToCustomer — викликається з gateway після того, як клієнтський контакт
|
|
24
|
+
// (email/phone) вже резолвнений і опційно згенерований персональний купон.
|
|
25
|
+
message SendToCustomerRequest {
|
|
26
|
+
// userId з auth-service — пишемо в NotificationLog.user_id для зведень.
|
|
27
|
+
string user_id = 1;
|
|
28
|
+
NotificationChannel channel = 2;
|
|
29
|
+
|
|
30
|
+
// Recipient — email або phone, заздалегідь визначені gateway з акаунта.
|
|
31
|
+
string recipient = 3;
|
|
32
|
+
|
|
33
|
+
// Шлях 1: templateId — рендеримо існуючий шаблон з variables.
|
|
34
|
+
optional string template_id = 4;
|
|
35
|
+
|
|
36
|
+
// Шлях 2: ad-hoc контент. Якщо template_id порожній — використовуємо ці поля.
|
|
37
|
+
// body_html — для EMAIL (буде обгорнутий брендингом).
|
|
38
|
+
// body_text — для SMS (plain text) або текстова версія email.
|
|
39
|
+
optional string custom_subject = 5;
|
|
40
|
+
optional string custom_body_html = 6;
|
|
41
|
+
optional string custom_body_text = 7;
|
|
42
|
+
|
|
43
|
+
// JSON з placeholders для Handlebars: { "coupon_code": "...", ... }
|
|
44
|
+
string variables_json = 8;
|
|
45
|
+
|
|
46
|
+
// Locale для пошуку версії шаблону + надсилання branding-обгортки.
|
|
47
|
+
optional NotificationLocale locale = 9;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
message SendToCustomerResponse {
|
|
51
|
+
bool ok = 1;
|
|
52
|
+
string error_message = 2;
|
|
53
|
+
// id запису в NotificationLog (для трекінгу в /notifications/logs).
|
|
54
|
+
string log_id = 3;
|
|
19
55
|
}
|
|
20
56
|
|
|
21
57
|
service NotificationLogsService {
|
|
@@ -29,6 +65,202 @@ service TelegramChatsService {
|
|
|
29
65
|
rpc TestSendTelegram (TestSendTelegramRequest) returns (TestSendTelegramResponse);
|
|
30
66
|
}
|
|
31
67
|
|
|
68
|
+
// Маркетингові кампанії: створення, запуск, статистика.
|
|
69
|
+
service CampaignsService {
|
|
70
|
+
rpc ListCampaigns (ListCampaignsRequest) returns (ListCampaignsResponse);
|
|
71
|
+
rpc GetCampaign (GetCampaignRequest) returns (CampaignResponse);
|
|
72
|
+
rpc CreateCampaign (CreateCampaignRequest) returns (CampaignResponse);
|
|
73
|
+
rpc UpdateCampaign (UpdateCampaignRequest) returns (CampaignResponse);
|
|
74
|
+
rpc DeleteCampaign (DeleteCampaignRequest) returns (DeleteCampaignResponse);
|
|
75
|
+
rpc StartCampaign (StartCampaignRequest) returns (CampaignResponse);
|
|
76
|
+
rpc CancelCampaign (CancelCampaignRequest) returns (CampaignResponse);
|
|
77
|
+
// Превью сегменту — повертає кількість + перші N клієнтів, БЕЗ створення кампанії.
|
|
78
|
+
rpc PreviewSegment (PreviewSegmentRequest) returns (PreviewSegmentResponse);
|
|
79
|
+
// Список отримувачів конкретної кампанії з їхніми статусами.
|
|
80
|
+
rpc ListRecipients (ListRecipientsRequest) returns (ListRecipientsResponse);
|
|
81
|
+
// Викликається з gateway після того, як сегмент резолвнено клієнтами —
|
|
82
|
+
// передається список {userId, recipient}, нотифікація розкладає у чергу.
|
|
83
|
+
rpc EnqueueRecipients(EnqueueRecipientsRequest) returns (EnqueueRecipientsResponse);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
message EnqueueRecipientsRequest {
|
|
87
|
+
string campaign_id = 1;
|
|
88
|
+
repeated CampaignResolvedRecipient recipients = 2;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
message CampaignResolvedRecipient {
|
|
92
|
+
string user_id = 1;
|
|
93
|
+
string recipient = 2; // email або phone
|
|
94
|
+
// true → у клієнта promotions=false. dispatcher позначить SKIPPED_OPT_OUT
|
|
95
|
+
// якщо respect_opt_out=true для кампанії.
|
|
96
|
+
bool opt_out = 3;
|
|
97
|
+
// Унікальний код, згенерований gateway через CouponsService.CreateCoupon.
|
|
98
|
+
// Підставляється у шаблон як {{coupon_code}}.
|
|
99
|
+
optional string coupon_code = 4;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
message EnqueueRecipientsResponse {
|
|
103
|
+
int32 enqueued = 1;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
message ListCampaignsRequest {
|
|
107
|
+
optional CampaignStatusEnum status = 1;
|
|
108
|
+
optional int32 page = 2;
|
|
109
|
+
optional int32 limit = 3;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
message ListCampaignsResponse {
|
|
113
|
+
repeated Campaign items = 1;
|
|
114
|
+
int32 total = 2;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
message GetCampaignRequest {
|
|
118
|
+
string id = 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
message DeleteCampaignRequest {
|
|
122
|
+
string id = 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
message DeleteCampaignResponse {
|
|
126
|
+
bool ok = 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
message StartCampaignRequest {
|
|
130
|
+
string id = 1;
|
|
131
|
+
// ISO date; якщо порожньо → запустити одразу.
|
|
132
|
+
optional string scheduled_at = 2;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
message CancelCampaignRequest {
|
|
136
|
+
string id = 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
message CreateCampaignRequest {
|
|
140
|
+
string name = 1;
|
|
141
|
+
NotificationChannel channel = 2;
|
|
142
|
+
optional string template_id = 3;
|
|
143
|
+
optional string custom_subject = 4;
|
|
144
|
+
optional string custom_body_html = 5;
|
|
145
|
+
optional string custom_body_text = 6;
|
|
146
|
+
// JSON segment spec.
|
|
147
|
+
string segment_json = 7;
|
|
148
|
+
// JSON coupon spec — null/empty для кампаній без купонів.
|
|
149
|
+
optional string coupon_spec_json = 8;
|
|
150
|
+
bool respect_opt_out = 9;
|
|
151
|
+
optional NotificationLocale locale = 10;
|
|
152
|
+
string created_by_id = 11;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
message UpdateCampaignRequest {
|
|
156
|
+
string id = 1;
|
|
157
|
+
// Можна оновлювати тільки DRAFT — гілки нижче опційні.
|
|
158
|
+
optional string name = 2;
|
|
159
|
+
optional NotificationChannel channel = 3;
|
|
160
|
+
optional string template_id = 4;
|
|
161
|
+
optional string custom_subject = 5;
|
|
162
|
+
optional string custom_body_html = 6;
|
|
163
|
+
optional string custom_body_text = 7;
|
|
164
|
+
optional string segment_json = 8;
|
|
165
|
+
optional string coupon_spec_json = 9;
|
|
166
|
+
optional bool respect_opt_out = 10;
|
|
167
|
+
optional NotificationLocale locale = 11;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
message CampaignResponse {
|
|
171
|
+
bool ok = 1;
|
|
172
|
+
string error_message = 2;
|
|
173
|
+
Campaign campaign = 3;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
message Campaign {
|
|
177
|
+
string id = 1;
|
|
178
|
+
string name = 2;
|
|
179
|
+
NotificationChannel channel = 3;
|
|
180
|
+
optional string template_id = 4;
|
|
181
|
+
optional string custom_subject = 5;
|
|
182
|
+
optional string custom_body_html = 6;
|
|
183
|
+
optional string custom_body_text = 7;
|
|
184
|
+
NotificationLocale locale = 8;
|
|
185
|
+
string segment_json = 9;
|
|
186
|
+
optional string coupon_spec_json = 10;
|
|
187
|
+
bool respect_opt_out = 11;
|
|
188
|
+
CampaignStatusEnum status = 12;
|
|
189
|
+
optional string scheduled_at = 13;
|
|
190
|
+
optional string started_at = 14;
|
|
191
|
+
optional string completed_at = 15;
|
|
192
|
+
int32 total_recipients = 16;
|
|
193
|
+
int32 sent_count = 17;
|
|
194
|
+
int32 failed_count = 18;
|
|
195
|
+
int32 skipped_opt_out_count = 19;
|
|
196
|
+
string created_by_id = 20;
|
|
197
|
+
string created_at = 21;
|
|
198
|
+
string updated_at = 22;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
enum CampaignStatusEnum {
|
|
202
|
+
CAMPAIGN_STATUS_UNSPECIFIED = 0;
|
|
203
|
+
DRAFT = 1;
|
|
204
|
+
SCHEDULED = 2;
|
|
205
|
+
RUNNING = 3;
|
|
206
|
+
COMPLETED = 4;
|
|
207
|
+
CANCELLED = 5;
|
|
208
|
+
CAMPAIGN_FAILED = 6;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
message PreviewSegmentRequest {
|
|
212
|
+
string segment_json = 1;
|
|
213
|
+
NotificationChannel channel = 2; // потрібно для перевірки наявності email/phone
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
message PreviewSegmentResponse {
|
|
217
|
+
int32 total_count = 1;
|
|
218
|
+
// Перші 10 для UI; решта — за необхідності окремим запитом.
|
|
219
|
+
repeated PreviewSegmentSample sample = 2;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
message PreviewSegmentSample {
|
|
223
|
+
string user_id = 1;
|
|
224
|
+
string first_name = 2;
|
|
225
|
+
string last_name = 3;
|
|
226
|
+
string email = 4;
|
|
227
|
+
string phone = 5;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
message ListRecipientsRequest {
|
|
231
|
+
string campaign_id = 1;
|
|
232
|
+
optional CampaignRecipientStatusEnum status = 2;
|
|
233
|
+
optional int32 page = 3;
|
|
234
|
+
optional int32 limit = 4;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
message ListRecipientsResponse {
|
|
238
|
+
repeated CampaignRecipient items = 1;
|
|
239
|
+
int32 total = 2;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
message CampaignRecipient {
|
|
243
|
+
string id = 1;
|
|
244
|
+
string campaign_id = 2;
|
|
245
|
+
string user_id = 3;
|
|
246
|
+
string recipient = 4;
|
|
247
|
+
CampaignRecipientStatusEnum status = 5;
|
|
248
|
+
optional string coupon_code = 6;
|
|
249
|
+
optional string notification_log_id = 7;
|
|
250
|
+
optional string error_message = 8;
|
|
251
|
+
optional string sent_at = 9;
|
|
252
|
+
string created_at = 10;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
enum CampaignRecipientStatusEnum {
|
|
256
|
+
CAMPAIGN_RECIPIENT_UNSPECIFIED = 0;
|
|
257
|
+
RECIPIENT_PENDING = 1;
|
|
258
|
+
RECIPIENT_SENT = 2;
|
|
259
|
+
RECIPIENT_FAILED = 3;
|
|
260
|
+
RECIPIENT_SKIPPED_OPT_OUT = 4;
|
|
261
|
+
RECIPIENT_SKIPPED_NO_CONTACT = 5;
|
|
262
|
+
}
|
|
263
|
+
|
|
32
264
|
// Брендинг email-шаблонів — singleton редагується адміном.
|
|
33
265
|
service BrandingService {
|
|
34
266
|
rpc GetBranding (BrandingEmpty) returns (BrandingProfile);
|
package/dist/proto/order.proto
CHANGED
|
@@ -25,6 +25,26 @@ service OrderService {
|
|
|
25
25
|
rpc ReorderOrder(ReorderOrderRequest) returns (ReorderResponse);
|
|
26
26
|
|
|
27
27
|
rpc ListHistory(ListHistoryRequest) returns (ListHistoryResponse);
|
|
28
|
+
|
|
29
|
+
// CRM-агрегація для експорту клієнтів — повертає count/sum/last для кожного userId.
|
|
30
|
+
rpc AggregateByCustomers(AggregateByCustomersRequest) returns (AggregateByCustomersResponse);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
message AggregateByCustomersRequest {
|
|
34
|
+
repeated string user_ids = 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
message CustomerOrderAggregate {
|
|
38
|
+
string user_id = 1;
|
|
39
|
+
int32 orders_count = 2;
|
|
40
|
+
// Decimal у вигляді рядка ('1234.56') — щоб не втратити точність на gRPC border.
|
|
41
|
+
string total_sum = 3;
|
|
42
|
+
// ISO-рядок, відсутній якщо клієнт ще не робив замовлень.
|
|
43
|
+
optional string last_order_at = 4;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
message AggregateByCustomersResponse {
|
|
47
|
+
repeated CustomerOrderAggregate items = 1;
|
|
28
48
|
}
|
|
29
49
|
|
|
30
50
|
// ─── Enums (string у proto3, для зворотної сумісності) ─────────
|
package/dist/proto/users.proto
CHANGED
|
@@ -47,6 +47,9 @@ service UsersService {
|
|
|
47
47
|
rpc RemoveCartItem(RemoveCartItemRequest) returns (GetCartResponse);
|
|
48
48
|
rpc ClearCart(ClearCartRequest) returns (ClearCartResponse);
|
|
49
49
|
rpc SyncCart(SyncCartRequest) returns (GetCartResponse);
|
|
50
|
+
|
|
51
|
+
// Admin CRM — редагування клієнта менеджером (customers.edit на gateway).
|
|
52
|
+
rpc AdminUpdateCustomer(AdminUpdateCustomerRequest) returns (AdminUpdateCustomerResponse);
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
message GetMeRequest {
|
|
@@ -87,6 +90,19 @@ message User {
|
|
|
87
90
|
int32 bonuses = 4;
|
|
88
91
|
optional string email = 5;
|
|
89
92
|
optional string phone = 6;
|
|
93
|
+
optional string internal_note = 7;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
message AdminUpdateCustomerRequest {
|
|
97
|
+
string id = 1;
|
|
98
|
+
optional string first_name = 2;
|
|
99
|
+
optional string last_name = 3;
|
|
100
|
+
// internal_note редагується тут окремо, бо це CRM-поле — не видиме клієнту.
|
|
101
|
+
optional string internal_note = 4;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
message AdminUpdateCustomerResponse {
|
|
105
|
+
User user = 1;
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
message NotificationSettings {
|
package/events/auth/index.ts
CHANGED
package/gen/notification.ts
CHANGED
|
@@ -10,6 +10,27 @@ import { Observable } from "rxjs";
|
|
|
10
10
|
|
|
11
11
|
export const protobufPackage = "notification.v1";
|
|
12
12
|
|
|
13
|
+
export enum CampaignStatusEnum {
|
|
14
|
+
CAMPAIGN_STATUS_UNSPECIFIED = 0,
|
|
15
|
+
DRAFT = 1,
|
|
16
|
+
SCHEDULED = 2,
|
|
17
|
+
RUNNING = 3,
|
|
18
|
+
COMPLETED = 4,
|
|
19
|
+
CANCELLED = 5,
|
|
20
|
+
CAMPAIGN_FAILED = 6,
|
|
21
|
+
UNRECOGNIZED = -1,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export enum CampaignRecipientStatusEnum {
|
|
25
|
+
CAMPAIGN_RECIPIENT_UNSPECIFIED = 0,
|
|
26
|
+
RECIPIENT_PENDING = 1,
|
|
27
|
+
RECIPIENT_SENT = 2,
|
|
28
|
+
RECIPIENT_FAILED = 3,
|
|
29
|
+
RECIPIENT_SKIPPED_OPT_OUT = 4,
|
|
30
|
+
RECIPIENT_SKIPPED_NO_CONTACT = 5,
|
|
31
|
+
UNRECOGNIZED = -1,
|
|
32
|
+
}
|
|
33
|
+
|
|
13
34
|
export enum NotificationChannel {
|
|
14
35
|
NOTIFICATION_CHANNEL_UNSPECIFIED = 0,
|
|
15
36
|
EMAIL = 1,
|
|
@@ -59,6 +80,210 @@ export enum TelegramTopic {
|
|
|
59
80
|
UNRECOGNIZED = -1,
|
|
60
81
|
}
|
|
61
82
|
|
|
83
|
+
/**
|
|
84
|
+
* SendToCustomer — викликається з gateway після того, як клієнтський контакт
|
|
85
|
+
* (email/phone) вже резолвнений і опційно згенерований персональний купон.
|
|
86
|
+
*/
|
|
87
|
+
export interface SendToCustomerRequest {
|
|
88
|
+
/** userId з auth-service — пишемо в NotificationLog.user_id для зведень. */
|
|
89
|
+
userId: string;
|
|
90
|
+
channel: NotificationChannel;
|
|
91
|
+
/** Recipient — email або phone, заздалегідь визначені gateway з акаунта. */
|
|
92
|
+
recipient: string;
|
|
93
|
+
/** Шлях 1: templateId — рендеримо існуючий шаблон з variables. */
|
|
94
|
+
templateId?:
|
|
95
|
+
| string
|
|
96
|
+
| undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Шлях 2: ad-hoc контент. Якщо template_id порожній — використовуємо ці поля.
|
|
99
|
+
* body_html — для EMAIL (буде обгорнутий брендингом).
|
|
100
|
+
* body_text — для SMS (plain text) або текстова версія email.
|
|
101
|
+
*/
|
|
102
|
+
customSubject?: string | undefined;
|
|
103
|
+
customBodyHtml?: string | undefined;
|
|
104
|
+
customBodyText?:
|
|
105
|
+
| string
|
|
106
|
+
| undefined;
|
|
107
|
+
/** JSON з placeholders для Handlebars: { "coupon_code": "...", ... } */
|
|
108
|
+
variablesJson: string;
|
|
109
|
+
/** Locale для пошуку версії шаблону + надсилання branding-обгортки. */
|
|
110
|
+
locale?: NotificationLocale | undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface SendToCustomerResponse {
|
|
114
|
+
ok: boolean;
|
|
115
|
+
errorMessage: string;
|
|
116
|
+
/** id запису в NotificationLog (для трекінгу в /notifications/logs). */
|
|
117
|
+
logId: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface EnqueueRecipientsRequest {
|
|
121
|
+
campaignId: string;
|
|
122
|
+
recipients: CampaignResolvedRecipient[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface CampaignResolvedRecipient {
|
|
126
|
+
userId: string;
|
|
127
|
+
/** email або phone */
|
|
128
|
+
recipient: string;
|
|
129
|
+
/**
|
|
130
|
+
* true → у клієнта promotions=false. dispatcher позначить SKIPPED_OPT_OUT
|
|
131
|
+
* якщо respect_opt_out=true для кампанії.
|
|
132
|
+
*/
|
|
133
|
+
optOut: boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Унікальний код, згенерований gateway через CouponsService.CreateCoupon.
|
|
136
|
+
* Підставляється у шаблон як {{coupon_code}}.
|
|
137
|
+
*/
|
|
138
|
+
couponCode?: string | undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface EnqueueRecipientsResponse {
|
|
142
|
+
enqueued: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface ListCampaignsRequest {
|
|
146
|
+
status?: CampaignStatusEnum | undefined;
|
|
147
|
+
page?: number | undefined;
|
|
148
|
+
limit?: number | undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ListCampaignsResponse {
|
|
152
|
+
items: Campaign[];
|
|
153
|
+
total: number;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface GetCampaignRequest {
|
|
157
|
+
id: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface DeleteCampaignRequest {
|
|
161
|
+
id: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface DeleteCampaignResponse {
|
|
165
|
+
ok: boolean;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface StartCampaignRequest {
|
|
169
|
+
id: string;
|
|
170
|
+
/** ISO date; якщо порожньо → запустити одразу. */
|
|
171
|
+
scheduledAt?: string | undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface CancelCampaignRequest {
|
|
175
|
+
id: string;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface CreateCampaignRequest {
|
|
179
|
+
name: string;
|
|
180
|
+
channel: NotificationChannel;
|
|
181
|
+
templateId?: string | undefined;
|
|
182
|
+
customSubject?: string | undefined;
|
|
183
|
+
customBodyHtml?: string | undefined;
|
|
184
|
+
customBodyText?:
|
|
185
|
+
| string
|
|
186
|
+
| undefined;
|
|
187
|
+
/** JSON segment spec. */
|
|
188
|
+
segmentJson: string;
|
|
189
|
+
/** JSON coupon spec — null/empty для кампаній без купонів. */
|
|
190
|
+
couponSpecJson?: string | undefined;
|
|
191
|
+
respectOptOut: boolean;
|
|
192
|
+
locale?: NotificationLocale | undefined;
|
|
193
|
+
createdById: string;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface UpdateCampaignRequest {
|
|
197
|
+
id: string;
|
|
198
|
+
/** Можна оновлювати тільки DRAFT — гілки нижче опційні. */
|
|
199
|
+
name?: string | undefined;
|
|
200
|
+
channel?: NotificationChannel | undefined;
|
|
201
|
+
templateId?: string | undefined;
|
|
202
|
+
customSubject?: string | undefined;
|
|
203
|
+
customBodyHtml?: string | undefined;
|
|
204
|
+
customBodyText?: string | undefined;
|
|
205
|
+
segmentJson?: string | undefined;
|
|
206
|
+
couponSpecJson?: string | undefined;
|
|
207
|
+
respectOptOut?: boolean | undefined;
|
|
208
|
+
locale?: NotificationLocale | undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface CampaignResponse {
|
|
212
|
+
ok: boolean;
|
|
213
|
+
errorMessage: string;
|
|
214
|
+
campaign: Campaign | undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface Campaign {
|
|
218
|
+
id: string;
|
|
219
|
+
name: string;
|
|
220
|
+
channel: NotificationChannel;
|
|
221
|
+
templateId?: string | undefined;
|
|
222
|
+
customSubject?: string | undefined;
|
|
223
|
+
customBodyHtml?: string | undefined;
|
|
224
|
+
customBodyText?: string | undefined;
|
|
225
|
+
locale: NotificationLocale;
|
|
226
|
+
segmentJson: string;
|
|
227
|
+
couponSpecJson?: string | undefined;
|
|
228
|
+
respectOptOut: boolean;
|
|
229
|
+
status: CampaignStatusEnum;
|
|
230
|
+
scheduledAt?: string | undefined;
|
|
231
|
+
startedAt?: string | undefined;
|
|
232
|
+
completedAt?: string | undefined;
|
|
233
|
+
totalRecipients: number;
|
|
234
|
+
sentCount: number;
|
|
235
|
+
failedCount: number;
|
|
236
|
+
skippedOptOutCount: number;
|
|
237
|
+
createdById: string;
|
|
238
|
+
createdAt: string;
|
|
239
|
+
updatedAt: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface PreviewSegmentRequest {
|
|
243
|
+
segmentJson: string;
|
|
244
|
+
/** потрібно для перевірки наявності email/phone */
|
|
245
|
+
channel: NotificationChannel;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface PreviewSegmentResponse {
|
|
249
|
+
totalCount: number;
|
|
250
|
+
/** Перші 10 для UI; решта — за необхідності окремим запитом. */
|
|
251
|
+
sample: PreviewSegmentSample[];
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface PreviewSegmentSample {
|
|
255
|
+
userId: string;
|
|
256
|
+
firstName: string;
|
|
257
|
+
lastName: string;
|
|
258
|
+
email: string;
|
|
259
|
+
phone: string;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface ListRecipientsRequest {
|
|
263
|
+
campaignId: string;
|
|
264
|
+
status?: CampaignRecipientStatusEnum | undefined;
|
|
265
|
+
page?: number | undefined;
|
|
266
|
+
limit?: number | undefined;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface ListRecipientsResponse {
|
|
270
|
+
items: CampaignRecipient[];
|
|
271
|
+
total: number;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface CampaignRecipient {
|
|
275
|
+
id: string;
|
|
276
|
+
campaignId: string;
|
|
277
|
+
userId: string;
|
|
278
|
+
recipient: string;
|
|
279
|
+
status: CampaignRecipientStatusEnum;
|
|
280
|
+
couponCode?: string | undefined;
|
|
281
|
+
notificationLogId?: string | undefined;
|
|
282
|
+
errorMessage?: string | undefined;
|
|
283
|
+
sentAt?: string | undefined;
|
|
284
|
+
createdAt: string;
|
|
285
|
+
}
|
|
286
|
+
|
|
62
287
|
export interface BrandingEmpty {
|
|
63
288
|
}
|
|
64
289
|
|
|
@@ -340,6 +565,10 @@ export interface NotificationTemplateServiceClient {
|
|
|
340
565
|
renderPreview(request: RenderPreviewRequest): Observable<RenderPreviewResponse>;
|
|
341
566
|
|
|
342
567
|
sendTest(request: SendTestRequest): Observable<SendTestResponse>;
|
|
568
|
+
|
|
569
|
+
/** Реальна відправка клієнту з адмінки — або по шаблону, або ad-hoc body. */
|
|
570
|
+
|
|
571
|
+
sendToCustomer(request: SendToCustomerRequest): Observable<SendToCustomerResponse>;
|
|
343
572
|
}
|
|
344
573
|
|
|
345
574
|
export interface NotificationTemplateServiceController {
|
|
@@ -374,6 +603,12 @@ export interface NotificationTemplateServiceController {
|
|
|
374
603
|
): Promise<RenderPreviewResponse> | Observable<RenderPreviewResponse> | RenderPreviewResponse;
|
|
375
604
|
|
|
376
605
|
sendTest(request: SendTestRequest): Promise<SendTestResponse> | Observable<SendTestResponse> | SendTestResponse;
|
|
606
|
+
|
|
607
|
+
/** Реальна відправка клієнту з адмінки — або по шаблону, або ad-hoc body. */
|
|
608
|
+
|
|
609
|
+
sendToCustomer(
|
|
610
|
+
request: SendToCustomerRequest,
|
|
611
|
+
): Promise<SendToCustomerResponse> | Observable<SendToCustomerResponse> | SendToCustomerResponse;
|
|
377
612
|
}
|
|
378
613
|
|
|
379
614
|
export function NotificationTemplateServiceControllerMethods() {
|
|
@@ -388,6 +623,7 @@ export function NotificationTemplateServiceControllerMethods() {
|
|
|
388
623
|
"restoreVersion",
|
|
389
624
|
"renderPreview",
|
|
390
625
|
"sendTest",
|
|
626
|
+
"sendToCustomer",
|
|
391
627
|
];
|
|
392
628
|
for (const method of grpcMethods) {
|
|
393
629
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
@@ -471,6 +707,118 @@ export function TelegramChatsServiceControllerMethods() {
|
|
|
471
707
|
|
|
472
708
|
export const TELEGRAM_CHATS_SERVICE_NAME = "TelegramChatsService";
|
|
473
709
|
|
|
710
|
+
/** Маркетингові кампанії: створення, запуск, статистика. */
|
|
711
|
+
|
|
712
|
+
export interface CampaignsServiceClient {
|
|
713
|
+
listCampaigns(request: ListCampaignsRequest): Observable<ListCampaignsResponse>;
|
|
714
|
+
|
|
715
|
+
getCampaign(request: GetCampaignRequest): Observable<CampaignResponse>;
|
|
716
|
+
|
|
717
|
+
createCampaign(request: CreateCampaignRequest): Observable<CampaignResponse>;
|
|
718
|
+
|
|
719
|
+
updateCampaign(request: UpdateCampaignRequest): Observable<CampaignResponse>;
|
|
720
|
+
|
|
721
|
+
deleteCampaign(request: DeleteCampaignRequest): Observable<DeleteCampaignResponse>;
|
|
722
|
+
|
|
723
|
+
startCampaign(request: StartCampaignRequest): Observable<CampaignResponse>;
|
|
724
|
+
|
|
725
|
+
cancelCampaign(request: CancelCampaignRequest): Observable<CampaignResponse>;
|
|
726
|
+
|
|
727
|
+
/** Превью сегменту — повертає кількість + перші N клієнтів, БЕЗ створення кампанії. */
|
|
728
|
+
|
|
729
|
+
previewSegment(request: PreviewSegmentRequest): Observable<PreviewSegmentResponse>;
|
|
730
|
+
|
|
731
|
+
/** Список отримувачів конкретної кампанії з їхніми статусами. */
|
|
732
|
+
|
|
733
|
+
listRecipients(request: ListRecipientsRequest): Observable<ListRecipientsResponse>;
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Викликається з gateway після того, як сегмент резолвнено клієнтами —
|
|
737
|
+
* передається список {userId, recipient}, нотифікація розкладає у чергу.
|
|
738
|
+
*/
|
|
739
|
+
|
|
740
|
+
enqueueRecipients(request: EnqueueRecipientsRequest): Observable<EnqueueRecipientsResponse>;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/** Маркетингові кампанії: створення, запуск, статистика. */
|
|
744
|
+
|
|
745
|
+
export interface CampaignsServiceController {
|
|
746
|
+
listCampaigns(
|
|
747
|
+
request: ListCampaignsRequest,
|
|
748
|
+
): Promise<ListCampaignsResponse> | Observable<ListCampaignsResponse> | ListCampaignsResponse;
|
|
749
|
+
|
|
750
|
+
getCampaign(request: GetCampaignRequest): Promise<CampaignResponse> | Observable<CampaignResponse> | CampaignResponse;
|
|
751
|
+
|
|
752
|
+
createCampaign(
|
|
753
|
+
request: CreateCampaignRequest,
|
|
754
|
+
): Promise<CampaignResponse> | Observable<CampaignResponse> | CampaignResponse;
|
|
755
|
+
|
|
756
|
+
updateCampaign(
|
|
757
|
+
request: UpdateCampaignRequest,
|
|
758
|
+
): Promise<CampaignResponse> | Observable<CampaignResponse> | CampaignResponse;
|
|
759
|
+
|
|
760
|
+
deleteCampaign(
|
|
761
|
+
request: DeleteCampaignRequest,
|
|
762
|
+
): Promise<DeleteCampaignResponse> | Observable<DeleteCampaignResponse> | DeleteCampaignResponse;
|
|
763
|
+
|
|
764
|
+
startCampaign(
|
|
765
|
+
request: StartCampaignRequest,
|
|
766
|
+
): Promise<CampaignResponse> | Observable<CampaignResponse> | CampaignResponse;
|
|
767
|
+
|
|
768
|
+
cancelCampaign(
|
|
769
|
+
request: CancelCampaignRequest,
|
|
770
|
+
): Promise<CampaignResponse> | Observable<CampaignResponse> | CampaignResponse;
|
|
771
|
+
|
|
772
|
+
/** Превью сегменту — повертає кількість + перші N клієнтів, БЕЗ створення кампанії. */
|
|
773
|
+
|
|
774
|
+
previewSegment(
|
|
775
|
+
request: PreviewSegmentRequest,
|
|
776
|
+
): Promise<PreviewSegmentResponse> | Observable<PreviewSegmentResponse> | PreviewSegmentResponse;
|
|
777
|
+
|
|
778
|
+
/** Список отримувачів конкретної кампанії з їхніми статусами. */
|
|
779
|
+
|
|
780
|
+
listRecipients(
|
|
781
|
+
request: ListRecipientsRequest,
|
|
782
|
+
): Promise<ListRecipientsResponse> | Observable<ListRecipientsResponse> | ListRecipientsResponse;
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Викликається з gateway після того, як сегмент резолвнено клієнтами —
|
|
786
|
+
* передається список {userId, recipient}, нотифікація розкладає у чергу.
|
|
787
|
+
*/
|
|
788
|
+
|
|
789
|
+
enqueueRecipients(
|
|
790
|
+
request: EnqueueRecipientsRequest,
|
|
791
|
+
): Promise<EnqueueRecipientsResponse> | Observable<EnqueueRecipientsResponse> | EnqueueRecipientsResponse;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
export function CampaignsServiceControllerMethods() {
|
|
795
|
+
return function (constructor: Function) {
|
|
796
|
+
const grpcMethods: string[] = [
|
|
797
|
+
"listCampaigns",
|
|
798
|
+
"getCampaign",
|
|
799
|
+
"createCampaign",
|
|
800
|
+
"updateCampaign",
|
|
801
|
+
"deleteCampaign",
|
|
802
|
+
"startCampaign",
|
|
803
|
+
"cancelCampaign",
|
|
804
|
+
"previewSegment",
|
|
805
|
+
"listRecipients",
|
|
806
|
+
"enqueueRecipients",
|
|
807
|
+
];
|
|
808
|
+
for (const method of grpcMethods) {
|
|
809
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
810
|
+
GrpcMethod("CampaignsService", method)(constructor.prototype[method], method, descriptor);
|
|
811
|
+
}
|
|
812
|
+
const grpcStreamMethods: string[] = [];
|
|
813
|
+
for (const method of grpcStreamMethods) {
|
|
814
|
+
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
815
|
+
GrpcStreamMethod("CampaignsService", method)(constructor.prototype[method], method, descriptor);
|
|
816
|
+
}
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
export const CAMPAIGNS_SERVICE_NAME = "CampaignsService";
|
|
821
|
+
|
|
474
822
|
/** Брендинг email-шаблонів — singleton редагується адміном. */
|
|
475
823
|
|
|
476
824
|
export interface BrandingServiceClient {
|