@aepstore-dev/contracts 1.66.0 → 1.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gen/users.ts CHANGED
@@ -1,1026 +1,1026 @@
1
- // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
- // versions:
3
- // protoc-gen-ts_proto v2.10.1
4
- // protoc v7.35.0
5
- // source: users.proto
6
-
7
- /* eslint-disable */
8
- import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
9
- import { Observable } from "rxjs";
10
-
11
- export const protobufPackage = "users.v1";
12
-
13
- export enum UserFieldsType {
14
- USER_FIELDS_TYPE_UNSPECIFIED = 0,
15
- USER_FIELDS_TYPE_VIDEOS = 1,
16
- USER_FIELDS_TYPE_PRODUCTS = 2,
17
- USER_FIELDS_TYPE_SUBSCRIPTIONS = 3,
18
- USER_FIELDS_TYPE_SUBSCRIBERS = 4,
19
- UNRECOGNIZED = -1,
20
- }
21
-
22
- /** Periods mirror PremiumPeriod enum in schema.prisma. */
23
- export enum PremiumPeriod {
24
- PREMIUM_PERIOD_UNSPECIFIED = 0,
25
- PREMIUM_PERIOD_MONTH_1 = 1,
26
- PREMIUM_PERIOD_MONTH_3 = 2,
27
- PREMIUM_PERIOD_MONTH_6 = 3,
28
- PREMIUM_PERIOD_MONTH_12 = 4,
29
- UNRECOGNIZED = -1,
30
- }
31
-
32
- export interface Ok {
33
- ok: boolean;
34
- }
35
-
36
- export interface User {
37
- id: string;
38
- email: string;
39
- username: string;
40
- avatarUrl: string;
41
- roles: string[];
42
- /** ISO 8601 */
43
- createdAt: string;
44
- updatedAt: string;
45
- isBanned: boolean;
46
- /** ISO 8601, empty = permanent/none */
47
- bannedUntil: string;
48
- banReason: string;
49
- fullName: string;
50
- avatarBorderImageUrl: string;
51
- }
52
-
53
- export interface BanUserRequest {
54
- adminId: string;
55
- userId: string;
56
- reason: string;
57
- /** ISO 8601; empty = permanent ban */
58
- until: string;
59
- }
60
-
61
- export interface UnbanUserRequest {
62
- adminId: string;
63
- userId: string;
64
- }
65
-
66
- export interface Country {
67
- id: string;
68
- code: string;
69
- name: string;
70
- }
71
-
72
- export interface SocialMedia {
73
- id: string;
74
- platform: string;
75
- /** full link (built from username on read; empty for discord) */
76
- url: string;
77
- /** handle for handle-based platforms; empty for website */
78
- username: string;
79
- }
80
-
81
- export interface CreateSocialMedia {
82
- platform: string;
83
- /** only for platform="website" */
84
- url: string;
85
- /** handle for all other platforms */
86
- username: string;
87
- }
88
-
89
- export interface ProductUser {
90
- id: string;
91
- username: string;
92
- avatarUrl: string;
93
- }
94
-
95
- export interface Category {
96
- id: string;
97
- name: string;
98
- }
99
-
100
- export interface Product {
101
- id: string;
102
- name: string;
103
- description: string;
104
- /** Decimal as string (D7) */
105
- price: string;
106
- createdAt: string;
107
- updatedAt: string;
108
- /** profile-card preview fields */
109
- preview: string;
110
- /** Decimal as string */
111
- finalPrice: string;
112
- /** number as string */
113
- averageRating: string;
114
- status: string;
115
- /**
116
- * Author of the product (same person as the profile owner, but echoed per
117
- * product so cards can render the author independently).
118
- */
119
- user: ProductUser | undefined;
120
- categories: Category[];
121
- }
122
-
123
- export interface Video {
124
- id: string;
125
- title: string;
126
- description: string;
127
- url: string;
128
- createdAt: string;
129
- updatedAt: string;
130
- }
131
-
132
- export interface ActiveDevice {
133
- id: string;
134
- userAgent: string;
135
- ip: string;
136
- createdAt: string;
137
- lastUsedAt: string;
138
- }
139
-
140
- export interface ProfileStats {
141
- subscribersCount: number;
142
- subscriptionsCount: number;
143
- productsCount: number;
144
- videosCount: number;
145
- }
146
-
147
- /** Compact public user card for subscriber/subscription lists — no email/ban data. */
148
- export interface ProfileUser {
149
- id: string;
150
- username: string;
151
- avatarUrl: string;
152
- fullName: string;
153
- avatarBorderImageUrl: string;
154
- }
155
-
156
- export interface GetPublicProfileRequest {
157
- username: string;
158
- /** optional — present when caller is authenticated */
159
- viewerUserId: string;
160
- }
161
-
162
- export interface PublicProfileResponse {
163
- id: string;
164
- username: string;
165
- fullName: string;
166
- /** Decimal as string */
167
- rating: string;
168
- aboutMe: string;
169
- socialMedia: SocialMedia[];
170
- stats: ProfileStats | undefined;
171
- videos: Video[];
172
- products: Product[];
173
- country: Country | undefined;
174
- avatarUrl: string;
175
- bannerUrl: string;
176
- role: string;
177
- createdAt: string;
178
- hideSubscriptions: boolean;
179
- /** Either populated lists or empty depending on hide_subscriptions */
180
- subscriptions: ProfileUser[];
181
- subscribers: ProfileUser[];
182
- isOwner: boolean;
183
- /** viewer is subscribed to this profile (false when anonymous / self) */
184
- isSubscribed: boolean;
185
- /**
186
- * Premium fields — populated only when the profile owner has an active
187
- * PremiumSubscription. Non-premium viewers and non-premium profiles see
188
- * empty strings / false.
189
- */
190
- isPremium: boolean;
191
- profileColor: string;
192
- avatarBorder: AvatarBorder | undefined;
193
- animatedAvatarUrl: string;
194
- animatedBannerUrl: string;
195
- /** ISO 8601, empty when not premium */
196
- premiumExpiresAt: string;
197
- }
198
-
199
- export interface UpdateProfileRequest {
200
- userId: string;
201
- /**
202
- * Every editable field is `optional` so the wire format preserves the
203
- * "not set" state. A partial patch from the client (e.g. only avatarUrl)
204
- * no longer accidentally wipes the other columns to proto3 defaults.
205
- */
206
- fullName?: string | undefined;
207
- aboutMe?: string | undefined;
208
- newsletterSubscription?: boolean | undefined;
209
- hideSubscriptions?: boolean | undefined;
210
- avatarUrl?: string | undefined;
211
- bannerUrl?: string | undefined;
212
- countryId?: string | undefined;
213
- timezone?:
214
- | string
215
- | undefined;
216
- /**
217
- * social_media remains repeated (an empty list is still a meaningful
218
- * "replace with empty"); the gateway omits the field entirely when the
219
- * client didn't send it so partial patches don't clear social links.
220
- */
221
- socialMedia: CreateSocialMedia[];
222
- /**
223
- * Premium-only fields — rejected with FAILED_PRECONDITION when the caller
224
- * has no active premium. `''` = no change, `__clear__` = explicit reset.
225
- */
226
- profileColor?: string | undefined;
227
- avatarBorderId?: string | undefined;
228
- animatedAvatarUrl?: string | undefined;
229
- animatedBannerUrl?: string | undefined;
230
- }
231
-
232
- export interface UpdateUserRequest {
233
- userId: string;
234
- username: string;
235
- email: string;
236
- /** confirmation code when changing email/username */
237
- code: string;
238
- }
239
-
240
- export interface UserResponse {
241
- user: User | undefined;
242
- }
243
-
244
- /**
245
- * Lightweight uniqueness probe for signup / account-settings forms. Called
246
- * often (per keystroke/blur) — backed by a single indexed query, no writes.
247
- * Mirrors the exact-match uniqueness check in UpdateUser so availability never
248
- * disagrees with the real collision at submit time.
249
- */
250
- export interface CheckAvailabilityRequest {
251
- /** empty = skip this field */
252
- username: string;
253
- /** empty = skip this field */
254
- email: string;
255
- /** empty = none; set to current user so editing */
256
- excludeUserId: string;
257
- }
258
-
259
- export interface CheckAvailabilityResponse {
260
- /** false = username wasn't part of the query */
261
- usernameChecked: boolean;
262
- usernameAvailable: boolean;
263
- /** false = email wasn't part of the query */
264
- emailChecked: boolean;
265
- emailAvailable: boolean;
266
- }
267
-
268
- export interface UpdateUserRoleRequest {
269
- adminId: string;
270
- userId: string;
271
- role: string;
272
- /** "grant" (default) | "revoke" */
273
- action: string;
274
- }
275
-
276
- export interface GetUsersRequest {
277
- page: string;
278
- limit: string;
279
- search: string;
280
- roleName: string;
281
- }
282
-
283
- export interface GetUsersResponse {
284
- items: User[];
285
- total: number;
286
- page: number;
287
- limit: number;
288
- }
289
-
290
- export interface GetActiveDevicesRequest {
291
- userId: string;
292
- }
293
-
294
- export interface GetActiveDevicesResponse {
295
- devices: ActiveDevice[];
296
- }
297
-
298
- export interface ManageDevicesRequest {
299
- userId: string;
300
- deviceIdsToRemove: string[];
301
- }
302
-
303
- export interface ManageDevicesResponse {
304
- ok: boolean;
305
- removedCount: number;
306
- }
307
-
308
- export interface GetUserFieldsRequest {
309
- username: string;
310
- type: UserFieldsType;
311
- page: number;
312
- limit: number;
313
- /** optional */
314
- viewerUserId: string;
315
- }
316
-
317
- export interface GetUserFieldsResponse {
318
- videos: Video[];
319
- products: Product[];
320
- subscriptions: ProfileUser[];
321
- subscribers: ProfileUser[];
322
- total: number;
323
- page: number;
324
- limit: number;
325
- }
326
-
327
- export interface SubscriptionRequest {
328
- /** the authenticated user performing the action */
329
- subscriberId: string;
330
- /** the user being (un)subscribed to/from */
331
- targetId: string;
332
- }
333
-
334
- export interface SubscriptionResponse {
335
- /** state after the call */
336
- subscribed: boolean;
337
- /** target's subscriber count after the call */
338
- subscribersCount: number;
339
- }
340
-
341
- export interface GetMyPremiumRequest {
342
- userId: string;
343
- }
344
-
345
- export interface PremiumStateResponse {
346
- isActive: boolean;
347
- /** ACTIVE | EXPIRED | CANCELED | empty (never purchased) */
348
- status: string;
349
- currentPeriod: PremiumPeriod;
350
- /** ISO 8601, empty when never purchased */
351
- startedAt: string;
352
- /** ISO 8601 */
353
- expiresAt: string;
354
- autoRenew: boolean;
355
- /** null when not active */
356
- plan:
357
- | PremiumPlanInfo
358
- | undefined;
359
- /** null when no premium payment method preference */
360
- savedPaymentMethod: PremiumSavedPaymentMethod | undefined;
361
- }
362
-
363
- export interface PremiumSavedPaymentMethod {
364
- /** BALANCE | YOOKASSA | SAVED_CARD */
365
- method: string;
366
- /** null unless method=SAVED_CARD */
367
- card: PremiumSavedPaymentCard | undefined;
368
- }
369
-
370
- export interface PremiumSavedPaymentCard {
371
- id: string;
372
- brand: string;
373
- last4: string;
374
- expMonth: number;
375
- expYear: number;
376
- isDefault: boolean;
377
- nickname: string;
378
- createdAt: string;
379
- }
380
-
381
- export interface SetPremiumAutoRenewRequest {
382
- userId: string;
383
- enabled: boolean;
384
- }
385
-
386
- /**
387
- * Internal — payments-service hands us the period that was just paid for, plus
388
- * the YooKassa payment_method id (empty for balance/non-recurring purchases).
389
- */
390
- export interface ActivatePremiumRequest {
391
- userId: string;
392
- period: PremiumPeriod;
393
- /** empty for BALANCE / one-shot */
394
- paymentMethodId: string;
395
- /** false = first purchase; true = cron-driven renewal */
396
- isRenewal: boolean;
397
- /** set by the purchase flow; renewals keep true */
398
- autoRenew: boolean;
399
- }
400
-
401
- export interface IsPremiumActiveRequest {
402
- userId: string;
403
- }
404
-
405
- export interface IsPremiumActiveResponse {
406
- isActive: boolean;
407
- }
408
-
409
- export interface AvatarBorder {
410
- id: string;
411
- code: string;
412
- name: string;
413
- description: string;
414
- imageUrl: string;
415
- isAnimated: boolean;
416
- source: string;
417
- sortOrder: number;
418
- isActive: boolean;
419
- }
420
-
421
- export interface ListAvatarBordersRequest {
422
- /** admin-only — gateway gates by role */
423
- includeInactive: boolean;
424
- /** optional filter */
425
- source: string;
426
- }
427
-
428
- export interface ListAvatarBordersResponse {
429
- items: AvatarBorder[];
430
- }
431
-
432
- export interface UpsertAvatarBorderRequest {
433
- /** empty = create */
434
- id: string;
435
- /** required when creating */
436
- code: string;
437
- name: string;
438
- description: string;
439
- imageUrl: string;
440
- isAnimated: boolean;
441
- source: string;
442
- sortOrder: number;
443
- isActive: boolean;
444
- }
445
-
446
- export interface DeleteAvatarBorderRequest {
447
- id: string;
448
- }
449
-
450
- export interface DeleteAvatarBorderResponse {
451
- ok: boolean;
452
- }
453
-
454
- export interface UpdatePrivacyRequest {
455
- userId: string;
456
- hideEmail: boolean;
457
- hideBalance: boolean;
458
- hideOnline: boolean;
459
- }
460
-
461
- export interface UpdateEmailPrefsRequest {
462
- userId: string;
463
- emailOnSales: boolean;
464
- emailOnReviews: boolean;
465
- emailOnNews: boolean;
466
- }
467
-
468
- export interface UpdateEmailPrefsResponse {
469
- emailOnSales: boolean;
470
- emailOnReviews: boolean;
471
- emailOnNews: boolean;
472
- }
473
-
474
- export interface UpdateLocaleRequest {
475
- userId: string;
476
- /** "ru" | "en" | ... */
477
- locale: string;
478
- }
479
-
480
- export interface UpdateLocaleResponse {
481
- locale: string;
482
- }
483
-
484
- export interface SoftDeleteAccountRequest {
485
- userId: string;
486
- /** optional, for support/audit */
487
- reason: string;
488
- /** 0 → use server default (30) */
489
- cooldownDays: number;
490
- }
491
-
492
- export interface SoftDeleteAccountResponse {
493
- /** ISO 8601 */
494
- deletedAt: string;
495
- scheduledForHardDelete: string;
496
- }
497
-
498
- export interface RestoreAccountRequest {
499
- userId: string;
500
- }
501
-
502
- export interface HardDeletePendingRequest {
503
- /** 0 → default 100 */
504
- maxBatch: number;
505
- }
506
-
507
- export interface HardDeletePendingResponse {
508
- deleted: number;
509
- }
510
-
511
- export interface ChangePasswordRequest {
512
- userId: string;
513
- currentPassword: string;
514
- newPassword: string;
515
- /** Optional: revoke all other sessions on success. */
516
- revokeOtherSessions: boolean;
517
- }
518
-
519
- export interface BlockUserRequest {
520
- blockerId: string;
521
- blockedId: string;
522
- /** optional */
523
- reason: string;
524
- }
525
-
526
- export interface BlockUserResponse {
527
- blocked: boolean;
528
- }
529
-
530
- export interface BlockedUserRow {
531
- id: string;
532
- username: string;
533
- avatarUrl: string;
534
- blockedAt: string;
535
- reason: string;
536
- }
537
-
538
- export interface ListBlockedUsersRequest {
539
- blockerId: string;
540
- page: number;
541
- limit: number;
542
- }
543
-
544
- export interface ListBlockedUsersResponse {
545
- items: BlockedUserRow[];
546
- total: number;
547
- page: number;
548
- limit: number;
549
- }
550
-
551
- export interface IsBlockedRequest {
552
- blockerId: string;
553
- blockedId: string;
554
- }
555
-
556
- export interface IsBlockedResponse {
557
- isBlocked: boolean;
558
- }
559
-
560
- export interface DataExportRequestRow {
561
- id: string;
562
- userId: string;
563
- /** PENDING | PROCESSING | READY | FAILED */
564
- status: string;
565
- fileUrl: string;
566
- fileSize: number;
567
- error: string;
568
- createdAt: string;
569
- completedAt: string;
570
- }
571
-
572
- export interface RequestDataExportRequest {
573
- userId: string;
574
- }
575
-
576
- export interface ListDataExportsRequest {
577
- userId: string;
578
- page: number;
579
- limit: number;
580
- }
581
-
582
- export interface ListDataExportsResponse {
583
- items: DataExportRequestRow[];
584
- total: number;
585
- page: number;
586
- limit: number;
587
- }
588
-
589
- export interface PickPendingDataExportRequest {
590
- /** tasks-service polls; returns one PENDING row marked PROCESSING, or empty. */
591
- Placeholder: boolean;
592
- }
593
-
594
- export interface CompleteDataExportRequest {
595
- id: string;
596
- fileUrl: string;
597
- fileSize: number;
598
- /** if set, marks FAILED instead of READY */
599
- error: string;
600
- }
601
-
602
- export interface CollectUserExportDataRequest {
603
- userId: string;
604
- }
605
-
606
- export interface CollectUserExportDataResponse {
607
- /**
608
- * Opaque JSON-as-string of user-owned data. tasks-service writes it to
609
- * S3 verbatim. Keeps the schema-specific marshaling private to users-service.
610
- */
611
- payloadJson: string;
612
- }
613
-
614
- export interface GetAccountSettingsRequest {
615
- userId: string;
616
- }
617
-
618
- /**
619
- * Current premium plan the user holds. Mirrors a PremiumPlan catalog entry.
620
- * Absent (null) when the user has no active subscription.
621
- */
622
- export interface PremiumPlanInfo {
623
- /** MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12 */
624
- period: string;
625
- months: number;
626
- /** total for the period, Decimal-as-string */
627
- price: string;
628
- /** ≈ X ₽/month */
629
- monthlyPrice: string;
630
- discountPercent: string;
631
- currency: string;
632
- }
633
-
634
- export interface AccountSettingsResponse {
635
- /** Identity */
636
- id: string;
637
- username: string;
638
- email: string;
639
- fullName: string;
640
- aboutMe: string;
641
- avatarUrl: string;
642
- bannerUrl: string;
643
- locale: string;
644
- timezone: string;
645
- countryId: string;
646
- createdAt: string;
647
- /** 2FA */
648
- twoFactorType: string;
649
- twoFactorEnabled: boolean;
650
- backupCodesRemaining: number;
651
- /** Privacy */
652
- hideEmail: boolean;
653
- hideBalance: boolean;
654
- hideOnline: boolean;
655
- hideSubscriptions: boolean;
656
- /** Email prefs */
657
- emailOnSales: boolean;
658
- emailOnReviews: boolean;
659
- emailOnNews: boolean;
660
- /** Payout defaults */
661
- payoutMethod: string;
662
- payoutDetails: string;
663
- premiumIsActive: boolean;
664
- /** Soft-delete state */
665
- deletedAt: string;
666
- scheduledForHardDelete: string;
667
- socialMedia: SocialMedia[];
668
- /**
669
- * Premium customization snapshot — denormalised border image URL so the
670
- * client can render the current overlay without a second roundtrip.
671
- */
672
- avatarBorderId: string;
673
- avatarBorderImageUrl: string;
674
- animatedAvatarUrl: string;
675
- animatedBannerUrl: string;
676
- profileColor: string;
677
- }
678
-
679
- export const USERS_V1_PACKAGE_NAME = "users.v1";
680
-
681
- export interface UsersServiceClient {
682
- getPublicProfile(request: GetPublicProfileRequest): Observable<PublicProfileResponse>;
683
-
684
- updateProfile(request: UpdateProfileRequest): Observable<PublicProfileResponse>;
685
-
686
- updateUser(request: UpdateUserRequest): Observable<UserResponse>;
687
-
688
- checkAvailability(request: CheckAvailabilityRequest): Observable<CheckAvailabilityResponse>;
689
-
690
- updateUserRole(request: UpdateUserRoleRequest): Observable<UserResponse>;
691
-
692
- getUsers(request: GetUsersRequest): Observable<GetUsersResponse>;
693
-
694
- getActiveDevices(request: GetActiveDevicesRequest): Observable<GetActiveDevicesResponse>;
695
-
696
- manageDevices(request: ManageDevicesRequest): Observable<ManageDevicesResponse>;
697
-
698
- getUserFields(request: GetUserFieldsRequest): Observable<GetUserFieldsResponse>;
699
-
700
- createSubscription(request: SubscriptionRequest): Observable<SubscriptionResponse>;
701
-
702
- deleteSubscription(request: SubscriptionRequest): Observable<SubscriptionResponse>;
703
-
704
- banUser(request: BanUserRequest): Observable<UserResponse>;
705
-
706
- unbanUser(request: UnbanUserRequest): Observable<UserResponse>;
707
-
708
- /**
709
- * Premium (paid). State lives in users-service; payments-service handles
710
- * money and calls ActivatePremium (internal) on completion.
711
- */
712
-
713
- getMyPremium(request: GetMyPremiumRequest): Observable<PremiumStateResponse>;
714
-
715
- setPremiumAutoRenew(request: SetPremiumAutoRenewRequest): Observable<PremiumStateResponse>;
716
-
717
- /**
718
- * Internal — InternalServiceGuard. Called by payments-service after a
719
- * successful premium payment (balance or YooKassa webhook).
720
- */
721
-
722
- activatePremium(request: ActivatePremiumRequest): Observable<PremiumStateResponse>;
723
-
724
- /** Internal — fast lookup for the commission engine in payments-service. */
725
-
726
- isPremiumActive(request: IsPremiumActiveRequest): Observable<IsPremiumActiveResponse>;
727
-
728
- /**
729
- * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
730
- * are admin only (gateway enforces with RolesGuard).
731
- */
732
-
733
- listAvatarBorders(request: ListAvatarBordersRequest): Observable<ListAvatarBordersResponse>;
734
-
735
- upsertAvatarBorder(request: UpsertAvatarBorderRequest): Observable<AvatarBorder>;
736
-
737
- deleteAvatarBorder(request: DeleteAvatarBorderRequest): Observable<DeleteAvatarBorderResponse>;
738
-
739
- /** Account settings — bundled write surface for the UI. */
740
-
741
- updatePrivacy(request: UpdatePrivacyRequest): Observable<PublicProfileResponse>;
742
-
743
- updateEmailPrefs(request: UpdateEmailPrefsRequest): Observable<UpdateEmailPrefsResponse>;
744
-
745
- updateLocale(request: UpdateLocaleRequest): Observable<UpdateLocaleResponse>;
746
-
747
- /**
748
- * Soft-delete + restore. Internal AuthService also queries the soft-delete
749
- * state on login (rejects if deletedAt set).
750
- */
751
-
752
- softDeleteAccount(request: SoftDeleteAccountRequest): Observable<SoftDeleteAccountResponse>;
753
-
754
- restoreAccount(request: RestoreAccountRequest): Observable<UserResponse>;
755
-
756
- /** tasks-service cron */
757
-
758
- hardDeletePending(request: HardDeletePendingRequest): Observable<HardDeletePendingResponse>;
759
-
760
- /** Blocks */
761
-
762
- blockUser(request: BlockUserRequest): Observable<BlockUserResponse>;
763
-
764
- unblockUser(request: BlockUserRequest): Observable<BlockUserResponse>;
765
-
766
- listBlockedUsers(request: ListBlockedUsersRequest): Observable<ListBlockedUsersResponse>;
767
-
768
- /** internal lookup */
769
-
770
- isBlocked(request: IsBlockedRequest): Observable<IsBlockedResponse>;
771
-
772
- /** Data export */
773
-
774
- requestDataExport(request: RequestDataExportRequest): Observable<DataExportRequestRow>;
775
-
776
- listDataExports(request: ListDataExportsRequest): Observable<ListDataExportsResponse>;
777
-
778
- /** tasks-service */
779
-
780
- pickPendingDataExport(request: PickPendingDataExportRequest): Observable<DataExportRequestRow>;
781
-
782
- /** tasks-service */
783
-
784
- completeDataExport(request: CompleteDataExportRequest): Observable<DataExportRequestRow>;
785
-
786
- /** tasks-service */
787
-
788
- collectUserExportData(request: CollectUserExportDataRequest): Observable<CollectUserExportDataResponse>;
789
-
790
- /** Unified read for the settings page */
791
-
792
- getAccountSettings(request: GetAccountSettingsRequest): Observable<AccountSettingsResponse>;
793
-
794
- /** Password — separate from generic createCode/verifyCode reset flow. */
795
-
796
- changePassword(request: ChangePasswordRequest): Observable<Ok>;
797
- }
798
-
799
- export interface UsersServiceController {
800
- getPublicProfile(
801
- request: GetPublicProfileRequest,
802
- ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
803
-
804
- updateProfile(
805
- request: UpdateProfileRequest,
806
- ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
807
-
808
- updateUser(request: UpdateUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
809
-
810
- checkAvailability(
811
- request: CheckAvailabilityRequest,
812
- ): Promise<CheckAvailabilityResponse> | Observable<CheckAvailabilityResponse> | CheckAvailabilityResponse;
813
-
814
- updateUserRole(request: UpdateUserRoleRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
815
-
816
- getUsers(request: GetUsersRequest): Promise<GetUsersResponse> | Observable<GetUsersResponse> | GetUsersResponse;
817
-
818
- getActiveDevices(
819
- request: GetActiveDevicesRequest,
820
- ): Promise<GetActiveDevicesResponse> | Observable<GetActiveDevicesResponse> | GetActiveDevicesResponse;
821
-
822
- manageDevices(
823
- request: ManageDevicesRequest,
824
- ): Promise<ManageDevicesResponse> | Observable<ManageDevicesResponse> | ManageDevicesResponse;
825
-
826
- getUserFields(
827
- request: GetUserFieldsRequest,
828
- ): Promise<GetUserFieldsResponse> | Observable<GetUserFieldsResponse> | GetUserFieldsResponse;
829
-
830
- createSubscription(
831
- request: SubscriptionRequest,
832
- ): Promise<SubscriptionResponse> | Observable<SubscriptionResponse> | SubscriptionResponse;
833
-
834
- deleteSubscription(
835
- request: SubscriptionRequest,
836
- ): Promise<SubscriptionResponse> | Observable<SubscriptionResponse> | SubscriptionResponse;
837
-
838
- banUser(request: BanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
839
-
840
- unbanUser(request: UnbanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
841
-
842
- /**
843
- * Premium (paid). State lives in users-service; payments-service handles
844
- * money and calls ActivatePremium (internal) on completion.
845
- */
846
-
847
- getMyPremium(
848
- request: GetMyPremiumRequest,
849
- ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
850
-
851
- setPremiumAutoRenew(
852
- request: SetPremiumAutoRenewRequest,
853
- ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
854
-
855
- /**
856
- * Internal — InternalServiceGuard. Called by payments-service after a
857
- * successful premium payment (balance or YooKassa webhook).
858
- */
859
-
860
- activatePremium(
861
- request: ActivatePremiumRequest,
862
- ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
863
-
864
- /** Internal — fast lookup for the commission engine in payments-service. */
865
-
866
- isPremiumActive(
867
- request: IsPremiumActiveRequest,
868
- ): Promise<IsPremiumActiveResponse> | Observable<IsPremiumActiveResponse> | IsPremiumActiveResponse;
869
-
870
- /**
871
- * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
872
- * are admin only (gateway enforces with RolesGuard).
873
- */
874
-
875
- listAvatarBorders(
876
- request: ListAvatarBordersRequest,
877
- ): Promise<ListAvatarBordersResponse> | Observable<ListAvatarBordersResponse> | ListAvatarBordersResponse;
878
-
879
- upsertAvatarBorder(
880
- request: UpsertAvatarBorderRequest,
881
- ): Promise<AvatarBorder> | Observable<AvatarBorder> | AvatarBorder;
882
-
883
- deleteAvatarBorder(
884
- request: DeleteAvatarBorderRequest,
885
- ): Promise<DeleteAvatarBorderResponse> | Observable<DeleteAvatarBorderResponse> | DeleteAvatarBorderResponse;
886
-
887
- /** Account settings — bundled write surface for the UI. */
888
-
889
- updatePrivacy(
890
- request: UpdatePrivacyRequest,
891
- ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
892
-
893
- updateEmailPrefs(
894
- request: UpdateEmailPrefsRequest,
895
- ): Promise<UpdateEmailPrefsResponse> | Observable<UpdateEmailPrefsResponse> | UpdateEmailPrefsResponse;
896
-
897
- updateLocale(
898
- request: UpdateLocaleRequest,
899
- ): Promise<UpdateLocaleResponse> | Observable<UpdateLocaleResponse> | UpdateLocaleResponse;
900
-
901
- /**
902
- * Soft-delete + restore. Internal AuthService also queries the soft-delete
903
- * state on login (rejects if deletedAt set).
904
- */
905
-
906
- softDeleteAccount(
907
- request: SoftDeleteAccountRequest,
908
- ): Promise<SoftDeleteAccountResponse> | Observable<SoftDeleteAccountResponse> | SoftDeleteAccountResponse;
909
-
910
- restoreAccount(request: RestoreAccountRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
911
-
912
- /** tasks-service cron */
913
-
914
- hardDeletePending(
915
- request: HardDeletePendingRequest,
916
- ): Promise<HardDeletePendingResponse> | Observable<HardDeletePendingResponse> | HardDeletePendingResponse;
917
-
918
- /** Blocks */
919
-
920
- blockUser(request: BlockUserRequest): Promise<BlockUserResponse> | Observable<BlockUserResponse> | BlockUserResponse;
921
-
922
- unblockUser(
923
- request: BlockUserRequest,
924
- ): Promise<BlockUserResponse> | Observable<BlockUserResponse> | BlockUserResponse;
925
-
926
- listBlockedUsers(
927
- request: ListBlockedUsersRequest,
928
- ): Promise<ListBlockedUsersResponse> | Observable<ListBlockedUsersResponse> | ListBlockedUsersResponse;
929
-
930
- /** internal lookup */
931
-
932
- isBlocked(request: IsBlockedRequest): Promise<IsBlockedResponse> | Observable<IsBlockedResponse> | IsBlockedResponse;
933
-
934
- /** Data export */
935
-
936
- requestDataExport(
937
- request: RequestDataExportRequest,
938
- ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
939
-
940
- listDataExports(
941
- request: ListDataExportsRequest,
942
- ): Promise<ListDataExportsResponse> | Observable<ListDataExportsResponse> | ListDataExportsResponse;
943
-
944
- /** tasks-service */
945
-
946
- pickPendingDataExport(
947
- request: PickPendingDataExportRequest,
948
- ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
949
-
950
- /** tasks-service */
951
-
952
- completeDataExport(
953
- request: CompleteDataExportRequest,
954
- ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
955
-
956
- /** tasks-service */
957
-
958
- collectUserExportData(
959
- request: CollectUserExportDataRequest,
960
- ): Promise<CollectUserExportDataResponse> | Observable<CollectUserExportDataResponse> | CollectUserExportDataResponse;
961
-
962
- /** Unified read for the settings page */
963
-
964
- getAccountSettings(
965
- request: GetAccountSettingsRequest,
966
- ): Promise<AccountSettingsResponse> | Observable<AccountSettingsResponse> | AccountSettingsResponse;
967
-
968
- /** Password — separate from generic createCode/verifyCode reset flow. */
969
-
970
- changePassword(request: ChangePasswordRequest): Promise<Ok> | Observable<Ok> | Ok;
971
- }
972
-
973
- export function UsersServiceControllerMethods() {
974
- return function (constructor: Function) {
975
- const grpcMethods: string[] = [
976
- "getPublicProfile",
977
- "updateProfile",
978
- "updateUser",
979
- "checkAvailability",
980
- "updateUserRole",
981
- "getUsers",
982
- "getActiveDevices",
983
- "manageDevices",
984
- "getUserFields",
985
- "createSubscription",
986
- "deleteSubscription",
987
- "banUser",
988
- "unbanUser",
989
- "getMyPremium",
990
- "setPremiumAutoRenew",
991
- "activatePremium",
992
- "isPremiumActive",
993
- "listAvatarBorders",
994
- "upsertAvatarBorder",
995
- "deleteAvatarBorder",
996
- "updatePrivacy",
997
- "updateEmailPrefs",
998
- "updateLocale",
999
- "softDeleteAccount",
1000
- "restoreAccount",
1001
- "hardDeletePending",
1002
- "blockUser",
1003
- "unblockUser",
1004
- "listBlockedUsers",
1005
- "isBlocked",
1006
- "requestDataExport",
1007
- "listDataExports",
1008
- "pickPendingDataExport",
1009
- "completeDataExport",
1010
- "collectUserExportData",
1011
- "getAccountSettings",
1012
- "changePassword",
1013
- ];
1014
- for (const method of grpcMethods) {
1015
- const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
1016
- GrpcMethod("UsersService", method)(constructor.prototype[method], method, descriptor);
1017
- }
1018
- const grpcStreamMethods: string[] = [];
1019
- for (const method of grpcStreamMethods) {
1020
- const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
1021
- GrpcStreamMethod("UsersService", method)(constructor.prototype[method], method, descriptor);
1022
- }
1023
- };
1024
- }
1025
-
1026
- export const USERS_SERVICE_NAME = "UsersService";
1
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
+ // versions:
3
+ // protoc-gen-ts_proto v2.10.1
4
+ // protoc v7.35.1
5
+ // source: users.proto
6
+
7
+ /* eslint-disable */
8
+ import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
9
+ import { Observable } from "rxjs";
10
+
11
+ export const protobufPackage = "users.v1";
12
+
13
+ export enum UserFieldsType {
14
+ USER_FIELDS_TYPE_UNSPECIFIED = 0,
15
+ USER_FIELDS_TYPE_VIDEOS = 1,
16
+ USER_FIELDS_TYPE_PRODUCTS = 2,
17
+ USER_FIELDS_TYPE_SUBSCRIPTIONS = 3,
18
+ USER_FIELDS_TYPE_SUBSCRIBERS = 4,
19
+ UNRECOGNIZED = -1,
20
+ }
21
+
22
+ /** Periods mirror PremiumPeriod enum in schema.prisma. */
23
+ export enum PremiumPeriod {
24
+ PREMIUM_PERIOD_UNSPECIFIED = 0,
25
+ PREMIUM_PERIOD_MONTH_1 = 1,
26
+ PREMIUM_PERIOD_MONTH_3 = 2,
27
+ PREMIUM_PERIOD_MONTH_6 = 3,
28
+ PREMIUM_PERIOD_MONTH_12 = 4,
29
+ UNRECOGNIZED = -1,
30
+ }
31
+
32
+ export interface Ok {
33
+ ok: boolean;
34
+ }
35
+
36
+ export interface User {
37
+ id: string;
38
+ email: string;
39
+ username: string;
40
+ avatarUrl: string;
41
+ roles: string[];
42
+ /** ISO 8601 */
43
+ createdAt: string;
44
+ updatedAt: string;
45
+ isBanned: boolean;
46
+ /** ISO 8601, empty = permanent/none */
47
+ bannedUntil: string;
48
+ banReason: string;
49
+ fullName: string;
50
+ avatarBorderImageUrl: string;
51
+ }
52
+
53
+ export interface BanUserRequest {
54
+ adminId: string;
55
+ userId: string;
56
+ reason: string;
57
+ /** ISO 8601; empty = permanent ban */
58
+ until: string;
59
+ }
60
+
61
+ export interface UnbanUserRequest {
62
+ adminId: string;
63
+ userId: string;
64
+ }
65
+
66
+ export interface Country {
67
+ id: string;
68
+ code: string;
69
+ name: string;
70
+ }
71
+
72
+ export interface SocialMedia {
73
+ id: string;
74
+ platform: string;
75
+ /** full link (built from username on read; empty for discord) */
76
+ url: string;
77
+ /** handle for handle-based platforms; empty for website */
78
+ username: string;
79
+ }
80
+
81
+ export interface CreateSocialMedia {
82
+ platform: string;
83
+ /** only for platform="website" */
84
+ url: string;
85
+ /** handle for all other platforms */
86
+ username: string;
87
+ }
88
+
89
+ export interface ProductUser {
90
+ id: string;
91
+ username: string;
92
+ avatarUrl: string;
93
+ }
94
+
95
+ export interface Category {
96
+ id: string;
97
+ name: string;
98
+ }
99
+
100
+ export interface Product {
101
+ id: string;
102
+ name: string;
103
+ description: string;
104
+ /** Decimal as string (D7) */
105
+ price: string;
106
+ createdAt: string;
107
+ updatedAt: string;
108
+ /** profile-card preview fields */
109
+ preview: string;
110
+ /** Decimal as string */
111
+ finalPrice: string;
112
+ /** number as string */
113
+ averageRating: string;
114
+ status: string;
115
+ /**
116
+ * Author of the product (same person as the profile owner, but echoed per
117
+ * product so cards can render the author independently).
118
+ */
119
+ user: ProductUser | undefined;
120
+ categories: Category[];
121
+ }
122
+
123
+ export interface Video {
124
+ id: string;
125
+ title: string;
126
+ description: string;
127
+ url: string;
128
+ createdAt: string;
129
+ updatedAt: string;
130
+ }
131
+
132
+ export interface ActiveDevice {
133
+ id: string;
134
+ userAgent: string;
135
+ ip: string;
136
+ createdAt: string;
137
+ lastUsedAt: string;
138
+ }
139
+
140
+ export interface ProfileStats {
141
+ subscribersCount: number;
142
+ subscriptionsCount: number;
143
+ productsCount: number;
144
+ videosCount: number;
145
+ }
146
+
147
+ /** Compact public user card for subscriber/subscription lists — no email/ban data. */
148
+ export interface ProfileUser {
149
+ id: string;
150
+ username: string;
151
+ avatarUrl: string;
152
+ fullName: string;
153
+ avatarBorderImageUrl: string;
154
+ }
155
+
156
+ export interface GetPublicProfileRequest {
157
+ username: string;
158
+ /** optional — present when caller is authenticated */
159
+ viewerUserId: string;
160
+ }
161
+
162
+ export interface PublicProfileResponse {
163
+ id: string;
164
+ username: string;
165
+ fullName: string;
166
+ /** Decimal as string */
167
+ rating: string;
168
+ aboutMe: string;
169
+ socialMedia: SocialMedia[];
170
+ stats: ProfileStats | undefined;
171
+ videos: Video[];
172
+ products: Product[];
173
+ country: Country | undefined;
174
+ avatarUrl: string;
175
+ bannerUrl: string;
176
+ role: string;
177
+ createdAt: string;
178
+ hideSubscriptions: boolean;
179
+ /** Either populated lists or empty depending on hide_subscriptions */
180
+ subscriptions: ProfileUser[];
181
+ subscribers: ProfileUser[];
182
+ isOwner: boolean;
183
+ /** viewer is subscribed to this profile (false when anonymous / self) */
184
+ isSubscribed: boolean;
185
+ /**
186
+ * Premium fields — populated only when the profile owner has an active
187
+ * PremiumSubscription. Non-premium viewers and non-premium profiles see
188
+ * empty strings / false.
189
+ */
190
+ isPremium: boolean;
191
+ profileColor: string;
192
+ avatarBorder: AvatarBorder | undefined;
193
+ animatedAvatarUrl: string;
194
+ animatedBannerUrl: string;
195
+ /** ISO 8601, empty when not premium */
196
+ premiumExpiresAt: string;
197
+ }
198
+
199
+ export interface UpdateProfileRequest {
200
+ userId: string;
201
+ /**
202
+ * Every editable field is `optional` so the wire format preserves the
203
+ * "not set" state. A partial patch from the client (e.g. only avatarUrl)
204
+ * no longer accidentally wipes the other columns to proto3 defaults.
205
+ */
206
+ fullName?: string | undefined;
207
+ aboutMe?: string | undefined;
208
+ newsletterSubscription?: boolean | undefined;
209
+ hideSubscriptions?: boolean | undefined;
210
+ avatarUrl?: string | undefined;
211
+ bannerUrl?: string | undefined;
212
+ countryId?: string | undefined;
213
+ timezone?:
214
+ | string
215
+ | undefined;
216
+ /**
217
+ * social_media remains repeated (an empty list is still a meaningful
218
+ * "replace with empty"); the gateway omits the field entirely when the
219
+ * client didn't send it so partial patches don't clear social links.
220
+ */
221
+ socialMedia: CreateSocialMedia[];
222
+ /**
223
+ * Premium-only fields — rejected with FAILED_PRECONDITION when the caller
224
+ * has no active premium. `''` = no change, `__clear__` = explicit reset.
225
+ */
226
+ profileColor?: string | undefined;
227
+ avatarBorderId?: string | undefined;
228
+ animatedAvatarUrl?: string | undefined;
229
+ animatedBannerUrl?: string | undefined;
230
+ }
231
+
232
+ export interface UpdateUserRequest {
233
+ userId: string;
234
+ username: string;
235
+ email: string;
236
+ /** confirmation code when changing email/username */
237
+ code: string;
238
+ }
239
+
240
+ export interface UserResponse {
241
+ user: User | undefined;
242
+ }
243
+
244
+ /**
245
+ * Lightweight uniqueness probe for signup / account-settings forms. Called
246
+ * often (per keystroke/blur) — backed by a single indexed query, no writes.
247
+ * Mirrors the exact-match uniqueness check in UpdateUser so availability never
248
+ * disagrees with the real collision at submit time.
249
+ */
250
+ export interface CheckAvailabilityRequest {
251
+ /** empty = skip this field */
252
+ username: string;
253
+ /** empty = skip this field */
254
+ email: string;
255
+ /** empty = none; set to current user so editing */
256
+ excludeUserId: string;
257
+ }
258
+
259
+ export interface CheckAvailabilityResponse {
260
+ /** false = username wasn't part of the query */
261
+ usernameChecked: boolean;
262
+ usernameAvailable: boolean;
263
+ /** false = email wasn't part of the query */
264
+ emailChecked: boolean;
265
+ emailAvailable: boolean;
266
+ }
267
+
268
+ export interface UpdateUserRoleRequest {
269
+ adminId: string;
270
+ userId: string;
271
+ role: string;
272
+ /** "grant" (default) | "revoke" */
273
+ action: string;
274
+ }
275
+
276
+ export interface GetUsersRequest {
277
+ page: string;
278
+ limit: string;
279
+ search: string;
280
+ roleName: string;
281
+ }
282
+
283
+ export interface GetUsersResponse {
284
+ items: User[];
285
+ total: number;
286
+ page: number;
287
+ limit: number;
288
+ }
289
+
290
+ export interface GetActiveDevicesRequest {
291
+ userId: string;
292
+ }
293
+
294
+ export interface GetActiveDevicesResponse {
295
+ devices: ActiveDevice[];
296
+ }
297
+
298
+ export interface ManageDevicesRequest {
299
+ userId: string;
300
+ deviceIdsToRemove: string[];
301
+ }
302
+
303
+ export interface ManageDevicesResponse {
304
+ ok: boolean;
305
+ removedCount: number;
306
+ }
307
+
308
+ export interface GetUserFieldsRequest {
309
+ username: string;
310
+ type: UserFieldsType;
311
+ page: number;
312
+ limit: number;
313
+ /** optional */
314
+ viewerUserId: string;
315
+ }
316
+
317
+ export interface GetUserFieldsResponse {
318
+ videos: Video[];
319
+ products: Product[];
320
+ subscriptions: ProfileUser[];
321
+ subscribers: ProfileUser[];
322
+ total: number;
323
+ page: number;
324
+ limit: number;
325
+ }
326
+
327
+ export interface SubscriptionRequest {
328
+ /** the authenticated user performing the action */
329
+ subscriberId: string;
330
+ /** the user being (un)subscribed to/from */
331
+ targetId: string;
332
+ }
333
+
334
+ export interface SubscriptionResponse {
335
+ /** state after the call */
336
+ subscribed: boolean;
337
+ /** target's subscriber count after the call */
338
+ subscribersCount: number;
339
+ }
340
+
341
+ export interface GetMyPremiumRequest {
342
+ userId: string;
343
+ }
344
+
345
+ export interface PremiumStateResponse {
346
+ isActive: boolean;
347
+ /** ACTIVE | EXPIRED | CANCELED | empty (never purchased) */
348
+ status: string;
349
+ currentPeriod: PremiumPeriod;
350
+ /** ISO 8601, empty when never purchased */
351
+ startedAt: string;
352
+ /** ISO 8601 */
353
+ expiresAt: string;
354
+ autoRenew: boolean;
355
+ /** null when not active */
356
+ plan:
357
+ | PremiumPlanInfo
358
+ | undefined;
359
+ /** null when no premium payment method preference */
360
+ savedPaymentMethod: PremiumSavedPaymentMethod | undefined;
361
+ }
362
+
363
+ export interface PremiumSavedPaymentMethod {
364
+ /** BALANCE | YOOKASSA | SAVED_CARD */
365
+ method: string;
366
+ /** null unless method=SAVED_CARD */
367
+ card: PremiumSavedPaymentCard | undefined;
368
+ }
369
+
370
+ export interface PremiumSavedPaymentCard {
371
+ id: string;
372
+ brand: string;
373
+ last4: string;
374
+ expMonth: number;
375
+ expYear: number;
376
+ isDefault: boolean;
377
+ nickname: string;
378
+ createdAt: string;
379
+ }
380
+
381
+ export interface SetPremiumAutoRenewRequest {
382
+ userId: string;
383
+ enabled: boolean;
384
+ }
385
+
386
+ /**
387
+ * Internal — payments-service hands us the period that was just paid for, plus
388
+ * the YooKassa payment_method id (empty for balance/non-recurring purchases).
389
+ */
390
+ export interface ActivatePremiumRequest {
391
+ userId: string;
392
+ period: PremiumPeriod;
393
+ /** empty for BALANCE / one-shot */
394
+ paymentMethodId: string;
395
+ /** false = first purchase; true = cron-driven renewal */
396
+ isRenewal: boolean;
397
+ /** set by the purchase flow; renewals keep true */
398
+ autoRenew: boolean;
399
+ }
400
+
401
+ export interface IsPremiumActiveRequest {
402
+ userId: string;
403
+ }
404
+
405
+ export interface IsPremiumActiveResponse {
406
+ isActive: boolean;
407
+ }
408
+
409
+ export interface AvatarBorder {
410
+ id: string;
411
+ code: string;
412
+ name: string;
413
+ description: string;
414
+ imageUrl: string;
415
+ isAnimated: boolean;
416
+ source: string;
417
+ sortOrder: number;
418
+ isActive: boolean;
419
+ }
420
+
421
+ export interface ListAvatarBordersRequest {
422
+ /** admin-only — gateway gates by role */
423
+ includeInactive: boolean;
424
+ /** optional filter */
425
+ source: string;
426
+ }
427
+
428
+ export interface ListAvatarBordersResponse {
429
+ items: AvatarBorder[];
430
+ }
431
+
432
+ export interface UpsertAvatarBorderRequest {
433
+ /** empty = create */
434
+ id: string;
435
+ /** required when creating */
436
+ code: string;
437
+ name: string;
438
+ description: string;
439
+ imageUrl: string;
440
+ isAnimated: boolean;
441
+ source: string;
442
+ sortOrder: number;
443
+ isActive: boolean;
444
+ }
445
+
446
+ export interface DeleteAvatarBorderRequest {
447
+ id: string;
448
+ }
449
+
450
+ export interface DeleteAvatarBorderResponse {
451
+ ok: boolean;
452
+ }
453
+
454
+ export interface UpdatePrivacyRequest {
455
+ userId: string;
456
+ hideEmail: boolean;
457
+ hideBalance: boolean;
458
+ hideOnline: boolean;
459
+ }
460
+
461
+ export interface UpdateEmailPrefsRequest {
462
+ userId: string;
463
+ emailOnSales: boolean;
464
+ emailOnReviews: boolean;
465
+ emailOnNews: boolean;
466
+ }
467
+
468
+ export interface UpdateEmailPrefsResponse {
469
+ emailOnSales: boolean;
470
+ emailOnReviews: boolean;
471
+ emailOnNews: boolean;
472
+ }
473
+
474
+ export interface UpdateLocaleRequest {
475
+ userId: string;
476
+ /** "ru" | "en" | ... */
477
+ locale: string;
478
+ }
479
+
480
+ export interface UpdateLocaleResponse {
481
+ locale: string;
482
+ }
483
+
484
+ export interface SoftDeleteAccountRequest {
485
+ userId: string;
486
+ /** optional, for support/audit */
487
+ reason: string;
488
+ /** 0 → use server default (30) */
489
+ cooldownDays: number;
490
+ }
491
+
492
+ export interface SoftDeleteAccountResponse {
493
+ /** ISO 8601 */
494
+ deletedAt: string;
495
+ scheduledForHardDelete: string;
496
+ }
497
+
498
+ export interface RestoreAccountRequest {
499
+ userId: string;
500
+ }
501
+
502
+ export interface HardDeletePendingRequest {
503
+ /** 0 → default 100 */
504
+ maxBatch: number;
505
+ }
506
+
507
+ export interface HardDeletePendingResponse {
508
+ deleted: number;
509
+ }
510
+
511
+ export interface ChangePasswordRequest {
512
+ userId: string;
513
+ currentPassword: string;
514
+ newPassword: string;
515
+ /** Optional: revoke all other sessions on success. */
516
+ revokeOtherSessions: boolean;
517
+ }
518
+
519
+ export interface BlockUserRequest {
520
+ blockerId: string;
521
+ blockedId: string;
522
+ /** optional */
523
+ reason: string;
524
+ }
525
+
526
+ export interface BlockUserResponse {
527
+ blocked: boolean;
528
+ }
529
+
530
+ export interface BlockedUserRow {
531
+ id: string;
532
+ username: string;
533
+ avatarUrl: string;
534
+ blockedAt: string;
535
+ reason: string;
536
+ }
537
+
538
+ export interface ListBlockedUsersRequest {
539
+ blockerId: string;
540
+ page: number;
541
+ limit: number;
542
+ }
543
+
544
+ export interface ListBlockedUsersResponse {
545
+ items: BlockedUserRow[];
546
+ total: number;
547
+ page: number;
548
+ limit: number;
549
+ }
550
+
551
+ export interface IsBlockedRequest {
552
+ blockerId: string;
553
+ blockedId: string;
554
+ }
555
+
556
+ export interface IsBlockedResponse {
557
+ isBlocked: boolean;
558
+ }
559
+
560
+ export interface DataExportRequestRow {
561
+ id: string;
562
+ userId: string;
563
+ /** PENDING | PROCESSING | READY | FAILED */
564
+ status: string;
565
+ fileUrl: string;
566
+ fileSize: number;
567
+ error: string;
568
+ createdAt: string;
569
+ completedAt: string;
570
+ }
571
+
572
+ export interface RequestDataExportRequest {
573
+ userId: string;
574
+ }
575
+
576
+ export interface ListDataExportsRequest {
577
+ userId: string;
578
+ page: number;
579
+ limit: number;
580
+ }
581
+
582
+ export interface ListDataExportsResponse {
583
+ items: DataExportRequestRow[];
584
+ total: number;
585
+ page: number;
586
+ limit: number;
587
+ }
588
+
589
+ export interface PickPendingDataExportRequest {
590
+ /** tasks-service polls; returns one PENDING row marked PROCESSING, or empty. */
591
+ Placeholder: boolean;
592
+ }
593
+
594
+ export interface CompleteDataExportRequest {
595
+ id: string;
596
+ fileUrl: string;
597
+ fileSize: number;
598
+ /** if set, marks FAILED instead of READY */
599
+ error: string;
600
+ }
601
+
602
+ export interface CollectUserExportDataRequest {
603
+ userId: string;
604
+ }
605
+
606
+ export interface CollectUserExportDataResponse {
607
+ /**
608
+ * Opaque JSON-as-string of user-owned data. tasks-service writes it to
609
+ * S3 verbatim. Keeps the schema-specific marshaling private to users-service.
610
+ */
611
+ payloadJson: string;
612
+ }
613
+
614
+ export interface GetAccountSettingsRequest {
615
+ userId: string;
616
+ }
617
+
618
+ /**
619
+ * Current premium plan the user holds. Mirrors a PremiumPlan catalog entry.
620
+ * Absent (null) when the user has no active subscription.
621
+ */
622
+ export interface PremiumPlanInfo {
623
+ /** MONTH_1 | MONTH_3 | MONTH_6 | MONTH_12 */
624
+ period: string;
625
+ months: number;
626
+ /** total for the period, Decimal-as-string */
627
+ price: string;
628
+ /** ≈ X ₽/month */
629
+ monthlyPrice: string;
630
+ discountPercent: string;
631
+ currency: string;
632
+ }
633
+
634
+ export interface AccountSettingsResponse {
635
+ /** Identity */
636
+ id: string;
637
+ username: string;
638
+ email: string;
639
+ fullName: string;
640
+ aboutMe: string;
641
+ avatarUrl: string;
642
+ bannerUrl: string;
643
+ locale: string;
644
+ timezone: string;
645
+ countryId: string;
646
+ createdAt: string;
647
+ /** 2FA */
648
+ twoFactorType: string;
649
+ twoFactorEnabled: boolean;
650
+ backupCodesRemaining: number;
651
+ /** Privacy */
652
+ hideEmail: boolean;
653
+ hideBalance: boolean;
654
+ hideOnline: boolean;
655
+ hideSubscriptions: boolean;
656
+ /** Email prefs */
657
+ emailOnSales: boolean;
658
+ emailOnReviews: boolean;
659
+ emailOnNews: boolean;
660
+ /** Payout defaults */
661
+ payoutMethod: string;
662
+ payoutDetails: string;
663
+ premiumIsActive: boolean;
664
+ /** Soft-delete state */
665
+ deletedAt: string;
666
+ scheduledForHardDelete: string;
667
+ socialMedia: SocialMedia[];
668
+ /**
669
+ * Premium customization snapshot — denormalised border image URL so the
670
+ * client can render the current overlay without a second roundtrip.
671
+ */
672
+ avatarBorderId: string;
673
+ avatarBorderImageUrl: string;
674
+ animatedAvatarUrl: string;
675
+ animatedBannerUrl: string;
676
+ profileColor: string;
677
+ }
678
+
679
+ export const USERS_V1_PACKAGE_NAME = "users.v1";
680
+
681
+ export interface UsersServiceClient {
682
+ getPublicProfile(request: GetPublicProfileRequest): Observable<PublicProfileResponse>;
683
+
684
+ updateProfile(request: UpdateProfileRequest): Observable<PublicProfileResponse>;
685
+
686
+ updateUser(request: UpdateUserRequest): Observable<UserResponse>;
687
+
688
+ checkAvailability(request: CheckAvailabilityRequest): Observable<CheckAvailabilityResponse>;
689
+
690
+ updateUserRole(request: UpdateUserRoleRequest): Observable<UserResponse>;
691
+
692
+ getUsers(request: GetUsersRequest): Observable<GetUsersResponse>;
693
+
694
+ getActiveDevices(request: GetActiveDevicesRequest): Observable<GetActiveDevicesResponse>;
695
+
696
+ manageDevices(request: ManageDevicesRequest): Observable<ManageDevicesResponse>;
697
+
698
+ getUserFields(request: GetUserFieldsRequest): Observable<GetUserFieldsResponse>;
699
+
700
+ createSubscription(request: SubscriptionRequest): Observable<SubscriptionResponse>;
701
+
702
+ deleteSubscription(request: SubscriptionRequest): Observable<SubscriptionResponse>;
703
+
704
+ banUser(request: BanUserRequest): Observable<UserResponse>;
705
+
706
+ unbanUser(request: UnbanUserRequest): Observable<UserResponse>;
707
+
708
+ /**
709
+ * Premium (paid). State lives in users-service; payments-service handles
710
+ * money and calls ActivatePremium (internal) on completion.
711
+ */
712
+
713
+ getMyPremium(request: GetMyPremiumRequest): Observable<PremiumStateResponse>;
714
+
715
+ setPremiumAutoRenew(request: SetPremiumAutoRenewRequest): Observable<PremiumStateResponse>;
716
+
717
+ /**
718
+ * Internal — InternalServiceGuard. Called by payments-service after a
719
+ * successful premium payment (balance or YooKassa webhook).
720
+ */
721
+
722
+ activatePremium(request: ActivatePremiumRequest): Observable<PremiumStateResponse>;
723
+
724
+ /** Internal — fast lookup for the commission engine in payments-service. */
725
+
726
+ isPremiumActive(request: IsPremiumActiveRequest): Observable<IsPremiumActiveResponse>;
727
+
728
+ /**
729
+ * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
730
+ * are admin only (gateway enforces with RolesGuard).
731
+ */
732
+
733
+ listAvatarBorders(request: ListAvatarBordersRequest): Observable<ListAvatarBordersResponse>;
734
+
735
+ upsertAvatarBorder(request: UpsertAvatarBorderRequest): Observable<AvatarBorder>;
736
+
737
+ deleteAvatarBorder(request: DeleteAvatarBorderRequest): Observable<DeleteAvatarBorderResponse>;
738
+
739
+ /** Account settings — bundled write surface for the UI. */
740
+
741
+ updatePrivacy(request: UpdatePrivacyRequest): Observable<PublicProfileResponse>;
742
+
743
+ updateEmailPrefs(request: UpdateEmailPrefsRequest): Observable<UpdateEmailPrefsResponse>;
744
+
745
+ updateLocale(request: UpdateLocaleRequest): Observable<UpdateLocaleResponse>;
746
+
747
+ /**
748
+ * Soft-delete + restore. Internal AuthService also queries the soft-delete
749
+ * state on login (rejects if deletedAt set).
750
+ */
751
+
752
+ softDeleteAccount(request: SoftDeleteAccountRequest): Observable<SoftDeleteAccountResponse>;
753
+
754
+ restoreAccount(request: RestoreAccountRequest): Observable<UserResponse>;
755
+
756
+ /** tasks-service cron */
757
+
758
+ hardDeletePending(request: HardDeletePendingRequest): Observable<HardDeletePendingResponse>;
759
+
760
+ /** Blocks */
761
+
762
+ blockUser(request: BlockUserRequest): Observable<BlockUserResponse>;
763
+
764
+ unblockUser(request: BlockUserRequest): Observable<BlockUserResponse>;
765
+
766
+ listBlockedUsers(request: ListBlockedUsersRequest): Observable<ListBlockedUsersResponse>;
767
+
768
+ /** internal lookup */
769
+
770
+ isBlocked(request: IsBlockedRequest): Observable<IsBlockedResponse>;
771
+
772
+ /** Data export */
773
+
774
+ requestDataExport(request: RequestDataExportRequest): Observable<DataExportRequestRow>;
775
+
776
+ listDataExports(request: ListDataExportsRequest): Observable<ListDataExportsResponse>;
777
+
778
+ /** tasks-service */
779
+
780
+ pickPendingDataExport(request: PickPendingDataExportRequest): Observable<DataExportRequestRow>;
781
+
782
+ /** tasks-service */
783
+
784
+ completeDataExport(request: CompleteDataExportRequest): Observable<DataExportRequestRow>;
785
+
786
+ /** tasks-service */
787
+
788
+ collectUserExportData(request: CollectUserExportDataRequest): Observable<CollectUserExportDataResponse>;
789
+
790
+ /** Unified read for the settings page */
791
+
792
+ getAccountSettings(request: GetAccountSettingsRequest): Observable<AccountSettingsResponse>;
793
+
794
+ /** Password — separate from generic createCode/verifyCode reset flow. */
795
+
796
+ changePassword(request: ChangePasswordRequest): Observable<Ok>;
797
+ }
798
+
799
+ export interface UsersServiceController {
800
+ getPublicProfile(
801
+ request: GetPublicProfileRequest,
802
+ ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
803
+
804
+ updateProfile(
805
+ request: UpdateProfileRequest,
806
+ ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
807
+
808
+ updateUser(request: UpdateUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
809
+
810
+ checkAvailability(
811
+ request: CheckAvailabilityRequest,
812
+ ): Promise<CheckAvailabilityResponse> | Observable<CheckAvailabilityResponse> | CheckAvailabilityResponse;
813
+
814
+ updateUserRole(request: UpdateUserRoleRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
815
+
816
+ getUsers(request: GetUsersRequest): Promise<GetUsersResponse> | Observable<GetUsersResponse> | GetUsersResponse;
817
+
818
+ getActiveDevices(
819
+ request: GetActiveDevicesRequest,
820
+ ): Promise<GetActiveDevicesResponse> | Observable<GetActiveDevicesResponse> | GetActiveDevicesResponse;
821
+
822
+ manageDevices(
823
+ request: ManageDevicesRequest,
824
+ ): Promise<ManageDevicesResponse> | Observable<ManageDevicesResponse> | ManageDevicesResponse;
825
+
826
+ getUserFields(
827
+ request: GetUserFieldsRequest,
828
+ ): Promise<GetUserFieldsResponse> | Observable<GetUserFieldsResponse> | GetUserFieldsResponse;
829
+
830
+ createSubscription(
831
+ request: SubscriptionRequest,
832
+ ): Promise<SubscriptionResponse> | Observable<SubscriptionResponse> | SubscriptionResponse;
833
+
834
+ deleteSubscription(
835
+ request: SubscriptionRequest,
836
+ ): Promise<SubscriptionResponse> | Observable<SubscriptionResponse> | SubscriptionResponse;
837
+
838
+ banUser(request: BanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
839
+
840
+ unbanUser(request: UnbanUserRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
841
+
842
+ /**
843
+ * Premium (paid). State lives in users-service; payments-service handles
844
+ * money and calls ActivatePremium (internal) on completion.
845
+ */
846
+
847
+ getMyPremium(
848
+ request: GetMyPremiumRequest,
849
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
850
+
851
+ setPremiumAutoRenew(
852
+ request: SetPremiumAutoRenewRequest,
853
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
854
+
855
+ /**
856
+ * Internal — InternalServiceGuard. Called by payments-service after a
857
+ * successful premium payment (balance or YooKassa webhook).
858
+ */
859
+
860
+ activatePremium(
861
+ request: ActivatePremiumRequest,
862
+ ): Promise<PremiumStateResponse> | Observable<PremiumStateResponse> | PremiumStateResponse;
863
+
864
+ /** Internal — fast lookup for the commission engine in payments-service. */
865
+
866
+ isPremiumActive(
867
+ request: IsPremiumActiveRequest,
868
+ ): Promise<IsPremiumActiveResponse> | Observable<IsPremiumActiveResponse> | IsPremiumActiveResponse;
869
+
870
+ /**
871
+ * Avatar borders (catalog + admin CRUD). Catalog read is public; mutations
872
+ * are admin only (gateway enforces with RolesGuard).
873
+ */
874
+
875
+ listAvatarBorders(
876
+ request: ListAvatarBordersRequest,
877
+ ): Promise<ListAvatarBordersResponse> | Observable<ListAvatarBordersResponse> | ListAvatarBordersResponse;
878
+
879
+ upsertAvatarBorder(
880
+ request: UpsertAvatarBorderRequest,
881
+ ): Promise<AvatarBorder> | Observable<AvatarBorder> | AvatarBorder;
882
+
883
+ deleteAvatarBorder(
884
+ request: DeleteAvatarBorderRequest,
885
+ ): Promise<DeleteAvatarBorderResponse> | Observable<DeleteAvatarBorderResponse> | DeleteAvatarBorderResponse;
886
+
887
+ /** Account settings — bundled write surface for the UI. */
888
+
889
+ updatePrivacy(
890
+ request: UpdatePrivacyRequest,
891
+ ): Promise<PublicProfileResponse> | Observable<PublicProfileResponse> | PublicProfileResponse;
892
+
893
+ updateEmailPrefs(
894
+ request: UpdateEmailPrefsRequest,
895
+ ): Promise<UpdateEmailPrefsResponse> | Observable<UpdateEmailPrefsResponse> | UpdateEmailPrefsResponse;
896
+
897
+ updateLocale(
898
+ request: UpdateLocaleRequest,
899
+ ): Promise<UpdateLocaleResponse> | Observable<UpdateLocaleResponse> | UpdateLocaleResponse;
900
+
901
+ /**
902
+ * Soft-delete + restore. Internal AuthService also queries the soft-delete
903
+ * state on login (rejects if deletedAt set).
904
+ */
905
+
906
+ softDeleteAccount(
907
+ request: SoftDeleteAccountRequest,
908
+ ): Promise<SoftDeleteAccountResponse> | Observable<SoftDeleteAccountResponse> | SoftDeleteAccountResponse;
909
+
910
+ restoreAccount(request: RestoreAccountRequest): Promise<UserResponse> | Observable<UserResponse> | UserResponse;
911
+
912
+ /** tasks-service cron */
913
+
914
+ hardDeletePending(
915
+ request: HardDeletePendingRequest,
916
+ ): Promise<HardDeletePendingResponse> | Observable<HardDeletePendingResponse> | HardDeletePendingResponse;
917
+
918
+ /** Blocks */
919
+
920
+ blockUser(request: BlockUserRequest): Promise<BlockUserResponse> | Observable<BlockUserResponse> | BlockUserResponse;
921
+
922
+ unblockUser(
923
+ request: BlockUserRequest,
924
+ ): Promise<BlockUserResponse> | Observable<BlockUserResponse> | BlockUserResponse;
925
+
926
+ listBlockedUsers(
927
+ request: ListBlockedUsersRequest,
928
+ ): Promise<ListBlockedUsersResponse> | Observable<ListBlockedUsersResponse> | ListBlockedUsersResponse;
929
+
930
+ /** internal lookup */
931
+
932
+ isBlocked(request: IsBlockedRequest): Promise<IsBlockedResponse> | Observable<IsBlockedResponse> | IsBlockedResponse;
933
+
934
+ /** Data export */
935
+
936
+ requestDataExport(
937
+ request: RequestDataExportRequest,
938
+ ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
939
+
940
+ listDataExports(
941
+ request: ListDataExportsRequest,
942
+ ): Promise<ListDataExportsResponse> | Observable<ListDataExportsResponse> | ListDataExportsResponse;
943
+
944
+ /** tasks-service */
945
+
946
+ pickPendingDataExport(
947
+ request: PickPendingDataExportRequest,
948
+ ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
949
+
950
+ /** tasks-service */
951
+
952
+ completeDataExport(
953
+ request: CompleteDataExportRequest,
954
+ ): Promise<DataExportRequestRow> | Observable<DataExportRequestRow> | DataExportRequestRow;
955
+
956
+ /** tasks-service */
957
+
958
+ collectUserExportData(
959
+ request: CollectUserExportDataRequest,
960
+ ): Promise<CollectUserExportDataResponse> | Observable<CollectUserExportDataResponse> | CollectUserExportDataResponse;
961
+
962
+ /** Unified read for the settings page */
963
+
964
+ getAccountSettings(
965
+ request: GetAccountSettingsRequest,
966
+ ): Promise<AccountSettingsResponse> | Observable<AccountSettingsResponse> | AccountSettingsResponse;
967
+
968
+ /** Password — separate from generic createCode/verifyCode reset flow. */
969
+
970
+ changePassword(request: ChangePasswordRequest): Promise<Ok> | Observable<Ok> | Ok;
971
+ }
972
+
973
+ export function UsersServiceControllerMethods() {
974
+ return function (constructor: Function) {
975
+ const grpcMethods: string[] = [
976
+ "getPublicProfile",
977
+ "updateProfile",
978
+ "updateUser",
979
+ "checkAvailability",
980
+ "updateUserRole",
981
+ "getUsers",
982
+ "getActiveDevices",
983
+ "manageDevices",
984
+ "getUserFields",
985
+ "createSubscription",
986
+ "deleteSubscription",
987
+ "banUser",
988
+ "unbanUser",
989
+ "getMyPremium",
990
+ "setPremiumAutoRenew",
991
+ "activatePremium",
992
+ "isPremiumActive",
993
+ "listAvatarBorders",
994
+ "upsertAvatarBorder",
995
+ "deleteAvatarBorder",
996
+ "updatePrivacy",
997
+ "updateEmailPrefs",
998
+ "updateLocale",
999
+ "softDeleteAccount",
1000
+ "restoreAccount",
1001
+ "hardDeletePending",
1002
+ "blockUser",
1003
+ "unblockUser",
1004
+ "listBlockedUsers",
1005
+ "isBlocked",
1006
+ "requestDataExport",
1007
+ "listDataExports",
1008
+ "pickPendingDataExport",
1009
+ "completeDataExport",
1010
+ "collectUserExportData",
1011
+ "getAccountSettings",
1012
+ "changePassword",
1013
+ ];
1014
+ for (const method of grpcMethods) {
1015
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
1016
+ GrpcMethod("UsersService", method)(constructor.prototype[method], method, descriptor);
1017
+ }
1018
+ const grpcStreamMethods: string[] = [];
1019
+ for (const method of grpcStreamMethods) {
1020
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
1021
+ GrpcStreamMethod("UsersService", method)(constructor.prototype[method], method, descriptor);
1022
+ }
1023
+ };
1024
+ }
1025
+
1026
+ export const USERS_SERVICE_NAME = "UsersService";