@mamindom/contracts 1.0.129 → 1.0.131
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/gen/notification.d.ts +247 -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 +238 -0
- package/dist/proto/order.proto +20 -0
- package/dist/proto/users.proto +16 -0
- package/events/orders/order-cancelled.interface.ts +0 -1
- package/events/orders/order-status-changed.interface.ts +0 -3
- package/events/stock/stock-confirm-requested.interface.ts +0 -2
- package/events/stock/stock-release-requested.interface.ts +0 -2
- package/events/stock/stock-reserve-failed.interface.ts +0 -2
- package/events/stock/stock-reserve-requested.interface.ts +0 -6
- package/events/stock/stock-reserved.interface.ts +0 -2
- package/gen/notification.ts +359 -1
- package/gen/order.ts +28 -0
- package/gen/users.ts +26 -0
- package/package.json +1 -1
- package/proto/notification.proto +238 -0
- package/proto/order.proto +20 -0
- package/proto/users.proto +16 -0
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
|
|
|
@@ -82,6 +307,8 @@ export interface BrandingProfile {
|
|
|
82
307
|
resolvedBrandName: string;
|
|
83
308
|
resolvedBrandUrl: string;
|
|
84
309
|
resolvedSupportEmail: string;
|
|
310
|
+
/** Кастомний HTML-хедер (замість дефолтного логотип-блоку). Порожньо → default. */
|
|
311
|
+
headerHtml: string;
|
|
85
312
|
}
|
|
86
313
|
|
|
87
314
|
export interface UpdateBrandingRequest {
|
|
@@ -92,6 +319,7 @@ export interface UpdateBrandingRequest {
|
|
|
92
319
|
supportEmail?: string | undefined;
|
|
93
320
|
footerHtml?: string | undefined;
|
|
94
321
|
actorId: string;
|
|
322
|
+
headerHtml?: string | undefined;
|
|
95
323
|
}
|
|
96
324
|
|
|
97
325
|
export interface NotificationTemplate {
|
|
@@ -203,7 +431,14 @@ export interface RenderPreviewRequest {
|
|
|
203
431
|
bodyHtml: string;
|
|
204
432
|
/** JSON-stringified variables { "order.number": "MD-2026-0001", ... } */
|
|
205
433
|
variablesJson: string;
|
|
206
|
-
subject?:
|
|
434
|
+
subject?:
|
|
435
|
+
| string
|
|
436
|
+
| undefined;
|
|
437
|
+
/**
|
|
438
|
+
* JSON-stringified branding override (header/footer/logo/brand…) для live-
|
|
439
|
+
* превʼю незбережених змін на сторінці брендингу. Порожньо → беремо з БД.
|
|
440
|
+
*/
|
|
441
|
+
brandingJson?: string | undefined;
|
|
207
442
|
}
|
|
208
443
|
|
|
209
444
|
export interface RenderPreviewResponse {
|
|
@@ -330,6 +565,10 @@ export interface NotificationTemplateServiceClient {
|
|
|
330
565
|
renderPreview(request: RenderPreviewRequest): Observable<RenderPreviewResponse>;
|
|
331
566
|
|
|
332
567
|
sendTest(request: SendTestRequest): Observable<SendTestResponse>;
|
|
568
|
+
|
|
569
|
+
/** Реальна відправка клієнту з адмінки — або по шаблону, або ad-hoc body. */
|
|
570
|
+
|
|
571
|
+
sendToCustomer(request: SendToCustomerRequest): Observable<SendToCustomerResponse>;
|
|
333
572
|
}
|
|
334
573
|
|
|
335
574
|
export interface NotificationTemplateServiceController {
|
|
@@ -364,6 +603,12 @@ export interface NotificationTemplateServiceController {
|
|
|
364
603
|
): Promise<RenderPreviewResponse> | Observable<RenderPreviewResponse> | RenderPreviewResponse;
|
|
365
604
|
|
|
366
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;
|
|
367
612
|
}
|
|
368
613
|
|
|
369
614
|
export function NotificationTemplateServiceControllerMethods() {
|
|
@@ -378,6 +623,7 @@ export function NotificationTemplateServiceControllerMethods() {
|
|
|
378
623
|
"restoreVersion",
|
|
379
624
|
"renderPreview",
|
|
380
625
|
"sendTest",
|
|
626
|
+
"sendToCustomer",
|
|
381
627
|
];
|
|
382
628
|
for (const method of grpcMethods) {
|
|
383
629
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
@@ -461,6 +707,118 @@ export function TelegramChatsServiceControllerMethods() {
|
|
|
461
707
|
|
|
462
708
|
export const TELEGRAM_CHATS_SERVICE_NAME = "TelegramChatsService";
|
|
463
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
|
+
|
|
464
822
|
/** Брендинг email-шаблонів — singleton редагується адміном. */
|
|
465
823
|
|
|
466
824
|
export interface BrandingServiceClient {
|
package/gen/order.ts
CHANGED
|
@@ -10,6 +10,23 @@ import { Observable } from "rxjs";
|
|
|
10
10
|
|
|
11
11
|
export const protobufPackage = "order.v1";
|
|
12
12
|
|
|
13
|
+
export interface AggregateByCustomersRequest {
|
|
14
|
+
userIds: string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface CustomerOrderAggregate {
|
|
18
|
+
userId: string;
|
|
19
|
+
ordersCount: number;
|
|
20
|
+
/** Decimal у вигляді рядка ('1234.56') — щоб не втратити точність на gRPC border. */
|
|
21
|
+
totalSum: string;
|
|
22
|
+
/** ISO-рядок, відсутній якщо клієнт ще не робив замовлень. */
|
|
23
|
+
lastOrderAt?: string | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface AggregateByCustomersResponse {
|
|
27
|
+
items: CustomerOrderAggregate[];
|
|
28
|
+
}
|
|
29
|
+
|
|
13
30
|
export interface OrderItem {
|
|
14
31
|
id: string;
|
|
15
32
|
productId: string;
|
|
@@ -325,6 +342,10 @@ export interface OrderServiceClient {
|
|
|
325
342
|
reorderOrder(request: ReorderOrderRequest): Observable<ReorderResponse>;
|
|
326
343
|
|
|
327
344
|
listHistory(request: ListHistoryRequest): Observable<ListHistoryResponse>;
|
|
345
|
+
|
|
346
|
+
/** CRM-агрегація для експорту клієнтів — повертає count/sum/last для кожного userId. */
|
|
347
|
+
|
|
348
|
+
aggregateByCustomers(request: AggregateByCustomersRequest): Observable<AggregateByCustomersResponse>;
|
|
328
349
|
}
|
|
329
350
|
|
|
330
351
|
export interface OrderServiceController {
|
|
@@ -371,6 +392,12 @@ export interface OrderServiceController {
|
|
|
371
392
|
listHistory(
|
|
372
393
|
request: ListHistoryRequest,
|
|
373
394
|
): Promise<ListHistoryResponse> | Observable<ListHistoryResponse> | ListHistoryResponse;
|
|
395
|
+
|
|
396
|
+
/** CRM-агрегація для експорту клієнтів — повертає count/sum/last для кожного userId. */
|
|
397
|
+
|
|
398
|
+
aggregateByCustomers(
|
|
399
|
+
request: AggregateByCustomersRequest,
|
|
400
|
+
): Promise<AggregateByCustomersResponse> | Observable<AggregateByCustomersResponse> | AggregateByCustomersResponse;
|
|
374
401
|
}
|
|
375
402
|
|
|
376
403
|
export function OrderServiceControllerMethods() {
|
|
@@ -392,6 +419,7 @@ export function OrderServiceControllerMethods() {
|
|
|
392
419
|
"setTrackingNumber",
|
|
393
420
|
"reorderOrder",
|
|
394
421
|
"listHistory",
|
|
422
|
+
"aggregateByCustomers",
|
|
395
423
|
];
|
|
396
424
|
for (const method of grpcMethods) {
|
|
397
425
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
package/gen/users.ts
CHANGED
|
@@ -62,6 +62,21 @@ export interface User {
|
|
|
62
62
|
bonuses: number;
|
|
63
63
|
email?: string | undefined;
|
|
64
64
|
phone?: string | undefined;
|
|
65
|
+
internalNote?: string | undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface AdminUpdateCustomerRequest {
|
|
69
|
+
id: string;
|
|
70
|
+
firstName?: string | undefined;
|
|
71
|
+
lastName?:
|
|
72
|
+
| string
|
|
73
|
+
| undefined;
|
|
74
|
+
/** internal_note редагується тут окремо, бо це CRM-поле — не видиме клієнту. */
|
|
75
|
+
internalNote?: string | undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface AdminUpdateCustomerResponse {
|
|
79
|
+
user: User | undefined;
|
|
65
80
|
}
|
|
66
81
|
|
|
67
82
|
export interface NotificationSettings {
|
|
@@ -378,6 +393,10 @@ export interface UsersServiceClient {
|
|
|
378
393
|
clearCart(request: ClearCartRequest): Observable<ClearCartResponse>;
|
|
379
394
|
|
|
380
395
|
syncCart(request: SyncCartRequest): Observable<GetCartResponse>;
|
|
396
|
+
|
|
397
|
+
/** Admin CRM — редагування клієнта менеджером (customers.edit на gateway). */
|
|
398
|
+
|
|
399
|
+
adminUpdateCustomer(request: AdminUpdateCustomerRequest): Observable<AdminUpdateCustomerResponse>;
|
|
381
400
|
}
|
|
382
401
|
|
|
383
402
|
export interface UsersServiceController {
|
|
@@ -481,6 +500,12 @@ export interface UsersServiceController {
|
|
|
481
500
|
clearCart(request: ClearCartRequest): Promise<ClearCartResponse> | Observable<ClearCartResponse> | ClearCartResponse;
|
|
482
501
|
|
|
483
502
|
syncCart(request: SyncCartRequest): Promise<GetCartResponse> | Observable<GetCartResponse> | GetCartResponse;
|
|
503
|
+
|
|
504
|
+
/** Admin CRM — редагування клієнта менеджером (customers.edit на gateway). */
|
|
505
|
+
|
|
506
|
+
adminUpdateCustomer(
|
|
507
|
+
request: AdminUpdateCustomerRequest,
|
|
508
|
+
): Promise<AdminUpdateCustomerResponse> | Observable<AdminUpdateCustomerResponse> | AdminUpdateCustomerResponse;
|
|
484
509
|
}
|
|
485
510
|
|
|
486
511
|
export function UsersServiceControllerMethods() {
|
|
@@ -513,6 +538,7 @@ export function UsersServiceControllerMethods() {
|
|
|
513
538
|
"removeCartItem",
|
|
514
539
|
"clearCart",
|
|
515
540
|
"syncCart",
|
|
541
|
+
"adminUpdateCustomer",
|
|
516
542
|
];
|
|
517
543
|
for (const method of grpcMethods) {
|
|
518
544
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|